Title: [206794] trunk
Revision
206794
Author
[email protected]
Date
2016-10-04 16:25:33 -0700 (Tue, 04 Oct 2016)

Log Message

WebAssembly: handle a few corner cases
https://bugs.webkit.org/show_bug.cgi?id=162884

Reviewed by Keith Miller.

JSTests:

* stress/wasm/generate-wasmops-header.js:
(const.opcodeIterator): max opcode value

Source/_javascript_Core:

* wasm/JSWASMModule.cpp: missing include broke cmake build
* wasm/WASMFunctionParser.h:
(JSC::WASM::FunctionParser<Context>::parseBlock): check op is valid
(JSC::WASM::FunctionParser<Context>::parseExpression): switch covers all cases
* wasm/WASMOps.h:
(JSC::WASM::isValidOpType): op is valid
* wasm/WASMParser.h:
(JSC::WASM::Parser::consumeString): avoid str[i] being one-past-the-end
(JSC::WASM::Parser::parseUInt32): shift math around to avoid overflow

Modified Paths

Diff

Modified: trunk/JSTests/ChangeLog (206793 => 206794)


--- trunk/JSTests/ChangeLog	2016-10-04 23:20:39 UTC (rev 206793)
+++ trunk/JSTests/ChangeLog	2016-10-04 23:25:33 UTC (rev 206794)
@@ -1,3 +1,13 @@
+2016-10-04  JF Bastien  <[email protected]>
+
+        WebAssembly: handle a few corner cases
+        https://bugs.webkit.org/show_bug.cgi?id=162884
+
+        Reviewed by Keith Miller.
+
+        * stress/wasm/generate-wasmops-header.js:
+        (const.opcodeIterator): max opcode value
+
 2016-10-03  JF Bastien  <[email protected]>
 
         Auto-generate WASMOps.h, share with testing JSON file

Modified: trunk/JSTests/stress/wasm/generate-wasmops-header.js (206793 => 206794)


--- trunk/JSTests/stress/wasm/generate-wasmops-header.js	2016-10-04 23:20:39 UTC (rev 206793)
+++ trunk/JSTests/stress/wasm/generate-wasmops-header.js	2016-10-04 23:25:33 UTC (rev 206794)
@@ -4,12 +4,12 @@
 const wasm = JSON.parse(read(jsonFile));
 const opcodes = wasm.opcode;
 
-// Iterate through opcodes which match filter.
-const opcodeIterator = (filter) => {
+// Iterate through opcodes which match filter, and on each iteration yield ret.
+const opcodeIterator = (filter, ret = op => { return {name: op, opcode: opcodes[op]}; }) => {
     return function*() {
         for (let op in opcodes)
             if (filter(opcodes[op]))
-                yield {name: op, opcode: opcodes[op]};
+                yield ret(op);
     };
 };
 
@@ -38,6 +38,21 @@
     ...opcodeMacroizer(op => (op.category === "arithmetic" || op.category === "comparison") && op.parameter.length === 2),
     "\n\n"].join("");
 
+const opValueSet = new Set(opcodeIterator(op => true, op => opcodes[op].value)());
+const maxOpValue = Math.max(...opValueSet);
+const validOps = (() => {
+    // Create a bitset of valid ops.
+    let v = "";
+    for (let i = 0; i < maxOpValue / 8; ++i) {
+        let entry = 0;
+        for (let j = 0; j < 8; ++j)
+            if (opValueSet.has(i * 8 + j))
+                entry |= 1 << j;
+        v += (i ? ", " : "") + "0x" + entry.toString(16);
+    }
+    return v;
+})();
+
 const template = `/*
  * Copyright (C) 2016 Apple Inc. All rights reserved.
  *
@@ -69,6 +84,8 @@
 
 #if ENABLE(WEBASSEMBLY)
 
+#include <cstdint>
+
 namespace JSC { namespace WASM {
 
 ${defines}
@@ -85,6 +102,14 @@
     FOR_EACH_WASM_OP(CREATE_ENUM_VALUE)
 };
 
+template<typename Int>
+inline bool isValidOpType(Int i)
+{
+    // Bitset of valid ops.
+    static const uint8_t valid[] = { ${validOps} };
+    return 0 <= i && i <= ${maxOpValue} && (valid[i / 8] & (1 << (i % 8)));
+}
+
 enum class BinaryOpType : uint8_t {
     FOR_EACH_WASM_BINARY_OP(CREATE_ENUM_VALUE)
 };

Modified: trunk/Source/_javascript_Core/ChangeLog (206793 => 206794)


--- trunk/Source/_javascript_Core/ChangeLog	2016-10-04 23:20:39 UTC (rev 206793)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-10-04 23:25:33 UTC (rev 206794)
@@ -1,3 +1,20 @@
+2016-10-04  JF Bastien  <[email protected]>
+
+        WebAssembly: handle a few corner cases
+        https://bugs.webkit.org/show_bug.cgi?id=162884
+
+        Reviewed by Keith Miller.
+
+        * wasm/JSWASMModule.cpp: missing include broke cmake build
+        * wasm/WASMFunctionParser.h:
+        (JSC::WASM::FunctionParser<Context>::parseBlock): check op is valid
+        (JSC::WASM::FunctionParser<Context>::parseExpression): switch covers all cases
+        * wasm/WASMOps.h:
+        (JSC::WASM::isValidOpType): op is valid
+        * wasm/WASMParser.h:
+        (JSC::WASM::Parser::consumeString): avoid str[i] being one-past-the-end
+        (JSC::WASM::Parser::parseUInt32): shift math around to avoid overflow
+
 2016-10-04  Yusuke Suzuki  <[email protected]>
 
         REGRESSION (r206778): Release JSC test ChakraCore.yaml/ChakraCore/test/Error/validate_line_column.js.default failing

Modified: trunk/Source/_javascript_Core/wasm/JSWASMModule.cpp (206793 => 206794)


--- trunk/Source/_javascript_Core/wasm/JSWASMModule.cpp	2016-10-04 23:20:39 UTC (rev 206793)
+++ trunk/Source/_javascript_Core/wasm/JSWASMModule.cpp	2016-10-04 23:25:33 UTC (rev 206794)
@@ -35,6 +35,7 @@
 #include "JSCellInlines.h"
 #include "JSFunction.h"
 #include "SlotVisitorInlines.h"
+#include "StructureInlines.h"
 
 namespace JSC {
 

Modified: trunk/Source/_javascript_Core/wasm/WASMFunctionParser.h (206793 => 206794)


--- trunk/Source/_javascript_Core/wasm/WASMFunctionParser.h	2016-10-04 23:20:39 UTC (rev 206793)
+++ trunk/Source/_javascript_Core/wasm/WASMFunctionParser.h	2016-10-04 23:25:33 UTC (rev 206794)
@@ -101,7 +101,7 @@
 {
     while (true) {
         uint8_t op;
-        if (!parseUInt7(op))
+        if (!parseUInt7(op) || !isValidOpType(op))
             return false;
 
         if (verbose) {
@@ -260,8 +260,7 @@
         return false;
     }
 
-    // Unknown opcode.
-    return false;
+    ASSERT_NOT_REACHED();
 }
 
 template<typename Context>

Modified: trunk/Source/_javascript_Core/wasm/WASMOps.h (206793 => 206794)


--- trunk/Source/_javascript_Core/wasm/WASMOps.h	2016-10-04 23:20:39 UTC (rev 206793)
+++ trunk/Source/_javascript_Core/wasm/WASMOps.h	2016-10-04 23:25:33 UTC (rev 206794)
@@ -29,6 +29,8 @@
 
 #if ENABLE(WEBASSEMBLY)
 
+#include <cstdint>
+
 namespace JSC { namespace WASM {
 
 #define FOR_EACH_WASM_SPECIAL_OP(macro) \
@@ -171,6 +173,14 @@
     FOR_EACH_WASM_OP(CREATE_ENUM_VALUE)
 };
 
+template<typename Int>
+inline bool isValidOpType(Int i)
+{
+    // Bitset of valid ops.
+    static const uint8_t valid[] = { 0xff, 0x8f, 0xff, 0x2, 0xff, 0xff, 0x7f, 0xa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f };
+    return 0 <= i && i <= 188 && (valid[i / 8] & (1 << (i % 8)));
+}
+
 enum class BinaryOpType : uint8_t {
     FOR_EACH_WASM_BINARY_OP(CREATE_ENUM_VALUE)
 };

Modified: trunk/Source/_javascript_Core/wasm/WASMParser.h (206793 => 206794)


--- trunk/Source/_javascript_Core/wasm/WASMParser.h	2016-10-04 23:20:39 UTC (rev 206793)
+++ trunk/Source/_javascript_Core/wasm/WASMParser.h	2016-10-04 23:25:33 UTC (rev 206794)
@@ -79,6 +79,8 @@
 ALWAYS_INLINE bool Parser::consumeString(const char* str)
 {
     unsigned start = m_offset;
+    if (m_offset >= m_sourceLength)
+        return false;
     for (unsigned i = 0; str[i]; i++) {
         if (!consumeCharacter(str[i])) {
             m_offset = start;
@@ -90,7 +92,7 @@
 
 ALWAYS_INLINE bool Parser::parseUInt32(uint32_t& result)
 {
-    if (m_offset + 4 >= m_sourceLength)
+    if (m_sourceLength < 4 || m_offset >= m_sourceLength - 4)
         return false;
     result = *reinterpret_cast<const uint32_t*>(m_source.data() + m_offset);
     m_offset += 4;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to