From 67aae9810cc4fa46e2fd5aea3a86f19192067242 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 5 Mar 2018 10:50:55 -0800 Subject: [PATCH] Use single replacer for string escaping --- src/compiler/utilities.ts | 19 +++++++++++-------- ...nonstrictTemplateWithNotOctalPrintsAsIs.js | 8 ++++++++ ...rictTemplateWithNotOctalPrintsAsIs.symbols | 5 +++++ ...strictTemplateWithNotOctalPrintsAsIs.types | 6 ++++++ ...nonstrictTemplateWithNotOctalPrintsAsIs.ts | 2 ++ 5 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 tests/baselines/reference/nonstrictTemplateWithNotOctalPrintsAsIs.js create mode 100644 tests/baselines/reference/nonstrictTemplateWithNotOctalPrintsAsIs.symbols create mode 100644 tests/baselines/reference/nonstrictTemplateWithNotOctalPrintsAsIs.types create mode 100644 tests/cases/compiler/nonstrictTemplateWithNotOctalPrintsAsIs.ts diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 8108d0f16923f..04c4874937f5c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2466,7 +2466,6 @@ namespace ts { const singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; const backtickQuoteEscapedCharsRegExp = /[\\\`\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; const escapedCharsMap = createMapFromTemplate({ - "\0": "\\0", "\t": "\\t", "\v": "\\v", "\f": "\\f", @@ -2481,7 +2480,6 @@ namespace ts { "\u2029": "\\u2029", // paragraphSeparator "\u0085": "\\u0085" // nextLine }); - const escapedNullRegExp = /\\0[0-9]/g; /** * Based heavily on the abstract 'Quote'/'QuoteJSONString' operation from ECMA-262 (24.3.2.2), @@ -2493,14 +2491,19 @@ namespace ts { quoteChar === CharacterCodes.backtick ? backtickQuoteEscapedCharsRegExp : quoteChar === CharacterCodes.singleQuote ? singleQuoteEscapedCharsRegExp : doubleQuoteEscapedCharsRegExp; - return s.replace(escapedCharsRegExp, getReplacement).replace(escapedNullRegExp, nullReplacement); + return s.replace(escapedCharsRegExp, getReplacement); } - function nullReplacement(c: string) { - return "\\x00" + c.charAt(c.length - 1); - } - - function getReplacement(c: string) { + function getReplacement(c: string, offset: number, input: string) { + if (c.charCodeAt(0) === CharacterCodes.nullCharacter) { + const lookAhead = input.charCodeAt(offset + c.length); + if (lookAhead >= CharacterCodes._0 && lookAhead <= CharacterCodes._9) { + // If the null character is followed by digits, print as a hex escape to prevent the result from parsing as an octal (which is forbidden in strict mode) + return "\\x00"; + } + // Otherwise, keep printing a literal \0 for the null character + return "\\0"; + } return escapedCharsMap.get(c) || get16BitUnicodeEscapeSequence(c.charCodeAt(0)); } diff --git a/tests/baselines/reference/nonstrictTemplateWithNotOctalPrintsAsIs.js b/tests/baselines/reference/nonstrictTemplateWithNotOctalPrintsAsIs.js new file mode 100644 index 0000000000000..0a40faeb638c4 --- /dev/null +++ b/tests/baselines/reference/nonstrictTemplateWithNotOctalPrintsAsIs.js @@ -0,0 +1,8 @@ +//// [nonstrictTemplateWithNotOctalPrintsAsIs.ts] +// https://github.com/Microsoft/TypeScript/issues/21828 +const d2 = `\\0041`; + + +//// [nonstrictTemplateWithNotOctalPrintsAsIs.js] +// https://github.com/Microsoft/TypeScript/issues/21828 +var d2 = "\\0041"; diff --git a/tests/baselines/reference/nonstrictTemplateWithNotOctalPrintsAsIs.symbols b/tests/baselines/reference/nonstrictTemplateWithNotOctalPrintsAsIs.symbols new file mode 100644 index 0000000000000..7d8ee9546e221 --- /dev/null +++ b/tests/baselines/reference/nonstrictTemplateWithNotOctalPrintsAsIs.symbols @@ -0,0 +1,5 @@ +=== tests/cases/compiler/nonstrictTemplateWithNotOctalPrintsAsIs.ts === +// https://github.com/Microsoft/TypeScript/issues/21828 +const d2 = `\\0041`; +>d2 : Symbol(d2, Decl(nonstrictTemplateWithNotOctalPrintsAsIs.ts, 1, 5)) + diff --git a/tests/baselines/reference/nonstrictTemplateWithNotOctalPrintsAsIs.types b/tests/baselines/reference/nonstrictTemplateWithNotOctalPrintsAsIs.types new file mode 100644 index 0000000000000..c0673f04b97e9 --- /dev/null +++ b/tests/baselines/reference/nonstrictTemplateWithNotOctalPrintsAsIs.types @@ -0,0 +1,6 @@ +=== tests/cases/compiler/nonstrictTemplateWithNotOctalPrintsAsIs.ts === +// https://github.com/Microsoft/TypeScript/issues/21828 +const d2 = `\\0041`; +>d2 : "\\0041" +>`\\0041` : "\\0041" + diff --git a/tests/cases/compiler/nonstrictTemplateWithNotOctalPrintsAsIs.ts b/tests/cases/compiler/nonstrictTemplateWithNotOctalPrintsAsIs.ts new file mode 100644 index 0000000000000..ce75032a1e815 --- /dev/null +++ b/tests/cases/compiler/nonstrictTemplateWithNotOctalPrintsAsIs.ts @@ -0,0 +1,2 @@ +// https://github.com/Microsoft/TypeScript/issues/21828 +const d2 = `\\0041`;