| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "test/unittests/test-utils.h" | 5 #include "test/unittests/test-utils.h" |
| 6 | 6 |
| 7 #include "src/wasm/module-decoder.h" | 7 #include "src/wasm/module-decoder.h" |
| 8 #include "src/wasm/wasm-opcodes.h" | 8 #include "src/wasm/wasm-opcodes.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 } | 63 } |
| 64 { | 64 { |
| 65 ModuleResult result = DecodeModule(data, data + 1); | 65 ModuleResult result = DecodeModule(data, data + 1); |
| 66 EXPECT_TRUE(result.ok()); | 66 EXPECT_TRUE(result.ok()); |
| 67 if (result.val) delete result.val; | 67 if (result.val) delete result.val; |
| 68 } | 68 } |
| 69 } | 69 } |
| 70 | 70 |
| 71 | 71 |
| 72 TEST_F(WasmModuleVerifyTest, OneGlobal) { | 72 TEST_F(WasmModuleVerifyTest, OneGlobal) { |
| 73 const byte data[] = { | 73 static const byte data[] = { |
| 74 kDeclGlobals, | 74 kDeclGlobals, |
| 75 1, | 75 1, |
| 76 0, | 76 0, |
| 77 0, | 77 0, |
| 78 0, | 78 0, |
| 79 0, // name offset | 79 0, // name offset |
| 80 kMemI32, // memory type | 80 kMemI32, // memory type |
| 81 0, // exported | 81 0, // exported |
| 82 }; | 82 }; |
| 83 | 83 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 102 for (size_t size = 1; size < arraysize(data); size++) { | 102 for (size_t size = 1; size < arraysize(data); size++) { |
| 103 // Should fall off end of module bytes. | 103 // Should fall off end of module bytes. |
| 104 ModuleResult result = DecodeModule(data, data + size); | 104 ModuleResult result = DecodeModule(data, data + size); |
| 105 EXPECT_FALSE(result.ok()); | 105 EXPECT_FALSE(result.ok()); |
| 106 if (result.val) delete result.val; | 106 if (result.val) delete result.val; |
| 107 } | 107 } |
| 108 } | 108 } |
| 109 | 109 |
| 110 | 110 |
| 111 TEST_F(WasmModuleVerifyTest, ZeroGlobals) { | 111 TEST_F(WasmModuleVerifyTest, ZeroGlobals) { |
| 112 const byte data[] = { | 112 static const byte data[] = { |
| 113 kDeclGlobals, 0, // declare 0 globals | 113 kDeclGlobals, 0, // declare 0 globals |
| 114 }; | 114 }; |
| 115 ModuleResult result = DecodeModule(data, data + arraysize(data)); | 115 ModuleResult result = DecodeModule(data, data + arraysize(data)); |
| 116 EXPECT_TRUE(result.ok()); | 116 EXPECT_TRUE(result.ok()); |
| 117 if (result.val) delete result.val; | 117 if (result.val) delete result.val; |
| 118 } | 118 } |
| 119 | 119 |
| 120 | 120 |
| 121 static void AppendUint32v(std::vector<byte>& buffer, uint32_t val) { | 121 static void AppendUint32v(std::vector<byte>& buffer, uint32_t val) { |
| 122 while (true) { | 122 while (true) { |
| 123 uint32_t next = val >> 7; | 123 uint32_t next = val >> 7; |
| 124 uint32_t out = val & 0x7f; | 124 uint32_t out = val & 0x7f; |
| 125 if (next) { | 125 if (next) { |
| 126 buffer.push_back(static_cast<byte>(0x80 | out)); | 126 buffer.push_back(static_cast<byte>(0x80 | out)); |
| 127 val = next; | 127 val = next; |
| 128 } else { | 128 } else { |
| 129 buffer.push_back(static_cast<byte>(out)); | 129 buffer.push_back(static_cast<byte>(out)); |
| 130 break; | 130 break; |
| 131 } | 131 } |
| 132 } | 132 } |
| 133 } | 133 } |
| 134 | 134 |
| 135 | 135 |
| 136 TEST_F(WasmModuleVerifyTest, NGlobals) { | 136 TEST_F(WasmModuleVerifyTest, NGlobals) { |
| 137 const byte data[] = { | 137 static const byte data[] = { |
| 138 0, 0, 0, 0, // name offset | 138 0, 0, 0, 0, // name offset |
| 139 kMemI32, // memory type | 139 kMemI32, // memory type |
| 140 0, // exported | 140 0, // exported |
| 141 }; | 141 }; |
| 142 for (uint32_t i = 0; i < 1000000; i = i * 7 + 1) { | 142 for (uint32_t i = 0; i < 1000000; i = i * 7 + 1) { |
| 143 std::vector<byte> buffer; | 143 std::vector<byte> buffer; |
| 144 buffer.push_back(kDeclGlobals); | 144 buffer.push_back(kDeclGlobals); |
| 145 AppendUint32v(buffer, i); | 145 AppendUint32v(buffer, i); |
| 146 for (uint32_t j = 0; j < i; j++) { | 146 for (uint32_t j = 0; j < i; j++) { |
| 147 buffer.insert(buffer.end(), data, data + arraysize(data)); | 147 buffer.insert(buffer.end(), data, data + arraysize(data)); |
| 148 } | 148 } |
| 149 | 149 |
| 150 ModuleResult result = DecodeModule(&buffer[0], &buffer[0] + buffer.size()); | 150 ModuleResult result = DecodeModule(&buffer[0], &buffer[0] + buffer.size()); |
| 151 EXPECT_TRUE(result.ok()); | 151 EXPECT_TRUE(result.ok()); |
| 152 if (result.val) delete result.val; | 152 if (result.val) delete result.val; |
| 153 } | 153 } |
| 154 } | 154 } |
| 155 | 155 |
| 156 | 156 |
| 157 TEST_F(WasmModuleVerifyTest, GlobalWithInvalidNameOffset) { | 157 TEST_F(WasmModuleVerifyTest, GlobalWithInvalidNameOffset) { |
| 158 const byte data[] = { | 158 static const byte data[] = { |
| 159 kDeclGlobals, | 159 kDeclGlobals, |
| 160 1, // declare one global | 160 1, // declare one global |
| 161 0, | 161 0, |
| 162 3, | 162 3, |
| 163 0, | 163 0, |
| 164 0, // name offset | 164 0, // name offset |
| 165 kMemI32, // memory type | 165 kMemI32, // memory type |
| 166 0, // exported | 166 0, // exported |
| 167 }; | 167 }; |
| 168 | 168 |
| 169 EXPECT_FAILURE(data); | 169 EXPECT_FAILURE(data); |
| 170 } | 170 } |
| 171 | 171 |
| 172 | 172 |
| 173 TEST_F(WasmModuleVerifyTest, GlobalWithInvalidMemoryType) { | 173 TEST_F(WasmModuleVerifyTest, GlobalWithInvalidMemoryType) { |
| 174 const byte data[] = { | 174 static const byte data[] = { |
| 175 kDeclGlobals, | 175 kDeclGlobals, |
| 176 1, // declare one global | 176 1, // declare one global |
| 177 0, | 177 0, |
| 178 0, | 178 0, |
| 179 0, | 179 0, |
| 180 0, // name offset | 180 0, // name offset |
| 181 33, // memory type | 181 33, // memory type |
| 182 0, // exported | 182 0, // exported |
| 183 }; | 183 }; |
| 184 | 184 |
| 185 EXPECT_FAILURE(data); | 185 EXPECT_FAILURE(data); |
| 186 } | 186 } |
| 187 | 187 |
| 188 | 188 |
| 189 TEST_F(WasmModuleVerifyTest, TwoGlobals) { | 189 TEST_F(WasmModuleVerifyTest, TwoGlobals) { |
| 190 const byte data[] = { | 190 static const byte data[] = { |
| 191 kDeclGlobals, | 191 kDeclGlobals, |
| 192 2, | 192 2, |
| 193 0, | 193 0, |
| 194 0, | 194 0, |
| 195 0, | 195 0, |
| 196 0, // #0: name offset | 196 0, // #0: name offset |
| 197 kMemF32, // memory type | 197 kMemF32, // memory type |
| 198 0, // exported | 198 0, // exported |
| 199 0, | 199 0, |
| 200 0, | 200 0, |
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 897 DecodeWasmSignatureForTesting(zone(), data, data + arraysize(data)); | 897 DecodeWasmSignatureForTesting(zone(), data, data + arraysize(data)); |
| 898 EXPECT_EQ(nullptr, sig); | 898 EXPECT_EQ(nullptr, sig); |
| 899 } | 899 } |
| 900 } | 900 } |
| 901 | 901 |
| 902 | 902 |
| 903 class WasmFunctionVerifyTest : public TestWithZone {}; | 903 class WasmFunctionVerifyTest : public TestWithZone {}; |
| 904 | 904 |
| 905 | 905 |
| 906 TEST_F(WasmFunctionVerifyTest, Ok_v_v_empty) { | 906 TEST_F(WasmFunctionVerifyTest, Ok_v_v_empty) { |
| 907 byte data[] = { | 907 static const byte data[] = { |
| 908 0, kLocalVoid, // signature | 908 0, kLocalVoid, // signature |
| 909 3, 0, // local int32 count | 909 3, 0, // local int32 count |
| 910 4, 0, // local int64 count | 910 4, 0, // local int64 count |
| 911 5, 0, // local float32 count | 911 5, 0, // local float32 count |
| 912 6, 0, // local float64 count | 912 6, 0, // local float64 count |
| 913 kExprNop // body | 913 kExprNop // body |
| 914 }; | 914 }; |
| 915 | 915 |
| 916 FunctionResult result = DecodeWasmFunction(nullptr, zone(), nullptr, data, | 916 FunctionResult result = DecodeWasmFunction(nullptr, zone(), nullptr, data, |
| 917 data + arraysize(data)); | 917 data + arraysize(data)); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 938 | 938 |
| 939 TEST_F(WasmModuleVerifyTest, WLLSectionNoLen) { | 939 TEST_F(WasmModuleVerifyTest, WLLSectionNoLen) { |
| 940 const byte data[] = { | 940 const byte data[] = { |
| 941 kDeclWLL, // section without length. | 941 kDeclWLL, // section without length. |
| 942 }; | 942 }; |
| 943 EXPECT_FAILURE(data); | 943 EXPECT_FAILURE(data); |
| 944 } | 944 } |
| 945 | 945 |
| 946 | 946 |
| 947 TEST_F(WasmModuleVerifyTest, WLLSectionEmpty) { | 947 TEST_F(WasmModuleVerifyTest, WLLSectionEmpty) { |
| 948 const byte data[] = { | 948 static const byte data[] = { |
| 949 kDeclWLL, 0, // empty section | 949 kDeclWLL, 0, // empty section |
| 950 }; | 950 }; |
| 951 ModuleResult result = DecodeModule(data, data + arraysize(data)); | 951 ModuleResult result = DecodeModule(data, data + arraysize(data)); |
| 952 EXPECT_TRUE(result.ok()); | 952 EXPECT_TRUE(result.ok()); |
| 953 if (result.val) delete result.val; | 953 if (result.val) delete result.val; |
| 954 } | 954 } |
| 955 | 955 |
| 956 | 956 |
| 957 TEST_F(WasmModuleVerifyTest, WLLSectionOne) { | 957 TEST_F(WasmModuleVerifyTest, WLLSectionOne) { |
| 958 const byte data[] = { | 958 static const byte data[] = { |
| 959 kDeclWLL, | 959 kDeclWLL, |
| 960 1, // LEB128 1 | 960 1, // LEB128 1 |
| 961 0, // one byte section | 961 0, // one byte section |
| 962 }; | 962 }; |
| 963 ModuleResult result = DecodeModule(data, data + arraysize(data)); | 963 ModuleResult result = DecodeModule(data, data + arraysize(data)); |
| 964 EXPECT_TRUE(result.ok()); | 964 EXPECT_TRUE(result.ok()); |
| 965 if (result.val) delete result.val; | 965 if (result.val) delete result.val; |
| 966 } | 966 } |
| 967 | 967 |
| 968 | 968 |
| 969 TEST_F(WasmModuleVerifyTest, WLLSectionTen) { | 969 TEST_F(WasmModuleVerifyTest, WLLSectionTen) { |
| 970 const byte data[] = { | 970 static const byte data[] = { |
| 971 kDeclWLL, | 971 kDeclWLL, |
| 972 10, // LEB128 10 | 972 10, // LEB128 10 |
| 973 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // 10 byte section | 973 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // 10 byte section |
| 974 }; | 974 }; |
| 975 ModuleResult result = DecodeModule(data, data + arraysize(data)); | 975 ModuleResult result = DecodeModule(data, data + arraysize(data)); |
| 976 EXPECT_TRUE(result.ok()); | 976 EXPECT_TRUE(result.ok()); |
| 977 if (result.val) delete result.val; | 977 if (result.val) delete result.val; |
| 978 } | 978 } |
| 979 | 979 |
| 980 | 980 |
| 981 TEST_F(WasmModuleVerifyTest, WLLSectionOverflow) { | 981 TEST_F(WasmModuleVerifyTest, WLLSectionOverflow) { |
| 982 const byte data[] = { | 982 static const byte data[] = { |
| 983 kDeclWLL, | 983 kDeclWLL, |
| 984 11, // LEB128 11 | 984 11, // LEB128 11 |
| 985 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // 10 byte section | 985 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // 10 byte section |
| 986 }; | 986 }; |
| 987 EXPECT_FAILURE(data); | 987 EXPECT_FAILURE(data); |
| 988 } | 988 } |
| 989 | 989 |
| 990 | 990 |
| 991 TEST_F(WasmModuleVerifyTest, WLLSectionUnderflow) { | 991 TEST_F(WasmModuleVerifyTest, WLLSectionUnderflow) { |
| 992 const byte data[] = { | 992 static const byte data[] = { |
| 993 kDeclWLL, | 993 kDeclWLL, 0xff, 0xff, 0xff, 0xff, 0x0f, // LEB128 0xffffffff |
| 994 0xff, 0xff, 0xff, 0xff, 0x0f, // LEB128 0xffffffff | 994 1, 2, 3, 4, // 4 byte section |
| 995 1, 2, 3, 4, // 4 byte section | |
| 996 }; | 995 }; |
| 997 EXPECT_FAILURE(data); | 996 EXPECT_FAILURE(data); |
| 998 } | 997 } |
| 999 | 998 |
| 1000 | 999 |
| 1001 TEST_F(WasmModuleVerifyTest, WLLSectionLoop) { | 1000 TEST_F(WasmModuleVerifyTest, WLLSectionLoop) { |
| 1002 // Would infinite loop decoding if wrapping and allowed. | 1001 // Would infinite loop decoding if wrapping and allowed. |
| 1003 const byte data[] = { | 1002 static const byte data[] = { |
| 1004 kDeclWLL, | 1003 kDeclWLL, 0xfa, 0xff, 0xff, 0xff, 0x0f, // LEB128 0xfffffffa |
| 1005 0xfa, 0xff, 0xff, 0xff, 0x0f, // LEB128 0xfffffffa | 1004 1, 2, 3, 4, // 4 byte section |
| 1006 1, 2, 3, 4, // 4 byte section | |
| 1007 }; | 1005 }; |
| 1008 EXPECT_FAILURE(data); | 1006 EXPECT_FAILURE(data); |
| 1009 } | 1007 } |
| 1010 | 1008 |
| 1009 TEST_F(WasmModuleVerifyTest, ImportTable_empty) { |
| 1010 static const byte data[] = {kDeclSignatures, 0, kDeclImportTable, 0}; |
| 1011 EXPECT_VERIFIES(data); |
| 1012 } |
| 1013 |
| 1014 TEST_F(WasmModuleVerifyTest, ImportTable_nosigs) { |
| 1015 static const byte data[] = {kDeclImportTable, 0}; |
| 1016 EXPECT_FAILURE(data); |
| 1017 } |
| 1018 |
| 1019 TEST_F(WasmModuleVerifyTest, ImportTable_invalid_sig) { |
| 1020 static const byte data[] = { |
| 1021 kDeclSignatures, |
| 1022 0, |
| 1023 kDeclImportTable, |
| 1024 1, |
| 1025 0, |
| 1026 0, // sig index |
| 1027 1, |
| 1028 0, |
| 1029 0, |
| 1030 0, // module name |
| 1031 1, |
| 1032 0, |
| 1033 0, |
| 1034 0 // function name |
| 1035 }; |
| 1036 EXPECT_FAILURE(data); |
| 1037 } |
| 1038 |
| 1039 TEST_F(WasmModuleVerifyTest, ImportTable_one_sig) { |
| 1040 static const byte data[] = { |
| 1041 kDeclSignatures, |
| 1042 1, |
| 1043 0, |
| 1044 static_cast<byte>(kAstStmt), |
| 1045 kDeclImportTable, |
| 1046 1, |
| 1047 0, |
| 1048 0, // sig index |
| 1049 1, |
| 1050 0, |
| 1051 0, |
| 1052 0, // module name |
| 1053 1, |
| 1054 0, |
| 1055 0, |
| 1056 0 // function name |
| 1057 }; |
| 1058 EXPECT_VERIFIES(data); |
| 1059 } |
| 1060 |
| 1061 TEST_F(WasmModuleVerifyTest, ImportTable_off_end) { |
| 1062 static const byte data[] = { |
| 1063 kDeclSignatures, |
| 1064 1, |
| 1065 0, |
| 1066 static_cast<byte>(kAstStmt), |
| 1067 kDeclImportTable, |
| 1068 1, |
| 1069 0, |
| 1070 0, // sig index |
| 1071 1, |
| 1072 0, |
| 1073 0, |
| 1074 0, // module name |
| 1075 1, |
| 1076 0, |
| 1077 0, |
| 1078 0 // function name |
| 1079 }; |
| 1080 |
| 1081 for (size_t length = 5; length < sizeof(data); length++) { |
| 1082 ModuleResult result = DecodeModule(data, data + length); |
| 1083 EXPECT_FALSE(result.ok()); |
| 1084 if (result.val) delete result.val; |
| 1085 } |
| 1086 } |
| 1087 |
| 1011 } // namespace wasm | 1088 } // namespace wasm |
| 1012 } // namespace internal | 1089 } // namespace internal |
| 1013 } // namespace v8 | 1090 } // namespace v8 |
| OLD | NEW |