Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 32b9728

Browse filesBrowse files
ddegazioConstellation
authored andcommitted
Segfault in JSC::IdentifierArena::makeBigIntDecimalIdentifier
https://bugs.webkit.org/show_bug.cgi?id=247644 rdar://98566429 Reviewed by Mark Lam and Yusuke Suzuki. We currently get a segfault because the parser for bigdecimal identifiers allocates a JSBigInt, which might cause us to run out of memory. The parser doesn't throw arbitrary exceptions elsewhere, so instead of throwing out-of-memory as an exception, it just produces an empty JSBigInt and crashes when using it. This patch addresses the issue by making the result of makeBigIntDecimalIdentifier nullable, checking for it in the parser, and failing with a SyntaxError if the identifier could not be created. * JSTests/stress/bigdecimal-identifiers-fail-on-oom.js: Added. (foo): * Source/JavaScriptCore/parser/Lexer.cpp: * Source/JavaScriptCore/parser/Parser.cpp: (JSC::Parser<LexerType>::parseDestructuringPattern): (JSC::Parser<LexerType>::parseClass): (JSC::Parser<LexerType>::parseClassFieldInitializerSourceElements): (JSC::Parser<LexerType>::parseProperty): (JSC::Parser<LexerType>::parseGetterSetter): * Source/JavaScriptCore/parser/ParserArena.cpp: (JSC::IdentifierArena::makeBigIntDecimalIdentifier): * Source/JavaScriptCore/parser/ParserArena.h: Canonical link: https://commits.webkit.org/256501@main
1 parent 8900c3f commit 32b9728
Copy full SHA for 32b9728

4 files changed

+40-11Lines changed: 40 additions & 11 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file
+20Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
function foo() {
2+
let m = new WebAssembly.Memory({initial: 1000});
3+
try {
4+
foo();
5+
} catch {}
6+
for (let i = 0; i < 1000; i++) {
7+
new Uint8Array(i);
8+
}
9+
}
10+
11+
try {
12+
foo();
13+
} catch {}
14+
15+
try {
16+
eval('class C{0x1n');
17+
} catch (e) {
18+
if (!(e instanceof SyntaxError))
19+
throw e;
20+
}
Collapse file

‎Source/JavaScriptCore/parser/Parser.cpp‎

Copy file name to clipboardExpand all lines: Source/JavaScriptCore/parser/Parser.cpp
+10-7Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,7 +1316,8 @@ template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseDe
13161316
wasString = true;
13171317
break;
13181318
case BIGINT:
1319-
propertyName = &m_parserArena.identifierArena().makeBigIntDecimalIdentifier(const_cast<VM&>(m_vm), *m_token.m_data.bigIntString, m_token.m_data.radix);
1319+
propertyName = m_parserArena.identifierArena().makeBigIntDecimalIdentifier(const_cast<VM&>(m_vm), *m_token.m_data.bigIntString, m_token.m_data.radix);
1320+
failIfFalse(propertyName, "Cannot parse big int property name");
13201321
break;
13211322
case OPENBRACKET:
13221323
next();
@@ -3054,8 +3055,8 @@ template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(T
30543055
next();
30553056
break;
30563057
case BIGINT:
3057-
ident = &m_parserArena.identifierArena().makeBigIntDecimalIdentifier(const_cast<VM&>(m_vm), *m_token.m_data.bigIntString, m_token.m_data.radix);
3058-
ASSERT(ident);
3058+
ident = m_parserArena.identifierArena().makeBigIntDecimalIdentifier(const_cast<VM&>(m_vm), *m_token.m_data.bigIntString, m_token.m_data.radix);
3059+
failIfFalse(ident, "Cannot parse big int property name");
30593060
next();
30603061
break;
30613062
case ESCAPED_KEYWORD:
@@ -3316,8 +3317,8 @@ template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseClassFie
33163317
next();
33173318
break;
33183319
case BIGINT:
3319-
ident = &m_parserArena.identifierArena().makeBigIntDecimalIdentifier(const_cast<VM&>(m_vm), *m_token.m_data.bigIntString, m_token.m_data.radix);
3320-
ASSERT(ident);
3320+
ident = m_parserArena.identifierArena().makeBigIntDecimalIdentifier(const_cast<VM&>(m_vm), *m_token.m_data.bigIntString, m_token.m_data.radix);
3321+
failIfFalse(ident, "Cannot parse big int property name");
33213322
next();
33223323
break;
33233324
case DOUBLE:
@@ -4613,7 +4614,8 @@ template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
46134614
return context.createProperty(const_cast<VM&>(m_vm), m_parserArena, propertyName, node, PropertyNode::Constant, SuperBinding::NotNeeded, ClassElementTag::No);
46144615
}
46154616
case BIGINT: {
4616-
const Identifier* ident = &m_parserArena.identifierArena().makeBigIntDecimalIdentifier(const_cast<VM&>(m_vm), *m_token.m_data.bigIntString, m_token.m_data.radix);
4617+
const Identifier* ident = m_parserArena.identifierArena().makeBigIntDecimalIdentifier(const_cast<VM&>(m_vm), *m_token.m_data.bigIntString, m_token.m_data.radix);
4618+
failIfFalse(ident, "Cannot parse big int property name");
46174619
next();
46184620

46194621
if (match(OPENPAREN)) {
@@ -4705,7 +4707,8 @@ template <class TreeBuilder> TreeProperty Parser<LexerType>::parseGetterSetter(T
47054707
numericPropertyName = m_token.m_data.doubleValue;
47064708
next();
47074709
} else if (match(BIGINT)) {
4708-
stringPropertyName = &m_parserArena.identifierArena().makeBigIntDecimalIdentifier(const_cast<VM&>(m_vm), *m_token.m_data.bigIntString, m_token.m_data.radix);
4710+
stringPropertyName = m_parserArena.identifierArena().makeBigIntDecimalIdentifier(const_cast<VM&>(m_vm), *m_token.m_data.bigIntString, m_token.m_data.radix);
4711+
failIfFalse(stringPropertyName, "Cannot parse big int property name");
47094712
next();
47104713
} else if (match(OPENBRACKET)) {
47114714
next();
Collapse file

‎Source/JavaScriptCore/parser/ParserArena.cpp‎

Copy file name to clipboardExpand all lines: Source/JavaScriptCore/parser/ParserArena.cpp
+9-3Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,22 @@ void ParserArena::allocateFreeablePool()
7979
ASSERT(freeablePool() == pool);
8080
}
8181

82-
const Identifier& IdentifierArena::makeBigIntDecimalIdentifier(VM& vm, const Identifier& identifier, uint8_t radix)
82+
const Identifier* IdentifierArena::makeBigIntDecimalIdentifier(VM& vm, const Identifier& identifier, uint8_t radix)
8383
{
8484
if (radix == 10)
85-
return identifier;
85+
return &identifier;
8686

8787
DeferTermination deferScope(vm);
8888
auto scope = DECLARE_CATCH_SCOPE(vm);
8989
JSValue bigInt = JSBigInt::parseInt(nullptr, vm, identifier.string(), radix, JSBigInt::ErrorParseMode::ThrowExceptions, JSBigInt::ParseIntSign::Unsigned);
9090
scope.assertNoException();
9191

92+
if (bigInt.isEmpty()) {
93+
// Handle out-of-memory or other failures by returning null, since
94+
// we don't have a global object to throw exceptions to in this scope.
95+
return nullptr;
96+
}
97+
9298
// FIXME: We are allocating a JSBigInt just to be able to use
9399
// JSBigInt::tryGetString when radix is not 10.
94100
// This creates some GC pressure, but since these identifiers
@@ -106,7 +112,7 @@ const Identifier& IdentifierArena::makeBigIntDecimalIdentifier(VM& vm, const Ide
106112
heapBigInt = bigInt.asHeapBigInt();
107113

108114
m_identifiers.append(Identifier::fromString(vm, JSBigInt::tryGetString(vm, heapBigInt, 10)));
109-
return m_identifiers.last();
115+
return &m_identifiers.last();
110116
}
111117

112118
const Identifier& IdentifierArena::makePrivateIdentifier(VM& vm, ASCIILiteral prefix, unsigned identifier)
Collapse file

‎Source/JavaScriptCore/parser/ParserArena.h‎

Copy file name to clipboardExpand all lines: Source/JavaScriptCore/parser/ParserArena.h
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ namespace JSC {
5050
ALWAYS_INLINE const Identifier& makeIdentifierLCharFromUChar(VM&, const UChar* characters, size_t length);
5151
ALWAYS_INLINE const Identifier& makeIdentifier(VM&, SymbolImpl*);
5252

53-
const Identifier& makeBigIntDecimalIdentifier(VM&, const Identifier&, uint8_t radix);
53+
const Identifier* makeBigIntDecimalIdentifier(VM&, const Identifier&, uint8_t radix);
5454
const Identifier& makeNumericIdentifier(VM&, double number);
5555
const Identifier& makePrivateIdentifier(VM&, ASCIILiteral, unsigned);
5656

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.