The new array with spread operation needs to check for length overflows.
https://bugs.webkit.org/show_bug.cgi?id=169780
<rdar://problem/31072182>
Reviewed by Filip Pizlo.
* dfg/DFGOperations.cpp:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileNewArrayWithSpread):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNewArrayWithSpread):
* ftl/FTLOperations.cpp:
(JSC::FTL::operationMaterializeObjectInOSR):
* llint/LLIntSlowPaths.cpp:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/JSGlobalObject.cpp:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@214071 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp
index 6e3a7e0..35ae636 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2013-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-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
@@ -1998,16 +1998,21 @@
auto scope = DECLARE_THROW_SCOPE(vm);
EncodedJSValue* values = static_cast<EncodedJSValue*>(buffer);
- unsigned length = 0;
+ Checked<unsigned, RecordOverflow> checkedLength = 0;
for (unsigned i = 0; i < numItems; i++) {
JSValue value = JSValue::decode(values[i]);
if (JSFixedArray* array = jsDynamicCast<JSFixedArray*>(vm, value))
- length += array->size();
+ checkedLength += array->size();
else
- ++length;
+ ++checkedLength;
}
+ if (UNLIKELY(checkedLength.hasOverflowed())) {
+ throwOutOfMemoryError(exec, scope);
+ return nullptr;
+ }
+ unsigned length = checkedLength.unsafeGet();
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);