diff --git a/lib/helpers.js b/lib/helpers.js index ef567e2..3e03643 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -60,6 +60,12 @@ export function preparePath(data, sexpr, parts, loc) { let tail = []; let depth = 0; + // Check if the first path segment is a number, which should throw an error + if (parts.length > 0 && !data && !sexpr && + !isNaN(parseFloat(parts[0].part)) && isFinite(parts[0].part)) { + throw new Exception('Invalid path: ' + parts.map(p => (p.separator ?? '') + p.part).join(''), { loc }); + } + for (let i = 0, l = parts.length; i < l; i++) { let part = parts[i].part; // If we have [] syntax then we do not treat path references as operators, diff --git a/spec/parser.js b/spec/parser.js index 93ad216..ff0bfb0 100644 --- a/spec/parser.js +++ b/spec/parser.js @@ -36,6 +36,16 @@ describe('parser', function () { equalsAst('{{this/foo}}', '{{ p%foo }}'); equalsAst('{{this.foo}}', '{{ p%this.foo }}'); equalsAst('{{this.#foo}}', '{{ p%this.#foo }}'); + equalsAst('{{this.0.foo}}', '{{ p%this.0/foo }}'); + equalsAst('{{this.foo.0}}', '{{ p%this.foo/0 }}'); + equalsAst('{{this.0}}', '{{ p%this.0 }}'); + shouldThrow( + function () { + astFor('{{0.foo}}'); + }, + Error, + /Invalid path: 0.foo/ + ); }); it('parses mustaches with - in a path', function () { diff --git a/src/handlebars.yy b/src/handlebars.yy index ed26c2c..507f2f8 100644 --- a/src/handlebars.yy +++ b/src/handlebars.yy @@ -174,6 +174,6 @@ path ; pathSegments - : pathSegments sep ID { $1.push({part: yy.id($3), original: $3, separator: $2}); $$ = $1; } + : pathSegments sep (ID | NUMBER) { $1.push({part: yy.id($3), original: $3, separator: $2}); $$ = $1; } | ID -> [{part: yy.id($1), original: $1}] ;