From 90613f2ae72993ac94a0f72890ba09715463830a Mon Sep 17 00:00:00 2001 From: Pieter de Bie Date: Wed, 13 Apr 2016 17:44:29 +0200 Subject: [PATCH] Properly parse unicode characters in strings This fixes the parsing of unicode strings that are 1 or 6 hex characters long. Extends the tests to support a third element in examples, which would be the re-stringified example, since a unicode character might be stringified in a different way than the original code, and still be valid. fixes webpack/css-loader#133 fixes #12 --- lib/parseValues.js | 20 ++++++++++---------- test/stringifyValues.js | 2 +- test/test-cases-values.js | 15 ++++++++++++++- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/lib/parseValues.js b/lib/parseValues.js index 316c6f3..97be01b 100644 --- a/lib/parseValues.js +++ b/lib/parseValues.js @@ -23,17 +23,17 @@ function endSpacingMatch(match) { } function unescapeString(content) { - return content.replace(/\\([a-fA-F0-9]{2,5}|.)/g, function(escaped) { - if(escaped.length > 2) { - var C = parseInt(escaped.substr(1), 16); - if(C < 0x10000) { - return String.fromCharCode(C); - } else { - return String.fromCharCode(Math.floor((C - 0x10000) / 0x400) + 0xD800) + - String.fromCharCode((C - 0x10000) % 0x400 + 0xDC00); - } + return content.replace(/\\(?:([a-fA-F0-9]{1,6})|(.))/g, function(all, unicode, otherCharacter) { + if (otherCharacter) { + return otherCharacter; + } + + var C = parseInt(unicode, 16); + if(C < 0x10000) { + return String.fromCharCode(C); } else { - return escaped.substr(1); + return String.fromCharCode(Math.floor((C - 0x10000) / 0x400) + 0xD800) + + String.fromCharCode((C - 0x10000) % 0x400 + 0xDC00); } }); } diff --git a/test/stringifyValues.js b/test/stringifyValues.js index b48acb2..8f1bbb5 100644 --- a/test/stringifyValues.js +++ b/test/stringifyValues.js @@ -10,7 +10,7 @@ describe("stringifyValues", function() { Object.keys(testCases).forEach(function(testCase) { it("should stringify values " + testCase, function() { var input = testCases[testCase][1]; - var expected = testCases[testCase][0]; + var expected = testCases[testCase][2] || testCases[testCase][0]; assert.deepEqual(Tokenizer.stringifyValues(input), expected); }); }); diff --git a/test/test-cases-values.js b/test/test-cases-values.js index 6d4fbb2..1d49bf1 100644 --- a/test/test-cases-values.js +++ b/test/test-cases-values.js @@ -175,7 +175,20 @@ module.exports = { "\"\\1F50E\"", singleValue([ { type: "string", stringType: "\"", value: "\ud83d\udd0e" } - ]) + ]), + ], + "escaped unicode 5 (extra short)": [ + "\"\\A\"", + singleValue([ + { type: "string", stringType: "\"", value: "\u000A" } + ]), + ], + "escaped unicode 6 (full length)": [ + "\"\\00000A\"", + singleValue([ + { type: "string", stringType: "\"", value: "\u000A" } + ]), + "\"\\A\"" ], "nested-item-with append": [ "linear-gradient(45deg) 25%",