Correctly detect string overflow when using the 'Function' constructor
authorrmorisset@apple.com <rmorisset@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 1 May 2018 16:01:25 +0000 (16:01 +0000)
committerrmorisset@apple.com <rmorisset@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 1 May 2018 16:01:25 +0000 (16:01 +0000)
commit7e384ec2968250e6b5db20dcdc9b17752fbea79d
tree1906b2a983ff8e0ec6317d2b3ef380d5e590f3c4
parent6dff1f7360c9529043ff87e3a8666d9dc005b4c2
Correctly detect string overflow when using the 'Function' constructor
https://bugs.webkit.org/show_bug.cgi?id=184883
<rdar://problem/36320331>

Reviewed by Filip Pizlo.

JSTests:

I put this regression test in the 'slowMicrobenchmarks' directory because it takes nearly 30s to run, and I am not sure where else to put it.

* slowMicrobenchmarks/function-constructor-with-huge-strings.js: Added.
(catch):

Source/JavaScriptCore:

The 'Function' constructor creates a string containing the source code of the new function through repeated string concatenation.
Because there was no way for the string concatenation routines in WTF to return an error, they just crashed in that case.

I added new tryAppend methods alongside the old append methods, that return a boolean (true means success, false means an overflow happened).
In this way, it becomes possible for the Function constructor to just throw a proper JS exception when asked to create a string > 4GB.
I made new methods instead of just adapting the existing ones (and reverted such a change on appendQuotedJSONString) so that callers that rely on the old behaviour (a hard CRASH() on overflow) don't silently start failing.

* runtime/FunctionConstructor.cpp:
(JSC::constructFunctionSkippingEvalEnabledCheck):
* runtime/JSONObject.cpp:
(JSC::Stringifier::appendStringifiedValue):

Source/WTF:

I added new tryAppend methods alongside the old append methods in StringBuilder, that return a boolean (true means success, false means an overflow happened).
I made new methods instead of just adapting the existing ones (and reverted such a change on appendQuotedJSONString) so that callers that rely on the old behaviour (a hard CRASH() on overflow) don't silently start failing.

* wtf/text/StringBuilder.cpp:
(WTF::StringBuilder::allocateBufferUpConvert):
(WTF::StringBuilder::tryAllocateBufferUpConvert):
(WTF::StringBuilder::appendUninitialized):
(WTF::StringBuilder::append):
(WTF::StringBuilder::tryAppend):
* wtf/text/StringBuilder.h:
(WTF::StringBuilder::tryAppend):
(WTF::StringBuilder::append):
(WTF::StringBuilder::tryAppendLiteral):
* wtf/text/StringBuilderJSON.cpp:
(WTF::StringBuilder::appendQuotedJSONString):
(WTF::StringBuilder::tryAppendQuotedJSONString):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231197 268f45cc-cd09-0410-ab3c-d52691b4dbfc
JSTests/ChangeLog
JSTests/slowMicrobenchmarks/function-constructor-with-huge-strings.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/FunctionConstructor.cpp
Source/JavaScriptCore/runtime/JSONObject.cpp
Source/WTF/ChangeLog
Source/WTF/wtf/text/StringBuilder.cpp
Source/WTF/wtf/text/StringBuilder.h
Source/WTF/wtf/text/StringBuilderJSON.cpp