Skip to content
Permalink
Browse files
Add support to throw OOM if MarkedArgumentBuffer may overflow.
https://bugs.webkit.org/show_bug.cgi?id=179092
<rdar://problem/35116160>

Reviewed by Saam Barati.

Source/JavaScriptCore:

The test for overflowing a MarkedArgumentBuffer will run for a ridiculously long
time, which renders it unsuitable for automated tests.  Instead, I've run a
test manually to verify that an OutOfMemoryError will be thrown when an overflow
occurs.

The MarkedArgumentBuffer's destructor will now assert that the client has indeed
checked for an overflow after invoking methods that may result in an overflow i.e.
the destructor checks that MarkedArgumentBuffer::hasOverflowed() has been called.
This is only done on debug builds.

* API/JSObjectRef.cpp:
(JSObjectMakeFunction):
(JSObjectMakeArray):
(JSObjectMakeDate):
(JSObjectMakeRegExp):
(JSObjectCallAsFunction):
(JSObjectCallAsConstructor):
* dfg/DFGOperations.cpp:
* inspector/InjectedScriptManager.cpp:
(Inspector::InjectedScriptManager::createInjectedScript):
* inspector/JSJavaScriptCallFrame.cpp:
(Inspector::JSJavaScriptCallFrame::scopeChain const):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::executeProgram):
* jsc.cpp:
(functionDollarAgentReceiveBroadcast):
* runtime/ArgList.cpp:
(JSC::MarkedArgumentBuffer::slowEnsureCapacity):
(JSC::MarkedArgumentBuffer::expandCapacity):
(JSC::MarkedArgumentBuffer::slowAppend):
* runtime/ArgList.h:
(JSC::MarkedArgumentBuffer::~MarkedArgumentBuffer):
(JSC::MarkedArgumentBuffer::appendWithAction):
(JSC::MarkedArgumentBuffer::append):
(JSC::MarkedArgumentBuffer::appendWithCrashOnOverflow):
(JSC::MarkedArgumentBuffer::hasOverflowed):
(JSC::MarkedArgumentBuffer::setNeedsOverflowCheck):
(JSC::MarkedArgumentBuffer::clearNeedsOverflowCheck):
* runtime/ArrayPrototype.cpp:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/GetterSetter.cpp:
(JSC::callSetter):
* runtime/IteratorOperations.cpp:
(JSC::iteratorNext):
(JSC::iteratorClose):
* runtime/JSBoundFunction.cpp:
(JSC::boundThisNoArgsFunctionCall):
(JSC::boundFunctionCall):
(JSC::boundThisNoArgsFunctionConstruct):
(JSC::boundFunctionConstruct):
* runtime/JSGenericTypedArrayViewConstructorInlines.h:
(JSC::constructGenericTypedArrayViewFromIterator):
* runtime/JSGenericTypedArrayViewPrototypeFunctions.h:
(JSC::genericTypedArrayViewProtoFuncSlice):
(JSC::genericTypedArrayViewPrivateFuncSubarrayCreate):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::haveABadTime):
* runtime/JSInternalPromise.cpp:
(JSC::JSInternalPromise::then):
* runtime/JSJob.cpp:
(JSC::JSJobMicrotask::run):
* runtime/JSMapIterator.cpp:
(JSC::JSMapIterator::createPair):
* runtime/JSModuleLoader.cpp:
(JSC::JSModuleLoader::provideFetch):
(JSC::JSModuleLoader::loadAndEvaluateModule):
(JSC::JSModuleLoader::loadModule):
(JSC::JSModuleLoader::linkAndEvaluateModule):
(JSC::JSModuleLoader::requestImportModule):
* runtime/JSONObject.cpp:
(JSC::Stringifier::toJSONImpl):
(JSC::Stringifier::appendStringifiedValue):
(JSC::Walker::callReviver):
* runtime/JSObject.cpp:
(JSC::ordinarySetSlow):
(JSC::callToPrimitiveFunction):
(JSC::JSObject::hasInstance):
* runtime/JSPromise.cpp:
(JSC::JSPromise::initialize):
(JSC::JSPromise::resolve):
* runtime/JSPromiseDeferred.cpp:
(JSC::newPromiseCapability):
(JSC::callFunction):
* runtime/JSSetIterator.cpp:
(JSC::JSSetIterator::createPair):
* runtime/LiteralParser.cpp:
(JSC::LiteralParser<CharType>::parse):
* runtime/MapConstructor.cpp:
(JSC::constructMap):
* runtime/ObjectConstructor.cpp:
(JSC::defineProperties):
* runtime/ProxyObject.cpp:
(JSC::performProxyGet):
(JSC::ProxyObject::performInternalMethodGetOwnProperty):
(JSC::ProxyObject::performHasProperty):
(JSC::ProxyObject::performPut):
(JSC::performProxyCall):
(JSC::performProxyConstruct):
(JSC::ProxyObject::performDelete):
(JSC::ProxyObject::performPreventExtensions):
(JSC::ProxyObject::performIsExtensible):
(JSC::ProxyObject::performDefineOwnProperty):
(JSC::ProxyObject::performGetOwnPropertyNames):
(JSC::ProxyObject::performSetPrototype):
(JSC::ProxyObject::performGetPrototype):
* runtime/ReflectObject.cpp:
(JSC::reflectObjectConstruct):
* runtime/SetConstructor.cpp:
(JSC::constructSet):
* runtime/StringPrototype.cpp:
(JSC::replaceUsingRegExpSearch):
(JSC::replaceUsingStringSearch):
* runtime/WeakMapConstructor.cpp:
(JSC::constructWeakMap):
* runtime/WeakSetConstructor.cpp:
(JSC::constructWeakSet):
* wasm/js/WasmToJS.cpp:
(JSC::Wasm::wasmToJS):

Source/WebCore:

No new tests.  The test for overflowing a MarkedArgumentBuffer will run for a
ridiculously long time, which renders it unsuitable for automated tests.

* Modules/plugins/QuickTimePluginReplacement.mm:
(WebCore::QuickTimePluginReplacement::installReplacement):
* bindings/js/JSCustomElementInterface.cpp:
(WebCore::constructCustomElementSynchronously):
(WebCore::JSCustomElementInterface::upgradeElement):
(WebCore::JSCustomElementInterface::invokeCallback):
* bindings/js/JSCustomXPathNSResolver.cpp:
(WebCore::JSCustomXPathNSResolver::lookupNamespaceURI):
* bindings/js/JSDOMBuiltinConstructorBase.cpp:
(WebCore::JSDOMBuiltinConstructorBase::callFunctionWithCurrentArguments):
* bindings/js/JSDOMConvertSequences.h:
(WebCore::JSConverter<IDLSequence<T>>::convert):
(WebCore::JSConverter<IDLFrozenArray<T>>::convert):
* bindings/js/JSDOMConvertWebGL.cpp:
(WebCore::convertToJSValue):
* bindings/js/JSDOMIterator.h:
(WebCore::jsPair):
(WebCore::iteratorForEach):
* bindings/js/JSDOMMapLike.cpp:
(WebCore::forwardFunctionCallToBackingMap):
(WebCore::forwardForEachCallToBackingMap):
* bindings/js/JSDOMPromiseDeferred.cpp:
(WebCore::DeferredPromise::callFunction):
(WebCore::createRejectedPromiseWithTypeError):
* bindings/js/JSErrorHandler.cpp:
(WebCore::JSErrorHandler::handleEvent):
* bindings/js/JSEventListener.cpp:
(WebCore::JSEventListener::handleEvent):
* bindings/js/JSLazyEventListener.cpp:
(WebCore::JSLazyEventListener::initializeJSFunction const):
* bindings/js/JSPluginElementFunctions.cpp:
(WebCore::callPlugin):
* bindings/js/JSReadableStreamPrivateConstructors.cpp:
(WebCore::constructJSReadableStreamReaderGeneric):
* bindings/js/ReadableStream.cpp:
(WebCore::ReadableStream::create):
(WebCore::ReadableStream::pipeTo):
(WebCore::ReadableStream::tee):
(WebCore::ReadableStream::lock):
(WebCore::checkReadableStream):
* bindings/js/ReadableStreamDefaultController.cpp:
(WebCore::ReadableStreamDefaultController::invoke):
* bindings/js/ScheduledAction.cpp:
(WebCore::ScheduledAction::executeFunctionInContext):
* bindings/js/SerializedScriptValue.cpp:
(WebCore::CloneSerializer::recordObject):
(WebCore::CloneSerializer::serialize):
(WebCore::CloneDeserializer::readTerminal):
(WebCore::CloneDeserializer::deserialize):
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateCallbackImplementationContent):
* bindings/scripts/test/JS/JSTestCallbackFunction.cpp:
(WebCore::JSTestCallbackFunction::handleEvent):
* bindings/scripts/test/JS/JSTestCallbackFunctionRethrow.cpp:
(WebCore::JSTestCallbackFunctionRethrow::handleEvent):
* bindings/scripts/test/JS/JSTestCallbackFunctionWithThisObject.cpp:
(WebCore::JSTestCallbackFunctionWithThisObject::handleEvent):
* bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.cpp:
(WebCore::JSTestCallbackFunctionWithTypedefs::handleEvent):
* bindings/scripts/test/JS/JSTestCallbackInterface.cpp:
(WebCore::JSTestCallbackInterface::callbackWithNoParam):
(WebCore::JSTestCallbackInterface::callbackWithArrayParam):
(WebCore::JSTestCallbackInterface::callbackWithSerializedScriptValueParam):
(WebCore::JSTestCallbackInterface::callbackWithStringList):
(WebCore::JSTestCallbackInterface::callbackWithBoolean):
(WebCore::JSTestCallbackInterface::callbackRequiresThisToPass):
(WebCore::JSTestCallbackInterface::callbackWithAReturnValue):
(WebCore::JSTestCallbackInterface::callbackThatRethrowsExceptions):
(WebCore::JSTestCallbackInterface::callbackThatSkipsInvokeCheck):
(WebCore::JSTestCallbackInterface::callbackWithThisObject):
* bindings/scripts/test/JS/JSTestVoidCallbackFunction.cpp:
(WebCore::JSTestVoidCallbackFunction::handleEvent):
* bridge/NP_jsobject.cpp:
* bridge/objc/WebScriptObject.mm:
(-[WebScriptObject callWebScriptMethod:withArguments:]):
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::updateCaptionContainer):
(WebCore::HTMLMediaElement::didAddUserAgentShadowRoot):
(WebCore::HTMLMediaElement::updateMediaControlsAfterPresentationModeChange):
(WebCore::HTMLMediaElement::getCurrentMediaControlsStatus):
* html/HTMLPlugInImageElement.cpp:
(WebCore::HTMLPlugInImageElement::didAddUserAgentShadowRoot):
* testing/Internals.cpp:
(WebCore::Internals::cloneArrayBuffer):



Canonical link: https://commits.webkit.org/195256@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224309 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Mark Lam committed Nov 2, 2017
1 parent 94d2dcd commit bb10620b0b1b5b3494d4b3d8bdbedf35d049a501
Showing with 533 additions and 61 deletions.
  1. +36 −0 Source/JavaScriptCore/API/JSObjectRef.cpp
  2. +128 −0 Source/JavaScriptCore/ChangeLog
  3. +1 −0 Source/JavaScriptCore/dfg/DFGOperations.cpp
  4. +2 −1 Source/JavaScriptCore/inspector/InjectedScriptManager.cpp
  5. +8 −1 Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp
  6. +1 −0 Source/JavaScriptCore/interpreter/Interpreter.cpp
  7. +2 −0 Source/JavaScriptCore/jsc.cpp
  8. +19 −6 Source/JavaScriptCore/runtime/ArgList.cpp
  9. +35 −6 Source/JavaScriptCore/runtime/ArgList.h
  10. +1 −0 Source/JavaScriptCore/runtime/ArrayPrototype.cpp
  11. +1 −0 Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
  12. +2 −1 Source/JavaScriptCore/runtime/GetterSetter.cpp
  13. +2 −0 Source/JavaScriptCore/runtime/IteratorOperations.cpp
  14. +16 −0 Source/JavaScriptCore/runtime/JSBoundFunction.cpp
  15. +5 −1 Source/JavaScriptCore/runtime/JSGenericTypedArrayViewConstructorInlines.h
  16. +2 −0 Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h
  17. +1 −0 Source/JavaScriptCore/runtime/JSGlobalObject.cpp
  18. +2 −1 Source/JavaScriptCore/runtime/JSInternalPromise.cpp
  19. +3 −1 Source/JavaScriptCore/runtime/JSJob.cpp
  20. +2 −1 Source/JavaScriptCore/runtime/JSMapIterator.cpp
  21. +6 −1 Source/JavaScriptCore/runtime/JSModuleLoader.cpp
  22. +3 −0 Source/JavaScriptCore/runtime/JSONObject.cpp
  23. +3 −0 Source/JavaScriptCore/runtime/JSObject.cpp
  24. +3 −1 Source/JavaScriptCore/runtime/JSPromise.cpp
  25. +3 −1 Source/JavaScriptCore/runtime/JSPromiseDeferred.cpp
  26. +2 −1 Source/JavaScriptCore/runtime/JSSetIterator.cpp
  27. +3 −3 Source/JavaScriptCore/runtime/LiteralParser.cpp
  28. +2 −1 Source/JavaScriptCore/runtime/MapConstructor.cpp
  29. +1 −0 Source/JavaScriptCore/runtime/ObjectConstructor.cpp
  30. +14 −1 Source/JavaScriptCore/runtime/ProxyObject.cpp
  31. +4 −0 Source/JavaScriptCore/runtime/ReflectObject.cpp
  32. +2 −1 Source/JavaScriptCore/runtime/SetConstructor.cpp
  33. +5 −0 Source/JavaScriptCore/runtime/StringPrototype.cpp
  34. +2 −1 Source/JavaScriptCore/runtime/WeakMapConstructor.cpp
  35. +2 −1 Source/JavaScriptCore/runtime/WeakSetConstructor.cpp
  36. +4 −0 Source/JavaScriptCore/wasm/js/WasmToJS.cpp
  37. +96 −0 Source/WebCore/ChangeLog
  38. +1 −0 Source/WebCore/Modules/plugins/QuickTimePluginReplacement.mm
  39. +4 −1 Source/WebCore/bindings/js/JSCustomElementInterface.cpp
  40. +1 −0 Source/WebCore/bindings/js/JSCustomXPathNSResolver.cpp
  41. +7 −1 Source/WebCore/bindings/js/JSDOMBuiltinConstructorBase.cpp
  42. +13 −1 Source/WebCore/bindings/js/JSDOMConvertSequences.h
  43. +2 −0 Source/WebCore/bindings/js/JSDOMConvertWebGL.cpp
  44. +6 −1 Source/WebCore/bindings/js/JSDOMIterator.h
  45. +2 −0 Source/WebCore/bindings/js/JSDOMMapLike.cpp
  46. +2 −0 Source/WebCore/bindings/js/JSDOMPromiseDeferred.cpp
  47. +2 −1 Source/WebCore/bindings/js/JSErrorHandler.cpp
  48. +1 −0 Source/WebCore/bindings/js/JSEventListener.cpp
  49. +1 −0 Source/WebCore/bindings/js/JSLazyEventListener.cpp
  50. +1 −0 Source/WebCore/bindings/js/JSPluginElementFunctions.cpp
  51. +2 −1 Source/WebCore/bindings/js/JSReadableStreamPrivateConstructors.cpp
  52. +5 −0 Source/WebCore/bindings/js/ReadableStream.cpp
  53. +1 −0 Source/WebCore/bindings/js/ReadableStreamDefaultController.cpp
  54. +10 −2 Source/WebCore/bindings/js/ScheduledAction.cpp
  55. +20 −20 Source/WebCore/bindings/js/SerializedScriptValue.cpp
  56. +1 −0 Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
  57. +1 −0 Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunction.cpp
  58. +1 −0 Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionRethrow.cpp
  59. +1 −0 Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithThisObject.cpp
  60. +1 −0 Source/WebCore/bindings/scripts/test/JS/JSTestCallbackFunctionWithTypedefs.cpp
  61. +10 −0 Source/WebCore/bindings/scripts/test/JS/JSTestCallbackInterface.cpp
  62. +1 −0 Source/WebCore/bindings/scripts/test/JS/JSTestVoidCallbackFunction.cpp
  63. +4 −1 Source/WebCore/bridge/NP_jsobject.cpp
  64. +2 −1 Source/WebCore/bridge/objc/WebScriptObject.mm
  65. +4 −0 Source/WebCore/html/HTMLMediaElement.cpp
  66. +1 −0 Source/WebCore/html/HTMLPlugInImageElement.cpp
  67. +1 −0 Source/WebCore/testing/Internals.cpp
@@ -151,6 +151,12 @@ JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned pa
for (unsigned i = 0; i < parameterCount; i++)
args.append(jsString(exec, parameterNames[i]->string()));
args.append(jsString(exec, body->string()));
if (UNLIKELY(args.hasOverflowed())) {
auto throwScope = DECLARE_THROW_SCOPE(vm);
throwOutOfMemoryError(exec, throwScope);
handleExceptionIfNeeded(scope, exec, exception);
return 0;
}

auto sourceURLString = sourceURL ? sourceURL->string() : String();
JSObject* result = constructFunction(exec, exec->lexicalGlobalObject(), args, nameID, SourceOrigin { sourceURLString }, sourceURLString, TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber()));
@@ -175,6 +181,12 @@ JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSVa
MarkedArgumentBuffer argList;
for (size_t i = 0; i < argumentCount; ++i)
argList.append(toJS(exec, arguments[i]));
if (UNLIKELY(argList.hasOverflowed())) {
auto throwScope = DECLARE_THROW_SCOPE(vm);
throwOutOfMemoryError(exec, throwScope);
handleExceptionIfNeeded(scope, exec, exception);
return 0;
}

result = constructArray(exec, static_cast<ArrayAllocationProfile*>(0), argList);
} else
@@ -200,6 +212,12 @@ JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSVal
MarkedArgumentBuffer argList;
for (size_t i = 0; i < argumentCount; ++i)
argList.append(toJS(exec, arguments[i]));
if (UNLIKELY(argList.hasOverflowed())) {
auto throwScope = DECLARE_THROW_SCOPE(vm);
throwOutOfMemoryError(exec, throwScope);
handleExceptionIfNeeded(scope, exec, exception);
return 0;
}

JSObject* result = constructDate(exec, exec->lexicalGlobalObject(), JSValue(), argList);
if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
@@ -243,6 +261,12 @@ JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSV
MarkedArgumentBuffer argList;
for (size_t i = 0; i < argumentCount; ++i)
argList.append(toJS(exec, arguments[i]));
if (UNLIKELY(argList.hasOverflowed())) {
auto throwScope = DECLARE_THROW_SCOPE(vm);
throwOutOfMemoryError(exec, throwScope);
handleExceptionIfNeeded(scope, exec, exception);
return 0;
}

JSObject* result = constructRegExp(exec, exec->lexicalGlobalObject(), argList);
if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
@@ -581,6 +605,12 @@ JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObject
MarkedArgumentBuffer argList;
for (size_t i = 0; i < argumentCount; i++)
argList.append(toJS(exec, arguments[i]));
if (UNLIKELY(argList.hasOverflowed())) {
auto throwScope = DECLARE_THROW_SCOPE(vm);
throwOutOfMemoryError(exec, throwScope);
handleExceptionIfNeeded(scope, exec, exception);
return 0;
}

CallData callData;
CallType callType = jsObject->methodTable(vm)->getCallData(jsObject, callData);
@@ -622,6 +652,12 @@ JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size
MarkedArgumentBuffer argList;
for (size_t i = 0; i < argumentCount; i++)
argList.append(toJS(exec, arguments[i]));
if (UNLIKELY(argList.hasOverflowed())) {
auto throwScope = DECLARE_THROW_SCOPE(vm);
throwOutOfMemoryError(exec, throwScope);
handleExceptionIfNeeded(scope, exec, exception);
return 0;
}

JSObjectRef result = toRef(profiledConstruct(exec, ProfilingReason::API, jsObject, constructType, constructData, argList));
if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow)
@@ -1,3 +1,131 @@
2017-11-01 Mark Lam <mark.lam@apple.com>

Add support to throw OOM if MarkedArgumentBuffer may overflow.
https://bugs.webkit.org/show_bug.cgi?id=179092
<rdar://problem/35116160>

Reviewed by Saam Barati.

The test for overflowing a MarkedArgumentBuffer will run for a ridiculously long
time, which renders it unsuitable for automated tests. Instead, I've run a
test manually to verify that an OutOfMemoryError will be thrown when an overflow
occurs.

The MarkedArgumentBuffer's destructor will now assert that the client has indeed
checked for an overflow after invoking methods that may result in an overflow i.e.
the destructor checks that MarkedArgumentBuffer::hasOverflowed() has been called.
This is only done on debug builds.

* API/JSObjectRef.cpp:
(JSObjectMakeFunction):
(JSObjectMakeArray):
(JSObjectMakeDate):
(JSObjectMakeRegExp):
(JSObjectCallAsFunction):
(JSObjectCallAsConstructor):
* dfg/DFGOperations.cpp:
* inspector/InjectedScriptManager.cpp:
(Inspector::InjectedScriptManager::createInjectedScript):
* inspector/JSJavaScriptCallFrame.cpp:
(Inspector::JSJavaScriptCallFrame::scopeChain const):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::executeProgram):
* jsc.cpp:
(functionDollarAgentReceiveBroadcast):
* runtime/ArgList.cpp:
(JSC::MarkedArgumentBuffer::slowEnsureCapacity):
(JSC::MarkedArgumentBuffer::expandCapacity):
(JSC::MarkedArgumentBuffer::slowAppend):
* runtime/ArgList.h:
(JSC::MarkedArgumentBuffer::~MarkedArgumentBuffer):
(JSC::MarkedArgumentBuffer::appendWithAction):
(JSC::MarkedArgumentBuffer::append):
(JSC::MarkedArgumentBuffer::appendWithCrashOnOverflow):
(JSC::MarkedArgumentBuffer::hasOverflowed):
(JSC::MarkedArgumentBuffer::setNeedsOverflowCheck):
(JSC::MarkedArgumentBuffer::clearNeedsOverflowCheck):
* runtime/ArrayPrototype.cpp:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/GetterSetter.cpp:
(JSC::callSetter):
* runtime/IteratorOperations.cpp:
(JSC::iteratorNext):
(JSC::iteratorClose):
* runtime/JSBoundFunction.cpp:
(JSC::boundThisNoArgsFunctionCall):
(JSC::boundFunctionCall):
(JSC::boundThisNoArgsFunctionConstruct):
(JSC::boundFunctionConstruct):
* runtime/JSGenericTypedArrayViewConstructorInlines.h:
(JSC::constructGenericTypedArrayViewFromIterator):
* runtime/JSGenericTypedArrayViewPrototypeFunctions.h:
(JSC::genericTypedArrayViewProtoFuncSlice):
(JSC::genericTypedArrayViewPrivateFuncSubarrayCreate):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::haveABadTime):
* runtime/JSInternalPromise.cpp:
(JSC::JSInternalPromise::then):
* runtime/JSJob.cpp:
(JSC::JSJobMicrotask::run):
* runtime/JSMapIterator.cpp:
(JSC::JSMapIterator::createPair):
* runtime/JSModuleLoader.cpp:
(JSC::JSModuleLoader::provideFetch):
(JSC::JSModuleLoader::loadAndEvaluateModule):
(JSC::JSModuleLoader::loadModule):
(JSC::JSModuleLoader::linkAndEvaluateModule):
(JSC::JSModuleLoader::requestImportModule):
* runtime/JSONObject.cpp:
(JSC::Stringifier::toJSONImpl):
(JSC::Stringifier::appendStringifiedValue):
(JSC::Walker::callReviver):
* runtime/JSObject.cpp:
(JSC::ordinarySetSlow):
(JSC::callToPrimitiveFunction):
(JSC::JSObject::hasInstance):
* runtime/JSPromise.cpp:
(JSC::JSPromise::initialize):
(JSC::JSPromise::resolve):
* runtime/JSPromiseDeferred.cpp:
(JSC::newPromiseCapability):
(JSC::callFunction):
* runtime/JSSetIterator.cpp:
(JSC::JSSetIterator::createPair):
* runtime/LiteralParser.cpp:
(JSC::LiteralParser<CharType>::parse):
* runtime/MapConstructor.cpp:
(JSC::constructMap):
* runtime/ObjectConstructor.cpp:
(JSC::defineProperties):
* runtime/ProxyObject.cpp:
(JSC::performProxyGet):
(JSC::ProxyObject::performInternalMethodGetOwnProperty):
(JSC::ProxyObject::performHasProperty):
(JSC::ProxyObject::performPut):
(JSC::performProxyCall):
(JSC::performProxyConstruct):
(JSC::ProxyObject::performDelete):
(JSC::ProxyObject::performPreventExtensions):
(JSC::ProxyObject::performIsExtensible):
(JSC::ProxyObject::performDefineOwnProperty):
(JSC::ProxyObject::performGetOwnPropertyNames):
(JSC::ProxyObject::performSetPrototype):
(JSC::ProxyObject::performGetPrototype):
* runtime/ReflectObject.cpp:
(JSC::reflectObjectConstruct):
* runtime/SetConstructor.cpp:
(JSC::constructSet):
* runtime/StringPrototype.cpp:
(JSC::replaceUsingRegExpSearch):
(JSC::replaceUsingStringSearch):
* runtime/WeakMapConstructor.cpp:
(JSC::constructWeakMap):
* runtime/WeakSetConstructor.cpp:
(JSC::constructWeakSet):
* wasm/js/WasmToJS.cpp:
(JSC::Wasm::wasmToJS):

2017-11-01 Michael Saboff <msaboff@apple.com>

Integer overflow in code generated by LoadVarargs processing in DFG and FTL.
@@ -2406,6 +2406,7 @@ JSCell* JIT_OPERATION operationSpreadGeneric(ExecState* exec, JSCell* iterable)

MarkedArgumentBuffer arguments;
arguments.append(iterable);
ASSERT(!arguments.hasOverflowed());
JSValue arrayResult = call(exec, iterationFunction, callType, callData, jsNull(), arguments);
RETURN_IF_EXCEPTION(throwScope, nullptr);
array = jsCast<JSArray*>(arrayResult);
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2007, 2008, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2007-2017 Apple Inc. All rights reserved.
* Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
* Copyright (C) 2012 Google Inc. All rights reserved.
*
@@ -158,6 +158,7 @@ JSC::JSObject* InjectedScriptManager::createInjectedScript(const String& source,
args.append(m_injectedScriptHost->wrapper(scriptState, globalObject));
args.append(globalThisValue);
args.append(jsNumber(id));
ASSERT(!args.hasOverflowed());

JSValue result = JSC::call(scriptState, functionValue, callType, callData, globalThisValue, args);
scope.clearException();
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
* Copyright (C) 2014-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -180,6 +180,9 @@ JSValue JSJavaScriptCallFrame::functionName(ExecState* exec) const

JSValue JSJavaScriptCallFrame::scopeChain(ExecState* exec) const
{
VM& vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

if (!impl().scopeChain())
return jsNull();

@@ -195,6 +198,10 @@ JSValue JSJavaScriptCallFrame::scopeChain(ExecState* exec) const
list.append(iter.get());
++iter;
} while (iter != end);
if (UNLIKELY(list.hasOverflowed())) {
throwOutOfMemoryError(exec, scope);
return { };
}

return constructArray(exec, nullptr, globalObject(), list);
}
@@ -862,6 +862,7 @@ JSValue Interpreter::executeProgram(const SourceCode& source, CallFrame* callFra
return throwException(callFrame, throwScope, createNotAFunctionError(callFrame, function));
MarkedArgumentBuffer jsonArg;
jsonArg.append(JSONPValue);
ASSERT(!jsonArg.hasOverflowed());
JSValue thisValue = JSONPPath.size() == 1 ? jsUndefined(): baseObject;
JSONPValue = JSC::call(callFrame, function, callType, callData, thisValue, jsonArg);
RETURN_IF_EXCEPTION(throwScope, JSValue());
@@ -2911,6 +2911,8 @@ EncodedJSValue JSC_HOST_CALL functionDollarAgentReceiveBroadcast(ExecState* exec
MarkedArgumentBuffer args;
args.append(jsBuffer);
args.append(jsNumber(message->index()));
if (UNLIKELY(args.hasOverflowed()))
return JSValue::encode(throwOutOfMemoryError(exec, scope));
scope.release();
return JSValue::encode(call(exec, callback, callType, callData, jsNull(), args));
}
@@ -65,21 +65,30 @@ void MarkedArgumentBuffer::markLists(SlotVisitor& visitor, ListSet& markSet)

void MarkedArgumentBuffer::slowEnsureCapacity(size_t requestedCapacity)
{
int newCapacity = Checked<int>(requestedCapacity).unsafeGet();
expandCapacity(newCapacity);
setNeedsOverflowCheck();
auto checkedNewCapacity = Checked<int, RecordOverflow>(requestedCapacity);
if (UNLIKELY(checkedNewCapacity.hasOverflowed()))
return this->overflowed();
expandCapacity(checkedNewCapacity.unsafeGet());
}

void MarkedArgumentBuffer::expandCapacity()
{
int newCapacity = (Checked<int>(m_capacity) * 2).unsafeGet();
expandCapacity(newCapacity);
setNeedsOverflowCheck();
auto checkedNewCapacity = Checked<int, RecordOverflow>(m_capacity) * 2;
if (UNLIKELY(checkedNewCapacity.hasOverflowed()))
return this->overflowed();
expandCapacity(checkedNewCapacity.unsafeGet());
}

void MarkedArgumentBuffer::expandCapacity(int newCapacity)
{
setNeedsOverflowCheck();
ASSERT(m_capacity < newCapacity);
size_t size = (Checked<size_t>(newCapacity) * sizeof(EncodedJSValue)).unsafeGet();
EncodedJSValue* newBuffer = static_cast<EncodedJSValue*>(fastMalloc(size));
auto checkedSize = Checked<size_t, RecordOverflow>(newCapacity) * sizeof(EncodedJSValue);
if (UNLIKELY(checkedSize.hasOverflowed()))
return this->overflowed();
EncodedJSValue* newBuffer = static_cast<EncodedJSValue*>(fastMalloc(checkedSize.unsafeGet()));
for (int i = 0; i < m_size; ++i) {
newBuffer[i] = m_buffer[i];
addMarkSet(JSValue::decode(m_buffer[i]));
@@ -97,6 +106,10 @@ void MarkedArgumentBuffer::slowAppend(JSValue v)
ASSERT(m_size <= m_capacity);
if (m_size == m_capacity)
expandCapacity();
if (UNLIKELY(Base::hasOverflowed())) {
ASSERT(m_needsOverflowCheck);
return;
}

slotFor(m_size) = JSValue::encode(v);
++m_size;

0 comments on commit bb10620

Please sign in to comment.