fix(std/encoding/toml): could not parse strings with apostrophes/semicolons (#6781)

This commit is contained in:
uki00a 2020-07-17 07:36:15 +09:00 committed by GitHub
parent 2d58fee807
commit 121eaa4efc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 5 deletions

View file

@ -27,4 +27,7 @@ The first newline is
trimmed in raw strings.
All other whitespace
is preserved.
'''
'''
withApostrophe = "What if it's not?"
withSemicolon = "const message = 'hello world';"

View file

@ -2,6 +2,8 @@
import { deepAssign } from "../_util/deep_assign.ts";
import { assert } from "../_util/assert.ts";
class TOMLError extends Error {}
class KeyValuePair {
constructor(public key: string, public value: unknown) {}
}
@ -230,10 +232,7 @@ class Parser {
if (invalidArr) {
dataString = dataString.replace(/,]/g, "]");
}
const m = /(?:\'|\[|{|\").*(?:\'|\]|\"|})\s*[^#]/g.exec(dataString);
if (m) {
dataString = m[0].trim();
}
dataString = this._stripComment(dataString);
if (dataString[0] === "{" && dataString[dataString.length - 1] === "}") {
const reg = /([a-zA-Z0-9-_\.]*) (=)/gi;
let result;
@ -260,6 +259,34 @@ 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);

View file

@ -29,6 +29,8 @@ Deno.test({
str6: "The quick brown\nfox jumps over\nthe lazy dog.",
lines: "The first newline is\ntrimmed in raw strings.\n All other " +
"whitespace\n is preserved.",
withApostrophe: "What if it's not?",
withSemicolon: `const message = 'hello world';`,
},
};
const actual = parseFile(path.join(testFilesDir, "string.toml"));