From c9aa72313e04656b9850aa0679e1117ee8ef0e0c Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 23 Nov 2017 13:24:54 -0500 Subject: [PATCH] throw error on illegal context (#934) --- src/parse/state/mustache.ts | 14 +++++++++++++- src/utils/reservedNames.ts | 3 --- .../errors.json | 8 ++++++++ .../input.html | 3 +++ .../samples/each-block-invalid-context/errors.json | 8 ++++++++ .../samples/each-block-invalid-context/input.html | 3 +++ 6 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 test/validator/samples/each-block-invalid-context-destructured/errors.json create mode 100644 test/validator/samples/each-block-invalid-context-destructured/input.html create mode 100644 test/validator/samples/each-block-invalid-context/errors.json create mode 100644 test/validator/samples/each-block-invalid-context/input.html diff --git a/src/parse/state/mustache.ts b/src/parse/state/mustache.ts index d71642cd1faf..3ca60032420d 100644 --- a/src/parse/state/mustache.ts +++ b/src/parse/state/mustache.ts @@ -1,6 +1,7 @@ import readExpression from '../read/expression'; import { whitespace } from '../../utils/patterns'; import { trimStart, trimEnd } from '../../utils/trim'; +import reservedNames from '../../utils/reservedNames'; import { Parser } from '../index'; import { Node } from '../../interfaces'; @@ -168,8 +169,15 @@ export default function mustache(parser: Parser) { do { parser.allowWhitespace(); + + const start = parser.index; const destructuredContext = parser.read(validIdentifier); + if (!destructuredContext) parser.error(`Expected name`); + if (reservedNames.has(destructuredContext)) { + parser.error(`'${destructuredContext}' is a reserved word in JavaScript and cannot be used here`, start); + } + block.destructuredContexts.push(destructuredContext); parser.allowWhitespace(); } while (parser.eat(',')); @@ -180,7 +188,11 @@ export default function mustache(parser: Parser) { parser.allowWhitespace(); parser.eat(']', true); } else { - block.context = parser.read(validIdentifier); // TODO check it's not a keyword + const start = parser.index; + block.context = parser.read(validIdentifier); + if (reservedNames.has(block.context)) { + parser.error(`'${block.context}' is a reserved word in JavaScript and cannot be used here`, start); + } if (!block.context) parser.error(`Expected name`); } diff --git a/src/utils/reservedNames.ts b/src/utils/reservedNames.ts index 1e5b28740e71..e0d1e860e3dd 100644 --- a/src/utils/reservedNames.ts +++ b/src/utils/reservedNames.ts @@ -49,7 +49,4 @@ const reservedNames = new Set([ 'yield', ]); -// prevent e.g. `{{#each states as state}}` breaking -reservedNames.add('state'); - export default reservedNames; diff --git a/test/validator/samples/each-block-invalid-context-destructured/errors.json b/test/validator/samples/each-block-invalid-context-destructured/errors.json new file mode 100644 index 000000000000..b14ef6325144 --- /dev/null +++ b/test/validator/samples/each-block-invalid-context-destructured/errors.json @@ -0,0 +1,8 @@ +[{ + "message": "'case' is a reserved word in JavaScript and cannot be used here", + "loc": { + "line": 1, + "column": 18 + }, + "pos": 18 +}] \ No newline at end of file diff --git a/test/validator/samples/each-block-invalid-context-destructured/input.html b/test/validator/samples/each-block-invalid-context-destructured/input.html new file mode 100644 index 000000000000..ce31634a851a --- /dev/null +++ b/test/validator/samples/each-block-invalid-context-destructured/input.html @@ -0,0 +1,3 @@ +{{#each cases as [case]}} + {{case.title}} +{{/each}} \ No newline at end of file diff --git a/test/validator/samples/each-block-invalid-context/errors.json b/test/validator/samples/each-block-invalid-context/errors.json new file mode 100644 index 000000000000..eecb97266b1e --- /dev/null +++ b/test/validator/samples/each-block-invalid-context/errors.json @@ -0,0 +1,8 @@ +[{ + "message": "'case' is a reserved word in JavaScript and cannot be used here", + "loc": { + "line": 1, + "column": 17 + }, + "pos": 17 +}] \ No newline at end of file diff --git a/test/validator/samples/each-block-invalid-context/input.html b/test/validator/samples/each-block-invalid-context/input.html new file mode 100644 index 000000000000..212c29ecdc1e --- /dev/null +++ b/test/validator/samples/each-block-invalid-context/input.html @@ -0,0 +1,3 @@ +{{#each cases as case}} + {{case.title}} +{{/each}} \ No newline at end of file