| 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-macro-gen.h" |
| 8 #include "src/wasm/wasm-opcodes.h" | 9 #include "src/wasm/wasm-opcodes.h" |
| 9 | 10 |
| 10 namespace v8 { | 11 namespace v8 { |
| 11 namespace internal { | 12 namespace internal { |
| 12 namespace wasm { | 13 namespace wasm { |
| 13 | 14 |
| 15 #define EMPTY_FUNCTION(sig_index) 0, SIG_INDEX(sig_index), U16_LE(0) |
| 14 #define VOID_VOID_SIG 0, kLocalVoid | 16 #define VOID_VOID_SIG 0, kLocalVoid |
| 15 #define INT_INT_SIG 1, kLocalI32, kLocalI32 | 17 #define INT_INT_SIG 1, kLocalI32, kLocalI32 |
| 16 | 18 |
| 17 #define U32(v) \ | |
| 18 static_cast<byte>(v), static_cast<byte>(v >> 8), static_cast<byte>(v >> 16), \ | |
| 19 static_cast<byte>(v >> 24) | |
| 20 #define U16(v) static_cast<byte>(v), static_cast<byte>(v >> 8) | |
| 21 #define U8(v) static_cast<byte>(v) | |
| 22 | |
| 23 #define SIG_INDEX(v) U16(v) | |
| 24 #define FUNC_INDEX(v) U16(v) | |
| 25 #define NAME_OFFSET(v) U32(v) | |
| 26 | |
| 27 #define EMPTY_FUNCTION(sig_index) 0, SIG_INDEX(sig_index), U16(0) | |
| 28 | |
| 29 class WasmModuleVerifyTest : public TestWithZone { | |
| 30 public: | |
| 31 ModuleResult DecodeModule(const byte* module_start, const byte* module_end) { | |
| 32 return DecodeWasmModule(nullptr, zone(), module_start, module_end, false, | |
| 33 kWasmOrigin); | |
| 34 } | |
| 35 }; | |
| 36 | |
| 37 | |
| 38 #define EXPECT_VERIFIES(data) \ | 19 #define EXPECT_VERIFIES(data) \ |
| 39 do { \ | 20 do { \ |
| 40 ModuleResult result = DecodeModule(data, data + arraysize(data)); \ | 21 ModuleResult result = DecodeModule(data, data + arraysize(data)); \ |
| 41 EXPECT_TRUE(result.ok()); \ | 22 EXPECT_TRUE(result.ok()); \ |
| 42 if (result.val) delete result.val; \ | 23 if (result.val) delete result.val; \ |
| 43 } while (false) | 24 } while (false) |
| 44 | 25 |
| 45 | 26 #define EXPECT_FAILURE_LEN(data, length) \ |
| 46 #define EXPECT_FAILURE(data) \ | 27 do { \ |
| 47 do { \ | 28 ModuleResult result = DecodeModule(data, data + length); \ |
| 48 ModuleResult result = DecodeModule(data, data + arraysize(data)); \ | 29 EXPECT_FALSE(result.ok()); \ |
| 49 EXPECT_FALSE(result.ok()); \ | 30 if (result.val) delete result.val; \ |
| 50 if (result.val) delete result.val; \ | |
| 51 } while (false) | 31 } while (false) |
| 52 | 32 |
| 33 #define EXPECT_FAILURE(data) EXPECT_FAILURE_LEN(data, sizeof(data)) |
| 34 |
| 35 #define EXPECT_OFF_END_FAILURE(data, min, max) \ |
| 36 do { \ |
| 37 for (size_t length = min; length < max; length++) { \ |
| 38 EXPECT_FAILURE_LEN(data, length); \ |
| 39 } \ |
| 40 } while (false) |
| 53 | 41 |
| 54 struct LocalTypePair { | 42 struct LocalTypePair { |
| 55 uint8_t code; | 43 uint8_t code; |
| 56 LocalType type; | 44 LocalType type; |
| 57 } kLocalTypes[] = {{kLocalI32, kAstI32}, | 45 } kLocalTypes[] = {{kLocalI32, kAstI32}, |
| 58 {kLocalI64, kAstI64}, | 46 {kLocalI64, kAstI64}, |
| 59 {kLocalF32, kAstF32}, | 47 {kLocalF32, kAstF32}, |
| 60 {kLocalF64, kAstF64}}; | 48 {kLocalF64, kAstF64}}; |
| 61 | 49 |
| 50 class WasmModuleVerifyTest : public TestWithZone { |
| 51 public: |
| 52 ModuleResult DecodeModule(const byte* module_start, const byte* module_end) { |
| 53 // Add the WASM magic and version number automatically. |
| 54 size_t size = static_cast<size_t>(module_end - module_start); |
| 55 byte header[] = {WASM_MODULE_HEADER}; |
| 56 size_t total = sizeof(header) + size; |
| 57 auto temp = new byte[total]; |
| 58 memcpy(temp, header, sizeof(header)); |
| 59 memcpy(temp + sizeof(header), module_start, size); |
| 60 ModuleResult result = DecodeWasmModule(nullptr, zone(), temp, temp + total, |
| 61 false, kWasmOrigin); |
| 62 delete[] temp; |
| 63 return result; |
| 64 } |
| 65 ModuleResult DecodeModuleNoHeader(const byte* module_start, |
| 66 const byte* module_end) { |
| 67 return DecodeWasmModule(nullptr, zone(), module_start, module_end, false, |
| 68 kWasmOrigin); |
| 69 } |
| 70 }; |
| 62 | 71 |
| 63 TEST_F(WasmModuleVerifyTest, DecodeEmpty) { | 72 TEST_F(WasmModuleVerifyTest, WrongMagic) { |
| 64 static const byte data[1]{kDeclEnd}; | 73 for (uint32_t x = 1; x; x <<= 1) { |
| 65 { | 74 const byte data[] = {U32_LE(kWasmMagic ^ x), U32_LE(kWasmVersion), |
| 66 ModuleResult result = DecodeModule(data, data); | 75 kDeclEnd}; |
| 67 EXPECT_TRUE(result.ok()); | 76 ModuleResult result = DecodeModuleNoHeader(data, data + sizeof(data)); |
| 68 if (result.val) delete result.val; | 77 EXPECT_FALSE(result.ok()); |
| 69 } | |
| 70 { | |
| 71 ModuleResult result = DecodeModule(data, data + 1); | |
| 72 EXPECT_TRUE(result.ok()); | |
| 73 if (result.val) delete result.val; | 78 if (result.val) delete result.val; |
| 74 } | 79 } |
| 75 } | 80 } |
| 76 | 81 |
| 82 TEST_F(WasmModuleVerifyTest, WrongVersion) { |
| 83 for (uint32_t x = 1; x; x <<= 1) { |
| 84 const byte data[] = {U32_LE(kWasmMagic), U32_LE(kWasmVersion ^ x), |
| 85 kDeclEnd}; |
| 86 ModuleResult result = DecodeModuleNoHeader(data, data + sizeof(data)); |
| 87 EXPECT_FALSE(result.ok()); |
| 88 if (result.val) delete result.val; |
| 89 } |
| 90 } |
| 91 |
| 92 TEST_F(WasmModuleVerifyTest, DecodeEmpty) { |
| 93 static const byte data[] = {kDeclEnd}; |
| 94 EXPECT_VERIFIES(data); |
| 95 } |
| 77 | 96 |
| 78 TEST_F(WasmModuleVerifyTest, OneGlobal) { | 97 TEST_F(WasmModuleVerifyTest, OneGlobal) { |
| 79 static const byte data[] = { | 98 static const byte data[] = { |
| 80 kDeclGlobals, | 99 kDeclGlobals, |
| 81 1, | 100 1, |
| 82 NAME_OFFSET(0), | 101 NAME_OFFSET(0), |
| 83 kMemI32, // memory type | 102 kMemI32, // memory type |
| 84 0, // exported | 103 0, // exported |
| 85 }; | 104 }; |
| 86 | 105 |
| 87 { | 106 { |
| 88 // Should decode to exactly one global. | 107 // Should decode to exactly one global. |
| 89 ModuleResult result = DecodeModule(data, data + arraysize(data)); | 108 ModuleResult result = DecodeModule(data, data + arraysize(data)); |
| 90 EXPECT_TRUE(result.ok()); | 109 EXPECT_TRUE(result.ok()); |
| 91 EXPECT_EQ(1, result.val->globals->size()); | 110 EXPECT_EQ(1, result.val->globals->size()); |
| 92 EXPECT_EQ(0, result.val->functions->size()); | 111 EXPECT_EQ(0, result.val->functions->size()); |
| 93 EXPECT_EQ(0, result.val->data_segments->size()); | 112 EXPECT_EQ(0, result.val->data_segments->size()); |
| 94 | 113 |
| 95 WasmGlobal* global = &result.val->globals->back(); | 114 WasmGlobal* global = &result.val->globals->back(); |
| 96 | 115 |
| 97 EXPECT_EQ(0, global->name_offset); | 116 EXPECT_EQ(0, global->name_offset); |
| 98 EXPECT_EQ(MachineType::Int32(), global->type); | 117 EXPECT_EQ(MachineType::Int32(), global->type); |
| 99 EXPECT_EQ(0, global->offset); | 118 EXPECT_EQ(0, global->offset); |
| 100 EXPECT_FALSE(global->exported); | 119 EXPECT_FALSE(global->exported); |
| 101 | 120 |
| 102 if (result.val) delete result.val; | 121 if (result.val) delete result.val; |
| 103 } | 122 } |
| 104 | 123 |
| 105 for (size_t size = 1; size < arraysize(data); size++) { | 124 EXPECT_OFF_END_FAILURE(data, 1, sizeof(data)); |
| 106 // Should fall off end of module bytes. | |
| 107 ModuleResult result = DecodeModule(data, data + size); | |
| 108 EXPECT_FALSE(result.ok()); | |
| 109 if (result.val) delete result.val; | |
| 110 } | |
| 111 } | 125 } |
| 112 | 126 |
| 113 | 127 |
| 114 TEST_F(WasmModuleVerifyTest, ZeroGlobals) { | 128 TEST_F(WasmModuleVerifyTest, ZeroGlobals) { |
| 115 static const byte data[] = { | 129 static const byte data[] = { |
| 116 kDeclGlobals, 0, // declare 0 globals | 130 kDeclGlobals, 0, // declare 0 globals |
| 117 }; | 131 }; |
| 118 ModuleResult result = DecodeModule(data, data + arraysize(data)); | 132 ModuleResult result = DecodeModule(data, data + arraysize(data)); |
| 119 EXPECT_TRUE(result.ok()); | 133 EXPECT_TRUE(result.ok()); |
| 120 if (result.val) delete result.val; | 134 if (result.val) delete result.val; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 135 } | 149 } |
| 136 } | 150 } |
| 137 | 151 |
| 138 | 152 |
| 139 TEST_F(WasmModuleVerifyTest, NGlobals) { | 153 TEST_F(WasmModuleVerifyTest, NGlobals) { |
| 140 static const byte data[] = { | 154 static const byte data[] = { |
| 141 NAME_OFFSET(0), // name offset | 155 NAME_OFFSET(0), // name offset |
| 142 kMemI32, // memory type | 156 kMemI32, // memory type |
| 143 0, // exported | 157 0, // exported |
| 144 }; | 158 }; |
| 145 for (uint32_t i = 0; i < 1000000; i = i * 7 + 1) { | 159 |
| 160 for (uint32_t i = 0; i < 1000000; i = i * 13 + 1) { |
| 146 std::vector<byte> buffer; | 161 std::vector<byte> buffer; |
| 147 buffer.push_back(kDeclGlobals); | 162 buffer.push_back(kDeclGlobals); |
| 148 AppendUint32v(buffer, i); | 163 AppendUint32v(buffer, i); |
| 149 for (uint32_t j = 0; j < i; j++) { | 164 for (uint32_t j = 0; j < i; j++) { |
| 150 buffer.insert(buffer.end(), data, data + arraysize(data)); | 165 buffer.insert(buffer.end(), data, data + sizeof(data)); |
| 151 } | 166 } |
| 152 | 167 |
| 153 ModuleResult result = DecodeModule(&buffer[0], &buffer[0] + buffer.size()); | 168 ModuleResult result = DecodeModule(&buffer[0], &buffer[0] + buffer.size()); |
| 154 EXPECT_TRUE(result.ok()); | 169 EXPECT_TRUE(result.ok()); |
| 155 if (result.val) delete result.val; | 170 if (result.val) delete result.val; |
| 156 } | 171 } |
| 157 } | 172 } |
| 158 | 173 |
| 159 | 174 |
| 160 TEST_F(WasmModuleVerifyTest, GlobalWithInvalidNameOffset) { | 175 TEST_F(WasmModuleVerifyTest, GlobalWithInvalidNameOffset) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 EXPECT_FALSE(g0->exported); | 227 EXPECT_FALSE(g0->exported); |
| 213 | 228 |
| 214 EXPECT_EQ(0, g1->name_offset); | 229 EXPECT_EQ(0, g1->name_offset); |
| 215 EXPECT_EQ(MachineType::Float64(), g1->type); | 230 EXPECT_EQ(MachineType::Float64(), g1->type); |
| 216 EXPECT_EQ(0, g1->offset); | 231 EXPECT_EQ(0, g1->offset); |
| 217 EXPECT_TRUE(g1->exported); | 232 EXPECT_TRUE(g1->exported); |
| 218 | 233 |
| 219 if (result.val) delete result.val; | 234 if (result.val) delete result.val; |
| 220 } | 235 } |
| 221 | 236 |
| 222 for (size_t size = 1; size < arraysize(data); size++) { | 237 EXPECT_OFF_END_FAILURE(data, 1, sizeof(data)); |
| 223 // Should fall off end of module bytes. | |
| 224 ModuleResult result = DecodeModule(data, data + size); | |
| 225 EXPECT_FALSE(result.ok()); | |
| 226 if (result.val) delete result.val; | |
| 227 } | |
| 228 } | 238 } |
| 229 | 239 |
| 230 | 240 |
| 231 TEST_F(WasmModuleVerifyTest, OneSignature) { | 241 TEST_F(WasmModuleVerifyTest, OneSignature) { |
| 232 { | 242 { |
| 233 static const byte data[] = {kDeclSignatures, 1, VOID_VOID_SIG}; | 243 static const byte data[] = {kDeclSignatures, 1, VOID_VOID_SIG}; |
| 234 EXPECT_VERIFIES(data); | 244 EXPECT_VERIFIES(data); |
| 235 } | 245 } |
| 236 | 246 |
| 237 { | 247 { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 263 EXPECT_EQ(0, result.val->signatures->at(0)->return_count()); | 273 EXPECT_EQ(0, result.val->signatures->at(0)->return_count()); |
| 264 EXPECT_EQ(1, result.val->signatures->at(1)->return_count()); | 274 EXPECT_EQ(1, result.val->signatures->at(1)->return_count()); |
| 265 EXPECT_EQ(1, result.val->signatures->at(2)->return_count()); | 275 EXPECT_EQ(1, result.val->signatures->at(2)->return_count()); |
| 266 | 276 |
| 267 EXPECT_EQ(0, result.val->signatures->at(0)->parameter_count()); | 277 EXPECT_EQ(0, result.val->signatures->at(0)->parameter_count()); |
| 268 EXPECT_EQ(1, result.val->signatures->at(1)->parameter_count()); | 278 EXPECT_EQ(1, result.val->signatures->at(1)->parameter_count()); |
| 269 EXPECT_EQ(2, result.val->signatures->at(2)->parameter_count()); | 279 EXPECT_EQ(2, result.val->signatures->at(2)->parameter_count()); |
| 270 } | 280 } |
| 271 if (result.val) delete result.val; | 281 if (result.val) delete result.val; |
| 272 | 282 |
| 273 for (size_t size = 1; size < arraysize(data); size++) { | 283 EXPECT_OFF_END_FAILURE(data, 1, sizeof(data)); |
| 274 ModuleResult result = DecodeModule(data, data + size); | |
| 275 // Should fall off the end of module bytes. | |
| 276 EXPECT_FALSE(result.ok()); | |
| 277 if (result.val) delete result.val; | |
| 278 } | |
| 279 } | 284 } |
| 280 | 285 |
| 281 | 286 |
| 282 TEST_F(WasmModuleVerifyTest, FunctionWithoutSig) { | 287 TEST_F(WasmModuleVerifyTest, FunctionWithoutSig) { |
| 283 static const byte data[] = { | 288 static const byte data[] = { |
| 284 kDeclFunctions, 1, | 289 kDeclFunctions, 1, |
| 285 // func#0 ------------------------------------------------------ | 290 // func#0 ------------------------------------------------------ |
| 286 SIG_INDEX(0), // signature index | 291 SIG_INDEX(0), // signature index |
| 287 NAME_OFFSET(0), // name offset | 292 NAME_OFFSET(0), // name offset |
| 288 U32(0), // code start offset | 293 U32_LE(0), // code start offset |
| 289 U32(0), // code end offset | 294 U32_LE(0), // code end offset |
| 290 U16(899), // local int32 count | 295 U16_LE(899), // local int32 count |
| 291 U16(799), // local int64 count | 296 U16_LE(799), // local int64 count |
| 292 U16(699), // local float32 count | 297 U16_LE(699), // local float32 count |
| 293 U16(599), // local float64 count | 298 U16_LE(599), // local float64 count |
| 294 0, // exported | 299 0, // exported |
| 295 1 // external | 300 1 // external |
| 296 }; | 301 }; |
| 297 | 302 |
| 298 ModuleResult result = DecodeModule(data, data + arraysize(data)); | 303 ModuleResult result = DecodeModule(data, data + arraysize(data)); |
| 299 EXPECT_FALSE(result.ok()); | 304 EXPECT_FALSE(result.ok()); |
| 300 if (result.val) delete result.val; | 305 if (result.val) delete result.val; |
| 301 } | 306 } |
| 302 | 307 |
| 303 | 308 |
| 304 TEST_F(WasmModuleVerifyTest, OneEmptyVoidVoidFunction) { | 309 TEST_F(WasmModuleVerifyTest, OneEmptyVoidVoidFunction) { |
| 305 const int kCodeStartOffset = 23; | 310 const int kCodeStartOffset = 31; |
| 306 const int kCodeEndOffset = kCodeStartOffset + 1; | 311 const int kCodeEndOffset = kCodeStartOffset + 1; |
| 307 | 312 |
| 308 static const byte data[] = { | 313 static const byte data[] = { |
| 309 kDeclSignatures, 1, | 314 kDeclSignatures, 1, |
| 310 // sig#0 ------------------------------------------------------- | 315 // sig#0 ------------------------------------------------------- |
| 311 VOID_VOID_SIG, | 316 VOID_VOID_SIG, |
| 312 // func#0 ------------------------------------------------------ | 317 // func#0 ------------------------------------------------------ |
| 313 kDeclFunctions, 1, | 318 kDeclFunctions, 1, |
| 314 kDeclFunctionLocals | kDeclFunctionExport | kDeclFunctionName, | 319 kDeclFunctionLocals | kDeclFunctionExport | kDeclFunctionName, |
| 315 SIG_INDEX(0), // signature index | 320 SIG_INDEX(0), // signature index |
| 316 NAME_OFFSET(9), // name offset | 321 NAME_OFFSET(9), // name offset |
| 317 U16(1466), // local int32 count | 322 U16_LE(1466), // local int32 count |
| 318 U16(1355), // local int64 count | 323 U16_LE(1355), // local int64 count |
| 319 U16(1244), // local float32 count | 324 U16_LE(1244), // local float32 count |
| 320 U16(1133), // local float64 count | 325 U16_LE(1133), // local float64 count |
| 321 1, 0, // size | 326 1, 0, // size |
| 322 kExprNop, | 327 kExprNop, |
| 323 }; | 328 }; |
| 324 | 329 |
| 325 { | 330 { |
| 326 // Should decode to exactly one function. | 331 // Should decode to exactly one function. |
| 327 ModuleResult result = DecodeModule(data, data + arraysize(data)); | 332 ModuleResult result = DecodeModule(data, data + arraysize(data)); |
| 328 EXPECT_TRUE(result.ok()); | 333 EXPECT_TRUE(result.ok()); |
| 329 EXPECT_EQ(0, result.val->globals->size()); | 334 EXPECT_EQ(0, result.val->globals->size()); |
| 330 EXPECT_EQ(1, result.val->signatures->size()); | 335 EXPECT_EQ(1, result.val->signatures->size()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 342 EXPECT_EQ(1355, function->local_i64_count); | 347 EXPECT_EQ(1355, function->local_i64_count); |
| 343 EXPECT_EQ(1244, function->local_f32_count); | 348 EXPECT_EQ(1244, function->local_f32_count); |
| 344 EXPECT_EQ(1133, function->local_f64_count); | 349 EXPECT_EQ(1133, function->local_f64_count); |
| 345 | 350 |
| 346 EXPECT_TRUE(function->exported); | 351 EXPECT_TRUE(function->exported); |
| 347 EXPECT_FALSE(function->external); | 352 EXPECT_FALSE(function->external); |
| 348 | 353 |
| 349 if (result.val) delete result.val; | 354 if (result.val) delete result.val; |
| 350 } | 355 } |
| 351 | 356 |
| 352 for (size_t size = 5; size < arraysize(data); size++) { | 357 EXPECT_OFF_END_FAILURE(data, 5, sizeof(data)); |
| 353 // Should fall off end of module bytes. | |
| 354 ModuleResult result = DecodeModule(data, data + size); | |
| 355 EXPECT_FALSE(result.ok()); | |
| 356 if (result.val) delete result.val; | |
| 357 } | |
| 358 } | 358 } |
| 359 | 359 |
| 360 | 360 |
| 361 TEST_F(WasmModuleVerifyTest, OneFunctionImported) { | 361 TEST_F(WasmModuleVerifyTest, OneFunctionImported) { |
| 362 static const byte data[] = { | 362 static const byte data[] = { |
| 363 kDeclSignatures, 1, | 363 kDeclSignatures, 1, |
| 364 // sig#0 ------------------------------------------------------- | 364 // sig#0 ------------------------------------------------------- |
| 365 VOID_VOID_SIG, kDeclFunctions, 1, | 365 VOID_VOID_SIG, kDeclFunctions, 1, |
| 366 // func#0 ------------------------------------------------------ | 366 // func#0 ------------------------------------------------------ |
| 367 kDeclFunctionImport, // no name, no locals, imported | 367 kDeclFunctionImport, // no name, no locals, imported |
| (...skipping 15 matching lines...) Expand all Loading... |
| 383 EXPECT_EQ(0, function->local_f64_count); | 383 EXPECT_EQ(0, function->local_f64_count); |
| 384 | 384 |
| 385 EXPECT_FALSE(function->exported); | 385 EXPECT_FALSE(function->exported); |
| 386 EXPECT_TRUE(function->external); | 386 EXPECT_TRUE(function->external); |
| 387 | 387 |
| 388 if (result.val) delete result.val; | 388 if (result.val) delete result.val; |
| 389 } | 389 } |
| 390 | 390 |
| 391 | 391 |
| 392 TEST_F(WasmModuleVerifyTest, OneFunctionWithNopBody) { | 392 TEST_F(WasmModuleVerifyTest, OneFunctionWithNopBody) { |
| 393 static const byte kCodeStartOffset = 11; | 393 static const byte kCodeStartOffset = 19; |
| 394 static const byte kCodeEndOffset = kCodeStartOffset + 1; | 394 static const byte kCodeEndOffset = kCodeStartOffset + 1; |
| 395 | 395 |
| 396 static const byte data[] = { | 396 static const byte data[] = { |
| 397 kDeclSignatures, 1, | 397 kDeclSignatures, 1, |
| 398 // sig#0 ------------------------------------------------------- | 398 // sig#0 ------------------------------------------------------- |
| 399 0, 0, // void -> void | 399 0, 0, // void -> void |
| 400 kDeclFunctions, 1, | 400 kDeclFunctions, 1, |
| 401 // func#0 ------------------------------------------------------ | 401 // func#0 ------------------------------------------------------ |
| 402 0, // no name, no locals | 402 0, // no name, no locals |
| 403 0, 0, // signature index | 403 0, 0, // signature index |
| (...skipping 16 matching lines...) Expand all Loading... |
| 420 EXPECT_EQ(0, function->local_f64_count); | 420 EXPECT_EQ(0, function->local_f64_count); |
| 421 | 421 |
| 422 EXPECT_FALSE(function->exported); | 422 EXPECT_FALSE(function->exported); |
| 423 EXPECT_FALSE(function->external); | 423 EXPECT_FALSE(function->external); |
| 424 | 424 |
| 425 if (result.val) delete result.val; | 425 if (result.val) delete result.val; |
| 426 } | 426 } |
| 427 | 427 |
| 428 | 428 |
| 429 TEST_F(WasmModuleVerifyTest, OneFunctionWithNopBody_WithLocals) { | 429 TEST_F(WasmModuleVerifyTest, OneFunctionWithNopBody_WithLocals) { |
| 430 static const byte kCodeStartOffset = 19; | 430 static const byte kCodeStartOffset = 27; |
| 431 static const byte kCodeEndOffset = kCodeStartOffset + 1; | 431 static const byte kCodeEndOffset = kCodeStartOffset + 1; |
| 432 | 432 |
| 433 static const byte data[] = { | 433 static const byte data[] = { |
| 434 kDeclSignatures, 1, | 434 kDeclSignatures, 1, |
| 435 // sig#0 ------------------------------------------------------- | 435 // sig#0 ------------------------------------------------------- |
| 436 0, 0, // void -> void | 436 0, 0, // void -> void |
| 437 kDeclFunctions, 1, | 437 kDeclFunctions, 1, |
| 438 // func#0 ------------------------------------------------------ | 438 // func#0 ------------------------------------------------------ |
| 439 kDeclFunctionLocals, 0, 0, // signature index | 439 kDeclFunctionLocals, 0, 0, // signature index |
| 440 1, 2, // local int32 count | 440 1, 2, // local int32 count |
| (...skipping 21 matching lines...) Expand all Loading... |
| 462 EXPECT_FALSE(function->exported); | 462 EXPECT_FALSE(function->exported); |
| 463 EXPECT_FALSE(function->external); | 463 EXPECT_FALSE(function->external); |
| 464 | 464 |
| 465 if (result.val) delete result.val; | 465 if (result.val) delete result.val; |
| 466 } | 466 } |
| 467 | 467 |
| 468 | 468 |
| 469 TEST_F(WasmModuleVerifyTest, OneGlobalOneFunctionWithNopBodyOneDataSegment) { | 469 TEST_F(WasmModuleVerifyTest, OneGlobalOneFunctionWithNopBodyOneDataSegment) { |
| 470 static const byte kDeclMemorySize = 4; | 470 static const byte kDeclMemorySize = 4; |
| 471 static const byte kCodeStartOffset = | 471 static const byte kCodeStartOffset = |
| 472 2 + kDeclMemorySize + kDeclGlobalSize + 4 + 2 + 17; | 472 8 + 2 + kDeclMemorySize + kDeclGlobalSize + 4 + 2 + 17; |
| 473 static const byte kCodeEndOffset = kCodeStartOffset + 3; | 473 static const byte kCodeEndOffset = kCodeStartOffset + 3; |
| 474 | 474 |
| 475 static const byte data[] = { | 475 static const byte data[] = { |
| 476 kDeclMemory, 28, 28, 1, | 476 kDeclMemory, 28, 28, 1, |
| 477 // global#0 -------------------------------------------------- | 477 // global#0 -------------------------------------------------- |
| 478 kDeclGlobals, 1, 0, 0, 0, 0, // name offset | 478 kDeclGlobals, 1, 0, 0, 0, 0, // name offset |
| 479 kMemU8, // memory type | 479 kMemU8, // memory type |
| 480 0, // exported | 480 0, // exported |
| 481 // sig#0 ----------------------------------------------------- | 481 // sig#0 ----------------------------------------------------- |
| 482 kDeclSignatures, 1, 0, 0, // void -> void | 482 kDeclSignatures, 1, 0, 0, // void -> void |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 WasmDataSegment* segment = &result.val->data_segments->back(); | 558 WasmDataSegment* segment = &result.val->data_segments->back(); |
| 559 | 559 |
| 560 EXPECT_EQ(0x9bbaa, segment->dest_addr); | 560 EXPECT_EQ(0x9bbaa, segment->dest_addr); |
| 561 EXPECT_EQ(11, segment->source_offset); | 561 EXPECT_EQ(11, segment->source_offset); |
| 562 EXPECT_EQ(3, segment->source_size); | 562 EXPECT_EQ(3, segment->source_size); |
| 563 EXPECT_TRUE(segment->init); | 563 EXPECT_TRUE(segment->init); |
| 564 | 564 |
| 565 if (result.val) delete result.val; | 565 if (result.val) delete result.val; |
| 566 } | 566 } |
| 567 | 567 |
| 568 for (size_t size = 5; size < arraysize(data); size++) { | 568 EXPECT_OFF_END_FAILURE(data, 5, sizeof(data)); |
| 569 // Should fall off end of module bytes. | |
| 570 ModuleResult result = DecodeModule(data, data + size); | |
| 571 EXPECT_FALSE(result.ok()); | |
| 572 if (result.val) delete result.val; | |
| 573 } | |
| 574 } | 569 } |
| 575 | 570 |
| 576 | 571 |
| 577 TEST_F(WasmModuleVerifyTest, TwoDataSegments) { | 572 TEST_F(WasmModuleVerifyTest, TwoDataSegments) { |
| 578 const byte data[] = { | 573 const byte data[] = { |
| 579 kDeclMemory, 28, 28, 1, kDeclDataSegments, 2, 0xee, 0xff, 0x07, | 574 kDeclMemory, 28, 28, 1, kDeclDataSegments, 2, 0xee, 0xff, 0x07, |
| 580 0, // dest addr | 575 0, // dest addr |
| 581 9, 0, 0, | 576 9, 0, 0, |
| 582 0, // #0: source offset | 577 0, // #0: source offset |
| 583 4, 0, 0, | 578 4, 0, 0, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 608 EXPECT_FALSE(s0->init); | 603 EXPECT_FALSE(s0->init); |
| 609 | 604 |
| 610 EXPECT_EQ(0x6ddcc, s1->dest_addr); | 605 EXPECT_EQ(0x6ddcc, s1->dest_addr); |
| 611 EXPECT_EQ(6, s1->source_offset); | 606 EXPECT_EQ(6, s1->source_offset); |
| 612 EXPECT_EQ(10, s1->source_size); | 607 EXPECT_EQ(10, s1->source_size); |
| 613 EXPECT_TRUE(s1->init); | 608 EXPECT_TRUE(s1->init); |
| 614 | 609 |
| 615 if (result.val) delete result.val; | 610 if (result.val) delete result.val; |
| 616 } | 611 } |
| 617 | 612 |
| 618 for (size_t size = 5; size < arraysize(data); size++) { | 613 EXPECT_OFF_END_FAILURE(data, 5, sizeof(data)); |
| 619 // Should fall off end of module bytes. | |
| 620 ModuleResult result = DecodeModule(data, data + size); | |
| 621 EXPECT_FALSE(result.ok()); | |
| 622 if (result.val) delete result.val; | |
| 623 } | |
| 624 } | 614 } |
| 625 | 615 |
| 626 | 616 |
| 627 TEST_F(WasmModuleVerifyTest, DataSegmentWithInvalidSource) { | 617 TEST_F(WasmModuleVerifyTest, DataSegmentWithInvalidSource) { |
| 628 const int dest_addr = 0x100; | 618 const int dest_addr = 0x100; |
| 629 const byte mem_size_log2 = 15; | 619 const byte mem_size_log2 = 15; |
| 620 const int kHeaderSize = 8; |
| 630 const int kDataSize = 19; | 621 const int kDataSize = 19; |
| 622 const int kTotalSize = kHeaderSize + kDataSize; |
| 631 | 623 |
| 632 for (int source_offset = 0; source_offset < 5 + kDataSize; source_offset++) { | 624 for (int source_offset = 0; source_offset < 5 + kDataSize; source_offset++) { |
| 633 for (int source_size = -1; source_size < 5 + kDataSize; source_size += 3) { | 625 for (int source_size = -1; source_size < 5 + kDataSize; source_size += 3) { |
| 634 byte data[] = { | 626 byte data[] = { |
| 635 kDeclMemory, | 627 kDeclMemory, |
| 636 mem_size_log2, | 628 mem_size_log2, |
| 637 mem_size_log2, | 629 mem_size_log2, |
| 638 1, | 630 1, |
| 639 kDeclDataSegments, | 631 kDeclDataSegments, |
| 640 1, | 632 1, |
| 641 U32(dest_addr), | 633 U32_LE(dest_addr), |
| 642 U32(source_offset), | 634 U32_LE(source_offset), |
| 643 U32(source_size), | 635 U32_LE(source_size), |
| 644 1, // init | 636 1, // init |
| 645 }; | 637 }; |
| 646 | 638 |
| 647 STATIC_ASSERT(kDataSize == arraysize(data)); | 639 STATIC_ASSERT(kDataSize == arraysize(data)); |
| 648 | 640 |
| 649 if (source_offset < kDataSize && source_size >= 0 && | 641 if (source_offset < kTotalSize && source_size >= 0 && |
| 650 (source_offset + source_size) <= kDataSize) { | 642 (source_offset + source_size) <= kTotalSize) { |
| 651 EXPECT_VERIFIES(data); | 643 EXPECT_VERIFIES(data); |
| 652 } else { | 644 } else { |
| 653 EXPECT_FAILURE(data); | 645 EXPECT_FAILURE(data); |
| 654 } | 646 } |
| 655 } | 647 } |
| 656 } | 648 } |
| 657 } | 649 } |
| 658 | 650 |
| 659 | 651 |
| 660 TEST_F(WasmModuleVerifyTest, DataSegmentWithInvalidDest) { | 652 TEST_F(WasmModuleVerifyTest, DataSegmentWithInvalidDest) { |
| 661 const int source_size = 3; | 653 const int source_size = 3; |
| 662 const int source_offset = 11; | 654 const int source_offset = 11; |
| 663 | 655 |
| 664 for (byte mem_size_log2 = 12; mem_size_log2 < 20; mem_size_log2++) { | 656 for (byte mem_size_log2 = 12; mem_size_log2 < 20; mem_size_log2++) { |
| 665 int mem_size = 1 << mem_size_log2; | 657 int mem_size = 1 << mem_size_log2; |
| 666 | 658 |
| 667 for (int dest_addr = mem_size - source_size; | 659 for (int dest_addr = mem_size - source_size; |
| 668 dest_addr < mem_size + source_size; dest_addr++) { | 660 dest_addr < mem_size + source_size; dest_addr++) { |
| 669 byte data[] = { | 661 byte data[] = { |
| 670 kDeclMemory, | 662 kDeclMemory, |
| 671 mem_size_log2, | 663 mem_size_log2, |
| 672 mem_size_log2, | 664 mem_size_log2, |
| 673 1, | 665 1, |
| 674 kDeclDataSegments, | 666 kDeclDataSegments, |
| 675 1, | 667 1, |
| 676 U32(dest_addr), | 668 U32_LE(dest_addr), |
| 677 U32(source_offset), | 669 U32_LE(source_offset), |
| 678 U32(source_size), | 670 U32_LE(source_size), |
| 679 1, // init | 671 1, // init |
| 680 }; | 672 }; |
| 681 | 673 |
| 682 if (dest_addr <= (mem_size - source_size)) { | 674 if (dest_addr <= (mem_size - source_size)) { |
| 683 EXPECT_VERIFIES(data); | 675 EXPECT_VERIFIES(data); |
| 684 } else { | 676 } else { |
| 685 EXPECT_FAILURE(data); | 677 EXPECT_FAILURE(data); |
| 686 } | 678 } |
| 687 } | 679 } |
| 688 } | 680 } |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1036 } | 1028 } |
| 1037 | 1029 |
| 1038 TEST_F(WasmModuleVerifyTest, ImportTable_off_end) { | 1030 TEST_F(WasmModuleVerifyTest, ImportTable_off_end) { |
| 1039 static const byte data[] = { | 1031 static const byte data[] = { |
| 1040 kDeclSignatures, 1, VOID_VOID_SIG, kDeclImportTable, 1, | 1032 kDeclSignatures, 1, VOID_VOID_SIG, kDeclImportTable, 1, |
| 1041 SIG_INDEX(0), // sig index | 1033 SIG_INDEX(0), // sig index |
| 1042 NAME_OFFSET(1), // module name | 1034 NAME_OFFSET(1), // module name |
| 1043 NAME_OFFSET(1), // function name | 1035 NAME_OFFSET(1), // function name |
| 1044 }; | 1036 }; |
| 1045 | 1037 |
| 1046 for (size_t length = 5; length < sizeof(data); length++) { | 1038 EXPECT_OFF_END_FAILURE(data, 5, sizeof(data)); |
| 1047 ModuleResult result = DecodeModule(data, data + length); | |
| 1048 EXPECT_FALSE(result.ok()); | |
| 1049 if (result.val) delete result.val; | |
| 1050 } | |
| 1051 } | 1039 } |
| 1052 | 1040 |
| 1053 TEST_F(WasmModuleVerifyTest, ExportTable_empty) { | 1041 TEST_F(WasmModuleVerifyTest, ExportTable_empty) { |
| 1054 static const byte data[] = {kDeclSignatures, 0, kDeclFunctions, 0, | 1042 static const byte data[] = {kDeclSignatures, 0, kDeclFunctions, 0, |
| 1055 kDeclExportTable, 0}; | 1043 kDeclExportTable, 0}; |
| 1056 EXPECT_VERIFIES(data); | 1044 EXPECT_VERIFIES(data); |
| 1057 } | 1045 } |
| 1058 | 1046 |
| 1059 TEST_F(WasmModuleVerifyTest, ExportTable_NoFunctions1) { | 1047 TEST_F(WasmModuleVerifyTest, ExportTable_NoFunctions1) { |
| 1060 static const byte data[] = {kDeclSignatures, 0, kDeclExportTable, 0}; | 1048 static const byte data[] = {kDeclSignatures, 0, kDeclExportTable, 0}; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1149 for (int length = 13; length < sizeof(data); length++) { | 1137 for (int length = 13; length < sizeof(data); length++) { |
| 1150 ModuleResult result = DecodeModule(data, data + length); | 1138 ModuleResult result = DecodeModule(data, data + length); |
| 1151 EXPECT_FALSE(result.ok()); | 1139 EXPECT_FALSE(result.ok()); |
| 1152 if (result.val) delete result.val; | 1140 if (result.val) delete result.val; |
| 1153 } | 1141 } |
| 1154 } | 1142 } |
| 1155 | 1143 |
| 1156 } // namespace wasm | 1144 } // namespace wasm |
| 1157 } // namespace internal | 1145 } // namespace internal |
| 1158 } // namespace v8 | 1146 } // namespace v8 |
| OLD | NEW |