Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(880)

Side by Side Diff: src/wasm/decoder.h

Issue 2052623003: [wasm] improve handling of malformed input (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: remove debugging statement Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #ifndef V8_WASM_DECODER_H_ 5 #ifndef V8_WASM_DECODER_H_
6 #define V8_WASM_DECODER_H_ 6 #define V8_WASM_DECODER_H_
7 7
8 #include "src/base/compiler-specific.h" 8 #include "src/base/compiler-specific.h"
9 #include "src/base/smart-pointers.h" 9 #include "src/base/smart-pointers.h"
10 #include "src/flags.h" 10 #include "src/flags.h"
(...skipping 28 matching lines...) Expand all
39 Decoder(const byte* start, const byte* end) 39 Decoder(const byte* start, const byte* end)
40 : start_(start), 40 : start_(start),
41 pc_(start), 41 pc_(start),
42 limit_(end), 42 limit_(end),
43 end_(end), 43 end_(end),
44 error_pc_(nullptr), 44 error_pc_(nullptr),
45 error_pt_(nullptr) {} 45 error_pt_(nullptr) {}
46 46
47 virtual ~Decoder() {} 47 virtual ~Decoder() {}
48 48
49 inline bool check(const byte* base, int offset, int length, const char* msg) { 49 inline bool check(const byte* base, unsigned int offset, unsigned int length,
50 const char* msg) {
50 DCHECK_GE(base, start_); 51 DCHECK_GE(base, start_);
51 if ((base + offset + length) > limit_) { 52 if ((base + offset + length) > limit_) {
52 error(base, base + offset, "%s", msg); 53 error(base, base + offset, "%s", msg);
53 return false; 54 return false;
54 } 55 }
55 return true; 56 return true;
56 } 57 }
57 58
58 // Reads a single 8-bit byte, reporting an error if out of bounds. 59 // Reads a single 8-bit byte, reporting an error if out of bounds.
59 inline uint8_t checked_read_u8(const byte* base, int offset, 60 inline uint8_t checked_read_u8(const byte* base, unsigned int offset,
60 const char* msg = "expected 1 byte") { 61 const char* msg = "expected 1 byte") {
61 return check(base, offset, 1, msg) ? base[offset] : 0; 62 return check(base, offset, 1, msg) ? base[offset] : 0;
62 } 63 }
63 64
64 // Reads 16-bit word, reporting an error if out of bounds. 65 // Reads 16-bit word, reporting an error if out of bounds.
65 inline uint16_t checked_read_u16(const byte* base, int offset, 66 inline uint16_t checked_read_u16(const byte* base, unsigned int offset,
66 const char* msg = "expected 2 bytes") { 67 const char* msg = "expected 2 bytes") {
67 return check(base, offset, 2, msg) ? read_u16(base + offset) : 0; 68 return check(base, offset, 2, msg) ? read_u16(base + offset) : 0;
68 } 69 }
69 70
70 // Reads 32-bit word, reporting an error if out of bounds. 71 // Reads 32-bit word, reporting an error if out of bounds.
71 inline uint32_t checked_read_u32(const byte* base, int offset, 72 inline uint32_t checked_read_u32(const byte* base, unsigned int offset,
72 const char* msg = "expected 4 bytes") { 73 const char* msg = "expected 4 bytes") {
73 return check(base, offset, 4, msg) ? read_u32(base + offset) : 0; 74 return check(base, offset, 4, msg) ? read_u32(base + offset) : 0;
74 } 75 }
75 76
76 // Reads 64-bit word, reporting an error if out of bounds. 77 // Reads 64-bit word, reporting an error if out of bounds.
77 inline uint64_t checked_read_u64(const byte* base, int offset, 78 inline uint64_t checked_read_u64(const byte* base, unsigned int offset,
78 const char* msg = "expected 8 bytes") { 79 const char* msg = "expected 8 bytes") {
79 return check(base, offset, 8, msg) ? read_u64(base + offset) : 0; 80 return check(base, offset, 8, msg) ? read_u64(base + offset) : 0;
80 } 81 }
81 82
82 // Reads a variable-length unsigned integer (little endian). 83 // Reads a variable-length unsigned integer (little endian).
83 uint32_t checked_read_u32v(const byte* base, int offset, int* length, 84 uint32_t checked_read_u32v(const byte* base, unsigned int offset,
85 unsigned int* length,
84 const char* msg = "expected LEB32") { 86 const char* msg = "expected LEB32") {
85 return checked_read_leb<uint32_t, false>(base, offset, length, msg); 87 return checked_read_leb<uint32_t, false>(base, offset, length, msg);
86 } 88 }
87 89
88 // Reads a variable-length signed integer (little endian). 90 // Reads a variable-length signed integer (little endian).
89 int32_t checked_read_i32v(const byte* base, int offset, int* length, 91 int32_t checked_read_i32v(const byte* base, unsigned int offset,
92 unsigned int* length,
90 const char* msg = "expected SLEB32") { 93 const char* msg = "expected SLEB32") {
91 uint32_t result = 94 uint32_t result =
92 checked_read_leb<uint32_t, true>(base, offset, length, msg); 95 checked_read_leb<uint32_t, true>(base, offset, length, msg);
93 if (*length == 5) return bit_cast<int32_t>(result); 96 if (*length == 5) return bit_cast<int32_t>(result);
94 if (*length > 0) { 97 if (*length > 0) {
95 int shift = 32 - 7 * *length; 98 int shift = 32 - 7 * *length;
96 // Perform sign extension. 99 // Perform sign extension.
97 return bit_cast<int32_t>(result << shift) >> shift; 100 return bit_cast<int32_t>(result << shift) >> shift;
98 } 101 }
99 return 0; 102 return 0;
100 } 103 }
101 104
102 // Reads a variable-length unsigned integer (little endian). 105 // Reads a variable-length unsigned integer (little endian).
103 uint64_t checked_read_u64v(const byte* base, int offset, int* length, 106 uint64_t checked_read_u64v(const byte* base, unsigned int offset,
107 unsigned int* length,
104 const char* msg = "expected LEB64") { 108 const char* msg = "expected LEB64") {
105 return checked_read_leb<uint64_t, false>(base, offset, length, msg); 109 return checked_read_leb<uint64_t, false>(base, offset, length, msg);
106 } 110 }
107 111
108 // Reads a variable-length signed integer (little endian). 112 // Reads a variable-length signed integer (little endian).
109 int64_t checked_read_i64v(const byte* base, int offset, int* length, 113 int64_t checked_read_i64v(const byte* base, unsigned int offset,
114 unsigned int* length,
110 const char* msg = "expected SLEB64") { 115 const char* msg = "expected SLEB64") {
111 uint64_t result = 116 uint64_t result =
112 checked_read_leb<uint64_t, true>(base, offset, length, msg); 117 checked_read_leb<uint64_t, true>(base, offset, length, msg);
113 if (*length == 10) return bit_cast<int64_t>(result); 118 if (*length == 10) return bit_cast<int64_t>(result);
114 if (*length > 0) { 119 if (*length > 0) {
115 int shift = 64 - 7 * *length; 120 int shift = 64 - 7 * *length;
116 // Perform sign extension. 121 // Perform sign extension.
117 return bit_cast<int64_t>(result << shift) >> shift; 122 return bit_cast<int64_t>(result << shift) >> shift;
118 } 123 }
119 return 0; 124 return 0;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 if (checkAvailable(4)) { 202 if (checkAvailable(4)) {
198 uint32_t val = read_u32(pc_); 203 uint32_t val = read_u32(pc_);
199 TRACE("%02x %02x %02x %02x = %u\n", pc_[0], pc_[1], pc_[2], pc_[3], val); 204 TRACE("%02x %02x %02x %02x = %u\n", pc_[0], pc_[1], pc_[2], pc_[3], val);
200 pc_ += 4; 205 pc_ += 4;
201 return val; 206 return val;
202 } 207 }
203 return traceOffEnd<uint32_t>(); 208 return traceOffEnd<uint32_t>();
204 } 209 }
205 210
206 // Reads a LEB128 variable-length 32-bit integer and advances {pc_}. 211 // Reads a LEB128 variable-length 32-bit integer and advances {pc_}.
207 uint32_t consume_u32v(int* length, const char* name = nullptr) { 212 uint32_t consume_u32v(unsigned int* length, const char* name = nullptr) {
208 TRACE(" +%d %-20s: ", static_cast<int>(pc_ - start_), 213 TRACE(" +%d %-20s: ", static_cast<int>(pc_ - start_),
209 name ? name : "varint"); 214 name ? name : "varint");
210 215
211 if (checkAvailable(1)) { 216 if (checkAvailable(1)) {
212 const byte* pos = pc_; 217 const byte* pos = pc_;
213 const byte* end = pc_ + 5; 218 const byte* end = pc_ + 5;
214 if (end > limit_) end = limit_; 219 if (end > limit_) end = limit_;
215 220
216 uint32_t result = 0; 221 uint32_t result = 0;
217 int shift = 0; 222 int shift = 0;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 const byte* start_; 348 const byte* start_;
344 const byte* pc_; 349 const byte* pc_;
345 const byte* limit_; 350 const byte* limit_;
346 const byte* end_; 351 const byte* end_;
347 const byte* error_pc_; 352 const byte* error_pc_;
348 const byte* error_pt_; 353 const byte* error_pt_;
349 base::SmartArrayPointer<char> error_msg_; 354 base::SmartArrayPointer<char> error_msg_;
350 355
351 private: 356 private:
352 template <typename IntType, bool is_signed> 357 template <typename IntType, bool is_signed>
353 IntType checked_read_leb(const byte* base, int offset, int* length, 358 IntType checked_read_leb(const byte* base, unsigned int offset,
354 const char* msg) { 359 unsigned int* length, const char* msg) {
355 if (!check(base, offset, 1, msg)) { 360 if (!check(base, offset, 1, msg)) {
356 *length = 0; 361 *length = 0;
357 return 0; 362 return 0;
358 } 363 }
359 364
360 const int kMaxLength = (sizeof(IntType) * 8 + 6) / 7; 365 const int kMaxLength = (sizeof(IntType) * 8 + 6) / 7;
361 const byte* ptr = base + offset; 366 const byte* ptr = base + offset;
362 const byte* end = ptr + kMaxLength; 367 const byte* end = ptr + kMaxLength;
363 if (end > limit_) end = limit_; 368 if (end > limit_) end = limit_;
364 int shift = 0; 369 int shift = 0;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 return result; 407 return result;
403 } 408 }
404 }; 409 };
405 410
406 #undef TRACE 411 #undef TRACE
407 } // namespace wasm 412 } // namespace wasm
408 } // namespace internal 413 } // namespace internal
409 } // namespace v8 414 } // namespace v8
410 415
411 #endif // V8_WASM_DECODER_H_ 416 #endif // V8_WASM_DECODER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698