From f188613e09349eed12fbd0a9352d95111493847e Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 12 Dec 2014 18:46:58 +0200 Subject: [PATCH] Add support for unknown entities (treat as ampersand + regular text). Fixes #10. --- acorn.js | 30 ++++++++++---- package.json | 2 +- test/tests-jsx.js | 101 ++++++++++++++-------------------------------- 3 files changed, 53 insertions(+), 80 deletions(-) diff --git a/acorn.js b/acorn.js index 00e9e7eaee..d1fda1ad68 100644 --- a/acorn.js +++ b/acorn.js @@ -553,6 +553,9 @@ var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); + var decimalNumber = /^\d+$/; + var hexNumber = /^[\da-fA-F]+$/; + // Whether a single character denotes a newline. var newline = /[\n\r\u2028\u2029]/; @@ -1421,22 +1424,33 @@ var str = '', count = 0, entity; var ch = nextChar(); if (ch !== '&') raise(tokPos, "Entity must start with an ampersand"); - tokPos++; + var startPos = ++tokPos; while (tokPos < inputLen && count++ < 10) { ch = nextChar(); tokPos++; if (ch === ';') { + if (str[0] === '#') { + if (str[1] === 'x') { + str = str.substr(2); + if (hexNumber.test(str)) { + entity = String.fromCharCode(parseInt(str, 16)); + } + } else { + str = str.substr(1); + if (decimalNumber.test(str)) { + entity = String.fromCharCode(parseInt(str, 10)); + } + } + } else { + entity = XHTMLEntities[str]; + } break; } str += ch; } - - if (str[0] === '#' && str[1] === 'x') { - entity = String.fromCharCode(parseInt(str.substr(2), 16)); - } else if (str[0] === '#') { - entity = String.fromCharCode(parseInt(str.substr(1), 10)); - } else { - entity = XHTMLEntities[str]; + if (!entity) { + tokPos = startPos; + return '&'; } return entity; } diff --git a/package.json b/package.json index 68ff13bc04..3c795c66b2 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "acorn-jsx", "description": "Alternative React JSX parser", "main": "acorn.js", - "version": "0.9.1-6", + "version": "0.9.1-7", "maintainers": [ { "name": "Marijn Haverbeke", diff --git a/test/tests-jsx.js b/test/tests-jsx.js index a07f0aea2e..1d76af0f14 100644 --- a/test/tests-jsx.js +++ b/test/tests-jsx.js @@ -330,7 +330,7 @@ var fbTestFixture = { end: { line: 1, column: 40 } } }, - '': { + '': { type: "ExpressionStatement", expression: { type: "XJSElement", @@ -339,11 +339,7 @@ var fbTestFixture = { name: { type: "XJSIdentifier", name: "a", - range: [1, 2], - loc: { - start: { line: 1, column: 1 }, - end: { line: 1, column: 2 } - } + range: [1, 2] }, selfClosing: true, attributes: [ @@ -352,11 +348,7 @@ var fbTestFixture = { name: { type: "XJSIdentifier", name: "b", - range: [3, 4], - loc: { - start: { line: 1, column: 3 }, - end: { line: 1, column: 4 } - } + range: [3, 4] }, value: { type: "XJSExpressionContainer", @@ -364,98 +356,65 @@ var fbTestFixture = { type: "Literal", value: " ", raw: "\" \"", - range: [6, 9], - loc: { - start: { line: 1, column: 6 }, - end: { line: 1, column: 9 } - } + range: [6, 9] }, - range: [5, 10], - loc: { - start: { line: 1, column: 5 }, - end: { line: 1, column: 10 } - } + range: [5, 10] }, - range: [3, 10], - loc: { - start: { line: 1, column: 3 }, - end: { line: 1, column: 10 } - } + range: [3, 10] }, { type: "XJSAttribute", name: { type: "XJSIdentifier", name: "c", - range: [11, 12], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 12 } - } + range: [11, 12] }, value: { type: "Literal", value: " ", raw: "\" \"", - range: [13, 16], - loc: { - start: { line: 1, column: 13 }, - end: { line: 1, column: 16 } - } + range: [13, 16] }, - range: [11, 16], - loc: { - start: { line: 1, column: 11 }, - end: { line: 1, column: 16 } - } + range: [11, 16] }, { type: "XJSAttribute", name: { type: "XJSIdentifier", name: "d", - range: [17, 18], - loc: { - start: { line: 1, column: 17 }, - end: { line: 1, column: 18 } - } + range: [17, 18] }, value: { type: "Literal", value: "&", raw: "\"&\"", - range: [19, 26], - loc: { - start: { line: 1, column: 19 }, - end: { line: 1, column: 26 } - } + range: [19, 26] }, - range: [17, 26], - loc: { - start: { line: 1, column: 17 }, - end: { line: 1, column: 26 } - } + range: [17, 26] + }, + { + type: "XJSAttribute", + name: { + type: "XJSIdentifier", + name: "e", + range: [27, 28] + }, + value: { + type: "Literal", + value: "&r;", + raw: "\"&r;\"", + range: [29, 37] + }, + range: [27, 37] } ], - range: [0, 29], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 29 } - } + range: [0, 40] }, closingElement: null, children: [], - range: [0, 29], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 29 } - } + range: [0, 40] }, - range: [0, 29], - loc: { - start: { line: 1, column: 0 }, - end: { line: 1, column: 29 } - } + range: [0, 40] }, '': { type: "ExpressionStatement",