diff --git a/lexer.js b/lexer.js index 8f8ff12..3e30b6d 100755 --- a/lexer.js +++ b/lexer.js @@ -1413,7 +1413,7 @@ function templateString () { if (ch === 92/*\*/) pos++; } - syntaxError(); + throw new Error('Unterminated template.'); } function blockComment () { diff --git a/lib/lexer.wasm b/lib/lexer.wasm index 08fbd54..dc29138 100755 Binary files a/lib/lexer.wasm and b/lib/lexer.wasm differ diff --git a/src/lexer.c b/src/lexer.c index b6576d4..fd3f1cf 100755 --- a/src/lexer.c +++ b/src/lexer.c @@ -192,7 +192,7 @@ uint32_t parseCJS (uint16_t* _source, uint32_t _sourceLen, void (*_addExport)(co break; case '}': if (openTokenDepth == 0) - return syntaxError(2), false; + return syntaxError(2), error; if (openTokenDepth-- == templateDepth) { templateDepth = templateStack[--templateStackDepth]; templateString(); @@ -259,8 +259,11 @@ uint32_t parseCJS (uint16_t* _source, uint32_t _sourceLen, void (*_addExport)(co lastTokenPos = pos; } - if (templateDepth != UINT16_MAX || openTokenDepth || error) + if (templateDepth != UINT16_MAX || openTokenDepth || error) { + if (!error) + syntaxError(1); return error; + } // success return 0; diff --git a/test/_unit.js b/test/_unit.js index 19f8015..719d922 100755 --- a/test/_unit.js +++ b/test/_unit.js @@ -64,6 +64,30 @@ suite('Lexer', () => { assert.deepStrictEqual(first, { exports: ['first'], reexports: [] }); }); + test('rejects unterminated and unexpected nesting', () => { + for (const source of ['(', '{', ')', '}', '({', '{(', 'exports.value = 1; }']) { + assert.throws(() => parse(source, 'nesting.js'), { name: 'Error' }); + assert.deepStrictEqual(parse('exports.recovery = 1;'), { + exports: ['recovery'], + reexports: [] + }); + } + assert.deepStrictEqual(parse('({}); exports.value = 1;'), { + exports: ['value'], + reexports: [] + }); + }); + + test('rejects unterminated templates with a parser error', () => { + for (const source of ['`open', '`open ${value', 'const value = `open']) { + assert.throws(() => parse(source, 'template.js'), { name: 'Error' }); + assert.deepStrictEqual(parse('exports.recovery = 1;'), { + exports: ['recovery'], + reexports: [] + }); + } + }); + test('automatic Wasm initialization', async () => { const lexer = await import('../dist/lexer.mjs?automatic-initialization');