Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/ChangeLog (214759 => 214760)
--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/ChangeLog 2017-04-03 10:11:25 UTC (rev 214759)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/ChangeLog 2017-04-03 10:12:38 UTC (rev 214760)
@@ -1,5 +1,17 @@
2017-03-16 Mark Lam <mark....@apple.com>
+ Array concat operation should check for length overflows.
+ https://bugs.webkit.org/show_bug.cgi?id=169796
+ <rdar://problem/31095276>
+
+ Reviewed by Keith Miller.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::concatAppendOne):
+ (JSC::arrayProtoPrivateFuncConcatMemcpy):
+
+2017-03-16 Mark Lam <mark....@apple.com>
+
The new array with spread operation needs to check for length overflows.
https://bugs.webkit.org/show_bug.cgi?id=169780
<rdar://problem/31072182>
Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/ArrayPrototype.cpp (214759 => 214760)
--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2017-04-03 10:11:25 UTC (rev 214759)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2017-04-03 10:12:38 UTC (rev 214760)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (por...@kde.org)
- * Copyright (C) 2003, 2007-2009, 2011, 2013, 2015-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2003-2017 Apple Inc. All rights reserved.
* Copyright (C) 2003 Peter Kelly (p...@post.com)
* Copyright (C) 2006 Alexey Proskuryakov (a...@nypop.com)
*
@@ -1205,6 +1205,14 @@
Butterfly* firstButterfly = first->butterfly();
unsigned firstArraySize = firstButterfly->publicLength();
+ Checked<unsigned, RecordOverflow> checkedResultSize = firstArraySize;
+ checkedResultSize += 1;
+ if (UNLIKELY(checkedResultSize.hasOverflowed())) {
+ throwOutOfMemoryError(exec, scope);
+ return encodedJSValue();
+ }
+
+ unsigned resultSize = checkedResultSize.unsafeGet();
IndexingType type = first->mergeIndexingTypeForCopying(indexingTypeForValue(second) | IsArray);
if (type == NonArray)
@@ -1211,9 +1219,11 @@
type = first->indexingType();
Structure* resultStructure = exec->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(type);
- JSArray* result = JSArray::create(vm, resultStructure, firstArraySize + 1);
- if (!result)
- return JSValue::encode(throwOutOfMemoryError(exec, scope));
+ JSArray* result = JSArray::create(vm, resultStructure, resultSize);
+ if (UNLIKELY(!result)) {
+ throwOutOfMemoryError(exec, scope);
+ return encodedJSValue();
+ }
bool success = result->appendMemcpy(exec, vm, 0, first);
ASSERT(!success || !scope.exception());
@@ -1266,10 +1276,19 @@
unsigned firstArraySize = firstButterfly->publicLength();
unsigned secondArraySize = secondButterfly->publicLength();
+ Checked<unsigned, RecordOverflow> checkedResultSize = firstArraySize;
+ checkedResultSize += secondArraySize;
+
+ if (UNLIKELY(checkedResultSize.hasOverflowed())) {
+ throwOutOfMemoryError(exec, scope);
+ return encodedJSValue();
+ }
+
+ unsigned resultSize = checkedResultSize.unsafeGet();
IndexingType secondType = secondArray->indexingType();
IndexingType type = firstArray->mergeIndexingTypeForCopying(secondType);
- if (type == NonArray || !firstArray->canFastCopy(vm, secondArray) || firstArraySize + secondArraySize >= MIN_SPARSE_ARRAY_INDEX) {
- JSArray* result = constructEmptyArray(exec, nullptr, firstArraySize + secondArraySize);
+ if (type == NonArray || !firstArray->canFastCopy(vm, secondArray) || resultSize >= MIN_SPARSE_ARRAY_INDEX) {
+ JSArray* result = constructEmptyArray(exec, nullptr, resultSize);
RETURN_IF_EXCEPTION(scope, encodedJSValue());
bool success = moveElements(exec, vm, result, 0, firstArray, firstArraySize);
@@ -1285,9 +1304,11 @@
}
Structure* resultStructure = exec->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(type);
- JSArray* result = JSArray::tryCreateForInitializationPrivate(vm, resultStructure, firstArraySize + secondArraySize);
- if (!result)
- return JSValue::encode(throwOutOfMemoryError(exec, scope));
+ JSArray* result = JSArray::tryCreateForInitializationPrivate(vm, resultStructure, resultSize);
+ if (UNLIKELY(!result)) {
+ throwOutOfMemoryError(exec, scope);
+ return encodedJSValue();
+ }
if (type == ArrayWithDouble) {
double* buffer = result->butterfly()->contiguousDouble().data();
@@ -1304,7 +1325,7 @@
}
}
- result->butterfly()->setPublicLength(firstArraySize + secondArraySize);
+ result->butterfly()->setPublicLength(resultSize);
return JSValue::encode(result);
}