From 5a333f3d7575456514d4b41776ec62f1d376bcf5 Mon Sep 17 00:00:00 2001 From: Neil Dhar Date: Tue, 12 Jul 2022 08:45:35 -0700 Subject: [PATCH] Handle empty BigInt literals in the parser Summary: OSS-Fuzz found that empty octal/hex/binary BigInt literals trigger an assert in our parser, since we don't correctly handle the case where there are no digits after the 0o/0x/0b. For example, `0bn` triggers this assert because after consuming the trailing "n", we assume that some digits were consumed, which isn't necessarily true. Reviewed By: tmikov Differential Revision: D37755199 fbshipit-source-id: 48805e0684ce4518a10e32ce17b02e22308444fa --- lib/Parser/JSLexer.cpp | 8 ++++---- test/Parser/literal.js | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/Parser/JSLexer.cpp b/lib/Parser/JSLexer.cpp index 2fca82e03..d6edd87e9 100644 --- a/lib/Parser/JSLexer.cpp +++ b/lib/Parser/JSLexer.cpp @@ -1461,13 +1461,13 @@ end: llvh::StringRef raw{rawStart, (size_t)(curCharPtr_ - rawStart)}; if (ok && !real && (!legacyOctal || raw == "0n") && tmpStorage_ == "n") { - assert(curCharPtr_ > start + 1 && "there should be numbers here"); + assert(curCharPtr_ > start && "Must consume at least the trailing n."); + llvh::ArrayRef digits{start, curCharPtr_ - 1}; // use parseIntWithRadix to validate the bigint literal's digits. The // converted value does not matter, only whether or not the string was // parsed correctly. - if (parseIntWithRadix( - llvh::ArrayRef{start, (size_t)(curCharPtr_ - start - 1)}, - radix)) { + if (digits.size() && + parseIntWithRadix(digits, radix)) { // This is a BigInt. rawStorage_.clear(); rawStorage_.append(raw); diff --git a/test/Parser/literal.js b/test/Parser/literal.js index 780f2adf4..4cee681ac 100644 --- a/test/Parser/literal.js +++ b/test/Parser/literal.js @@ -17,3 +17,6 @@ 0b2n // CHECK: invalid numeric literal + +0bn +// CHECK: invalid numeric literal