[asm.js] Fix infinite loop in parser on parse error.

The code in `AsmJsScanner::Next()` checks for both
end of input and parse error:

  if (token_ == kEndOfInput || token_ == kParseError) {
    return;
  }

but until now the code in the parsing loop only checked
for `kEndOfInput`, resulting in an infinite loop on
`kParseError`.

R=bradnelson@chromium.org, mstarzinger@chromium.org

Bug: chromium:771428
Change-Id: I9170f090503590b3b9b949a0d00ab4daef85bf66
Reviewed-on: https://chromium-review.googlesource.com/699994
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48290}
This commit is contained in:
Niklas Hambüchen 2017-10-04 16:44:44 +02:00 committed by Commit Bot
parent 66d75d41ec
commit 4f8a70adca
3 changed files with 27 additions and 1 deletions

View File

@ -104,6 +104,7 @@ Mike Pennisi <mike@mikepennisi.com>
Milton Chiang <milton.chiang@mediatek.com>
Myeong-bo Shim <m0609.shim@samsung.com>
Nicolas Antonius Ernst Leopold Maria Kaiser <nikai@nikai.net>
Niklas Hambüchen <mail@nh2.me>
Noj Vek <nojvek@gmail.com>
Oleksandr Chekhovskyi <oleksandr.chekhovskyi@gmail.com>
Paolo Giarrusso <p.giarrusso@gmail.com>

View File

@ -2496,7 +2496,8 @@ void AsmJsParser::GatherCases(ZoneVector<int32_t>* cases) {
value = static_cast<int32_t>(uvalue);
}
cases->push_back(value);
} else if (Peek(AsmJsScanner::kEndOfInput)) {
} else if (Peek(AsmJsScanner::kEndOfInput) ||
Peek(AsmJsScanner::kParseError)) {
break;
}
scanner_.Next();

View File

@ -0,0 +1,24 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
function Module() {
"use asm";
function f(i) {
i = i | 0;
switch (i | 0) {
case 2:
// Exceeds value range.
i = 0x1ffffffff;
break;
}
return i | 0;
}
return f;
}
var f = Module();
assertEquals(0, f(0));
assertEquals(1, f(1));
assertEquals(-1, f(2));
assertFalse(%IsAsmWasmCode(Module));