Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (216920 => 216921)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2017-05-16 09:10:55 UTC (rev 216920)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2017-05-16 09:24:13 UTC (rev 216921)
@@ -2080,6 +2080,7 @@
A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FB604B103F5EAB0017A286 /* PropertyDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; };
A7FCC26D17A0B6AA00786D1A /* FTLSwitchCase.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FCC26C17A0B6AA00786D1A /* FTLSwitchCase.h */; settings = {ATTRIBUTES = (Private, ); }; };
A8A4748E151A8306004123FF /* libWTF.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A8A4748D151A8306004123FF /* libWTF.a */; };
+ AD00659E1ECAC812000CA926 /* WasmLimits.h in Headers */ = {isa = PBXBuildFile; fileRef = AD00659D1ECAC7FE000CA926 /* WasmLimits.h */; settings = {ATTRIBUTES = (Private, ); }; };
AD2FCBE21DB58DAD00B3E736 /* JSWebAssemblyCompileError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD2FCBA61DB58DA400B3E736 /* JSWebAssemblyCompileError.cpp */; };
AD2FCBE31DB58DAD00B3E736 /* JSWebAssemblyCompileError.h in Headers */ = {isa = PBXBuildFile; fileRef = AD2FCBA71DB58DA400B3E736 /* JSWebAssemblyCompileError.h */; };
AD2FCBE41DB58DAD00B3E736 /* JSWebAssemblyInstance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD2FCBA81DB58DA400B3E736 /* JSWebAssemblyInstance.cpp */; };
@@ -4711,6 +4712,7 @@
A8A4748D151A8306004123FF /* libWTF.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libWTF.a; sourceTree = BUILT_PRODUCTS_DIR; };
A8E894310CD0602400367179 /* JSCallbackObjectFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCallbackObjectFunctions.h; sourceTree = "<group>"; };
A8E894330CD0603F00367179 /* JSGlobalObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObject.h; sourceTree = "<group>"; };
+ AD00659D1ECAC7FE000CA926 /* WasmLimits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmLimits.h; sourceTree = "<group>"; };
AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PropertyTable.cpp; sourceTree = "<group>"; };
AD2FCB8C1DB5844000B3E736 /* JSWebAssemblyModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSWebAssemblyModule.cpp; path = js/JSWebAssemblyModule.cpp; sourceTree = "<group>"; };
AD2FCB8D1DB5844000B3E736 /* JSWebAssemblyModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSWebAssemblyModule.h; path = js/JSWebAssemblyModule.h; sourceTree = "<group>"; };
@@ -6430,6 +6432,7 @@
53F40E8A1D5901BB0099A1B6 /* WasmFunctionParser.h */,
AD8FF3961EB5BD850087FF82 /* WasmIndexOrName.cpp */,
AD8FF3951EB5BD850087FF82 /* WasmIndexOrName.h */,
+ AD00659D1ECAC7FE000CA926 /* WasmLimits.h */,
53E9E0A91EAE83DE00FEE251 /* WasmMachineThreads.cpp */,
53E9E0AA1EAE83DE00FEE251 /* WasmMachineThreads.h */,
535557151D9DFA32006D583B /* WasmMemory.cpp */,
@@ -9469,6 +9472,7 @@
0F1FB38F1E173A6700A9BE50 /* SynchronousStopTheWorldMutatorScheduler.h in Headers */,
A784A26411D16622005776AC /* SyntaxChecker.h in Headers */,
DC7997831CDE9FA0004D4A09 /* TagRegistersMode.h in Headers */,
+ AD00659E1ECAC812000CA926 /* WasmLimits.h in Headers */,
70ECA6081AFDBEA200449739 /* TemplateRegistry.h in Headers */,
70ECA6091AFDBEA200449739 /* TemplateRegistryKey.h in Headers */,
95D4261AF4C84CE2ACBAC981 /* TemplateRegistryKeyTable.h in Headers */,
Added: trunk/Source/_javascript_Core/wasm/WasmLimits.h (0 => 216921)
--- trunk/Source/_javascript_Core/wasm/WasmLimits.h (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WasmLimits.h 2017-05-16 09:24:13 UTC (rev 216921)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 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
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEBASSEMBLY)
+
+#include <cstdint>
+
+namespace JSC {
+
+namespace Wasm {
+
+// These limits are arbitrary except that they match the limits imposed
+// by other browsers' implementation of WebAssembly. It is desirable for
+// us to accept at least the same inputs.
+
+constexpr size_t maxTypes = 1000000;
+constexpr size_t maxFunctions = 1000000;
+constexpr size_t maxImports = 100000;
+constexpr size_t maxExports = 100000;
+constexpr size_t maxGlobals = 1000000;
+constexpr size_t maxDataSegments = 100000;
+
+constexpr size_t maxStringSize = 100000;
+constexpr size_t maxModuleSize = 1024 * 1024 * 1024;
+constexpr size_t maxFunctionParams = 1000;
+
+constexpr size_t maxTableEntries = 10000000;
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
Modified: trunk/Source/_javascript_Core/wasm/WasmModuleParser.cpp (216920 => 216921)
--- trunk/Source/_javascript_Core/wasm/WasmModuleParser.cpp 2017-05-16 09:10:55 UTC (rev 216920)
+++ trunk/Source/_javascript_Core/wasm/WasmModuleParser.cpp 2017-05-16 09:24:13 UTC (rev 216921)
@@ -51,6 +51,7 @@
uint32_t versionNumber;
WASM_PARSER_FAIL_IF(length() < minSize, "expected a module of at least ", minSize, " bytes");
+ WASM_PARSER_FAIL_IF(length() > maxModuleSize, "module size ", length(), " is too large, maximum ", maxModuleSize);
WASM_PARSER_FAIL_IF(!consumeCharacter(0) || !consumeString("asm"), "modules doesn't start with '\\0asm'");
WASM_PARSER_FAIL_IF(!parseUInt32(versionNumber), "can't parse version number");
WASM_PARSER_FAIL_IF(versionNumber != expectedVersionNumber, "unexpected version number ", versionNumber, " expected ", expectedVersionNumber);
@@ -102,7 +103,7 @@
uint32_t count;
WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Type section's count");
- WASM_PARSER_FAIL_IF(count == std::numeric_limits<uint32_t>::max(), "Type section's count is too big ", count);
+ WASM_PARSER_FAIL_IF(count > maxTypes, "Type section's count is too big ", count, " maximum ", maxTypes);
WASM_PARSER_FAIL_IF(!m_info->usedSignatures.tryReserveCapacity(count), "can't allocate enough memory for Type section's ", count, " entries");
for (uint32_t i = 0; i < count; ++i) {
@@ -113,7 +114,7 @@
WASM_PARSER_FAIL_IF(!parseInt7(type), "can't get ", i, "th Type's type");
WASM_PARSER_FAIL_IF(type != Func, i, "th Type is non-Func ", type);
WASM_PARSER_FAIL_IF(!parseVarUInt32(argumentCount), "can't get ", i, "th Type's argument count");
- WASM_PARSER_FAIL_IF(argumentCount == std::numeric_limits<uint32_t>::max(), i, "th argument count is too big ", argumentCount);
+ WASM_PARSER_FAIL_IF(argumentCount > maxFunctionParams, i, "th argument count is too big ", argumentCount, " maximum ", maxFunctionParams);
RefPtr<Signature> maybeSignature = Signature::tryCreate(argumentCount);
WASM_PARSER_FAIL_IF(!maybeSignature, "can't allocate enough memory for Type section's ", i, "th signature");
Ref<Signature> signature = maybeSignature.releaseNonNull();
@@ -145,7 +146,7 @@
{
uint32_t importCount;
WASM_PARSER_FAIL_IF(!parseVarUInt32(importCount), "can't get Import section's count");
- WASM_PARSER_FAIL_IF(importCount == std::numeric_limits<uint32_t>::max(), "Import section's count is too big ", importCount);
+ WASM_PARSER_FAIL_IF(importCount > maxImports, "Import section's count is too big ", importCount, " maximum ", maxImports);
WASM_PARSER_FAIL_IF(!m_info->globals.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " globals"); // FIXME this over-allocates when we fix the FIXMEs below.
WASM_PARSER_FAIL_IF(!m_info->imports.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " imports"); // FIXME this over-allocates when we fix the FIXMEs below.
WASM_PARSER_FAIL_IF(!m_info->importFunctionSignatureIndices.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " import function signatures"); // FIXME this over-allocates when we fix the FIXMEs below.
@@ -211,7 +212,7 @@
{
uint32_t count;
WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Function section's count");
- WASM_PARSER_FAIL_IF(count == std::numeric_limits<uint32_t>::max(), "Function section's count is too big ", count);
+ WASM_PARSER_FAIL_IF(count > maxFunctions, "Function section's count is too big ", count, " maximum ", maxFunctions);
WASM_PARSER_FAIL_IF(!m_info->internalFunctionSignatureIndices.tryReserveCapacity(count), "can't allocate enough memory for ", count, " Function signatures");
WASM_PARSER_FAIL_IF(!m_info->functionLocationInBinary.tryReserveCapacity(count), "can't allocate enough memory for ", count, "Function locations");
@@ -334,6 +335,7 @@
{
uint32_t globalCount;
WASM_PARSER_FAIL_IF(!parseVarUInt32(globalCount), "can't get Global section's count");
+ WASM_PARSER_FAIL_IF(globalCount > maxGlobals, "Global section's count is too big ", globalCount, " maximum ", maxGlobals);
WASM_PARSER_FAIL_IF(!m_info->globals.tryReserveCapacity(globalCount + m_info->firstInternalGlobal), "can't allocate memory for ", globalCount + m_info->firstInternalGlobal, " globals");
for (uint32_t globalIndex = 0; globalIndex < globalCount; ++globalIndex) {
@@ -359,7 +361,7 @@
{
uint32_t exportCount;
WASM_PARSER_FAIL_IF(!parseVarUInt32(exportCount), "can't get Export section's count");
- WASM_PARSER_FAIL_IF(exportCount == std::numeric_limits<uint32_t>::max(), "Export section's count is too big ", exportCount);
+ WASM_PARSER_FAIL_IF(exportCount > maxExports, "Export section's count is too big ", exportCount, " maximum ", maxExports);
WASM_PARSER_FAIL_IF(!m_info->exports.tryReserveCapacity(exportCount), "can't allocate enough memory for ", exportCount, " exports");
HashSet<String> exportNames;
@@ -424,7 +426,7 @@
uint32_t elementCount;
WASM_PARSER_FAIL_IF(!parseVarUInt32(elementCount), "can't get Element section's count");
- WASM_PARSER_FAIL_IF(elementCount == std::numeric_limits<uint32_t>::max(), "Element section's count is too big ", elementCount);
+ WASM_PARSER_FAIL_IF(elementCount > maxTableEntries, "Element section's count is too big ", elementCount, " maximum ", maxTableEntries);
WASM_PARSER_FAIL_IF(!m_info->elements.tryReserveCapacity(elementCount), "can't allocate memory for ", elementCount, " Elements");
for (unsigned elementNum = 0; elementNum < elementCount; ++elementNum) {
uint32_t tableIndex;
@@ -471,6 +473,7 @@
WASM_PARSER_FAIL_IF(!parseVarUInt32(functionSize), "can't get ", i, "th Code function's size");
WASM_PARSER_FAIL_IF(functionSize > length(), "Code function's size ", functionSize, " exceeds the module's size ", length());
WASM_PARSER_FAIL_IF(functionSize > length() - m_offset, "Code function's size ", functionSize, " exceeds the module's remaining size", length() - m_offset);
+ WASM_PARSER_FAIL_IF(functionSize > std::numeric_limits<uint32_t>::max(), "Code function's size ", functionSize, " is too big");
m_info->functionLocationInBinary[i].start = m_offset;
m_info->functionLocationInBinary[i].end = m_offset + functionSize;
@@ -555,7 +558,7 @@
uint32_t segmentCount;
WASM_PARSER_FAIL_IF(!m_info->memory, "Data section cannot exist without a Memory section or Import");
WASM_PARSER_FAIL_IF(!parseVarUInt32(segmentCount), "can't get Data section's count");
- WASM_PARSER_FAIL_IF(segmentCount == std::numeric_limits<uint32_t>::max(), "Data section's count is too big ", segmentCount);
+ WASM_PARSER_FAIL_IF(segmentCount > maxDataSegments, "Data section's count is too big ", segmentCount, " maximum ", maxDataSegments);
WASM_PARSER_FAIL_IF(!m_info->data.tryReserveCapacity(segmentCount), "can't allocate enough memory for Data section's ", segmentCount, " segments");
for (uint32_t segmentNumber = 0; segmentNumber < segmentCount; ++segmentNumber) {