summaryrefslogtreecommitdiff
path: root/std/encoding/toml.ts
diff options
context:
space:
mode:
authorJakob Strobl <Jakob.Strobl@pitt.edu>2020-08-28 18:51:06 -0400
committerGitHub <noreply@github.com>2020-08-28 18:51:06 -0400
commit03a3256e9c62e38f2b35fa83c35be06fe2123fd2 (patch)
tree81a625065ce60e8b0f42b7fbb16cb3c2ea13b3ea /std/encoding/toml.ts
parent935c92800f0864c7076cd2e30130fe46fac7e8a5 (diff)
fix(std/encoding/toml): Comment after arrays causing incorrect output (#7224)
Diffstat (limited to 'std/encoding/toml.ts')
-rw-r--r--std/encoding/toml.ts100
1 files changed, 70 insertions, 30 deletions
diff --git a/std/encoding/toml.ts b/std/encoding/toml.ts
index 212c14bdc..62acc7db7 100644
--- a/std/encoding/toml.ts
+++ b/std/encoding/toml.ts
@@ -32,14 +32,82 @@ class Parser {
for (let i = 0; i < this.tomlLines.length; i++) {
const s = this.tomlLines[i];
const trimmed = s.trim();
- if (trimmed !== "" && trimmed[0] !== "#") {
+ if (trimmed !== "") {
out.push(s);
}
}
this.tomlLines = out;
+ this._removeComments();
this._mergeMultilines();
}
+ _removeComments(): void {
+ function isFullLineComment(line: string) {
+ return line.match(/^#/) ? true : false;
+ }
+
+ function stringStart(line: string) {
+ const m = line.match(/(?:=\s*\[?\s*)("""|'''|"|')/);
+ if (!m) {
+ return false;
+ }
+
+ // We want to know which syntax was used to open the string
+ openStringSyntax = m[1];
+ return true;
+ }
+
+ function stringEnd(line: string) {
+ // match the syntax used to open the string when searching for string close
+ // e.g. if we open with ''' we must close with a '''
+ const reg = RegExp(`(?<!(=\\s*))${openStringSyntax}(?!(.*"))`);
+ if (!line.match(reg)) {
+ return false;
+ }
+
+ openStringSyntax = "";
+ return true;
+ }
+
+ const cleaned = [];
+ let isOpenString = false;
+ let openStringSyntax = "";
+ for (let i = 0; i < this.tomlLines.length; i++) {
+ const line = this.tomlLines[i];
+
+ // stringStart and stringEnd are separate conditions to
+ // support both single-line and multi-line strings
+ if (!isOpenString && stringStart(line)) {
+ isOpenString = true;
+ }
+ if (isOpenString && stringEnd(line)) {
+ isOpenString = false;
+ }
+
+ if (!isOpenString && !isFullLineComment(line)) {
+ const out = line.split(
+ /(?<=([\,\[\]\{\}]|".*"|'.*'|\w(?!.*("|')+))\s*)#/gi,
+ );
+ cleaned.push(out[0].trim());
+ } else if (isOpenString || !isFullLineComment(line)) {
+ cleaned.push(line);
+ }
+
+ // If a single line comment doesnt end on the same line, throw error
+ if (
+ isOpenString && (openStringSyntax === "'" || openStringSyntax === '"')
+ ) {
+ throw new TOMLError(`Single-line string is not closed:\n${line}`);
+ }
+ }
+
+ if (isOpenString) {
+ throw new TOMLError(`Incomplete string until EOF`);
+ }
+
+ this.tomlLines = cleaned;
+ }
+
_mergeMultilines(): void {
function arrayStart(line: string): boolean {
const reg = /.*=\s*\[/g;
@@ -236,7 +304,7 @@ class Parser {
if (invalidArr) {
dataString = dataString.replace(/,]/g, "]");
}
- dataString = this._stripComment(dataString);
+
if (dataString[0] === "{" && dataString[dataString.length - 1] === "}") {
const reg = /([a-zA-Z0-9-_\.]*) (=)/gi;
let result;
@@ -263,34 +331,6 @@ class Parser {
}
return eval(dataString);
}
- private _stripComment(dataString: string): string {
- const isString = dataString.startsWith('"') || dataString.startsWith("'");
- if (isString) {
- const [quote] = dataString;
- let indexOfNextQuote = 0;
- while (
- (indexOfNextQuote = dataString.indexOf(quote, indexOfNextQuote + 1)) !==
- -1
- ) {
- const isEscaped = dataString[indexOfNextQuote - 1] === "\\";
- if (!isEscaped) {
- break;
- }
- }
- if (indexOfNextQuote === -1) {
- throw new TOMLError("imcomplete string literal");
- }
- const endOfString = indexOfNextQuote + 1;
- return dataString.slice(0, endOfString);
- }
-
- const m = /(?:|\[|{).*(?:|\]|})\s*^((?!#).)*/g.exec(dataString);
- if (m) {
- return m[0].trim();
- } else {
- return dataString;
- }
- }
_isLocalTime(str: string): boolean {
const reg = /(\d{2}):(\d{2}):(\d{2})/;
return reg.test(str);