Skip to content

Commit

Permalink
[[FIX]] Avoid crash when peeking past end of prog (#2937)
Browse files Browse the repository at this point in the history
The lexer returns `null` values when tokens are requested after all
input has been consumed. Previously, the `peek` function would correctly
produce the special "(end)" token in situations where the parser
attempted to look beyond the end of the program. In such cases, however,
it would also pollute the lookahead buffer with an invalid entry--the
`null` value returned by the lexer. Future calls to `peek` could receive
this buffered value.

Because JSHint's internals are written with the assumption that `peek`
always returns a token object, the `null` value would trigger a
TypeError and subsequent program crash.

Re-factor the `peek` function to only insert valid token objects into
the lookahead buffer.
  • Loading branch information
jugglinmike authored and rwaldron committed Aug 7, 2016
1 parent d800e44 commit 330d429
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 8 deletions.
16 changes: 8 additions & 8 deletions src/jshint.js
Original file line number Diff line number Diff line change
Expand Up @@ -716,16 +716,16 @@ var JSHINT = (function() {
}

while (j <= i) {
t = lookahead[j];
if (!t) {
t = lookahead[j] = lex.token();
t = lex.token();

// Peeking past the end of the program should produce the "(end)" token
// and should not extend the lookahead buffer.
if (!t && state.tokens.next.id === "(end)") {
return state.tokens.next;
}
j += 1;
}

// Peeking past the end of the program should produce the "(end)" token.
if (!t && state.tokens.next.id === "(end)") {
return state.tokens.next;
lookahead[j] = t;
j += 1;
}

return t;
Expand Down
5 changes: 5 additions & 0 deletions tests/unit/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,11 @@ exports.comments = function (test) {
TestRun(test).test(src);
TestRun(test).test(fs.readFileSync(__dirname + "/fixtures/gruntComment.js", "utf8"));

TestRun(test)
.addError(1, "Unmatched '{'.")
.addError(1, "Unrecoverable syntax error. (100% scanned).")
.test("({");

test.done();
};

Expand Down

0 comments on commit 330d429

Please sign in to comment.