diff options
Diffstat (limited to 'src/binary-reader.c')
-rw-r--r-- | src/binary-reader.c | 71 |
1 files changed, 50 insertions, 21 deletions
diff --git a/src/binary-reader.c b/src/binary-reader.c index 5fe7977a..a8bc2fd6 100644 --- a/src/binary-reader.c +++ b/src/binary-reader.c @@ -200,72 +200,88 @@ static void in_f64(Context* ctx, uint64_t* out_value, const char* desc) { ((type)((value) << SHIFT_AMOUNT(type, sign_bit)) >> \ SHIFT_AMOUNT(type, sign_bit)) -static void in_u32_leb128(Context* ctx, uint32_t* out_value, const char* desc) { - const uint8_t* p = ctx->data + ctx->offset; - const uint8_t* end = ctx->data + ctx->section_end; - +size_t wasm_read_u32_leb128(const uint8_t* p, + const uint8_t* end, + uint32_t* out_value) { if (p < end && (p[0] & 0x80) == 0) { *out_value = LEB128_1(uint32_t); - ctx->offset += 1; + return 1; } else if (p + 1 < end && (p[1] & 0x80) == 0) { *out_value = LEB128_2(uint32_t); - ctx->offset += 2; + return 2; } else if (p + 2 < end && (p[2] & 0x80) == 0) { *out_value = LEB128_3(uint32_t); - ctx->offset += 3; + return 3; } else if (p + 3 < end && (p[3] & 0x80) == 0) { *out_value = LEB128_4(uint32_t); - ctx->offset += 4; + return 4; } else if (p + 4 < end && (p[4] & 0x80) == 0) { /* the top bits set represent values > 32 bits */ if (p[4] & 0xf0) - RAISE_ERROR("invalid u32 leb128: %s", desc); + return 0; *out_value = LEB128_5(uint32_t); - ctx->offset += 5; + return 5; } else { /* past the end */ *out_value = 0; - RAISE_ERROR("unable to read u32 leb128: %s", desc); + return 0; } } -static void in_i32_leb128(Context* ctx, uint32_t* out_value, const char* desc) { +static void in_u32_leb128(Context* ctx, uint32_t* out_value, const char* desc) { const uint8_t* p = ctx->data + ctx->offset; const uint8_t* end = ctx->data + ctx->section_end; + size_t bytes_read = wasm_read_u32_leb128(p, end, out_value); + if (!bytes_read) + RAISE_ERROR("unable to read u32 leb128: %s", desc); + ctx->offset += bytes_read; +} +size_t wasm_read_i32_leb128(const uint8_t* p, + const uint8_t* end, + uint32_t* out_value) { if (p < end && (p[0] & 0x80) == 0) { uint32_t result = LEB128_1(uint32_t); *out_value = SIGN_EXTEND(int32_t, result, 6); - ctx->offset += 1; + return 1; } else if (p + 1 < end && (p[1] & 0x80) == 0) { uint32_t result = LEB128_2(uint32_t); *out_value = SIGN_EXTEND(int32_t, result, 13); - ctx->offset += 2; + return 2; } else if (p + 2 < end && (p[2] & 0x80) == 0) { uint32_t result = LEB128_3(uint32_t); *out_value = SIGN_EXTEND(int32_t, result, 20); - ctx->offset += 3; + return 3; } else if (p + 3 < end && (p[3] & 0x80) == 0) { uint32_t result = LEB128_4(uint32_t); *out_value = SIGN_EXTEND(int32_t, result, 27); - ctx->offset += 4; + return 4; } else if (p + 4 < end && (p[4] & 0x80) == 0) { /* the top bits should be a sign-extension of the sign bit */ WasmBool sign_bit_set = (p[4] & 0x8); int top_bits = p[4] & 0xf0; if ((sign_bit_set && top_bits != 0x70) || (!sign_bit_set && top_bits != 0)) { - RAISE_ERROR("invalid i32 leb128: %s", desc); + return 0; } uint32_t result = LEB128_5(uint32_t); *out_value = result; - ctx->offset += 5; + return 5; } else { /* past the end */ - RAISE_ERROR("unable to read i32 leb128: %s", desc); + return 0; } } +static void in_i32_leb128(Context* ctx, uint32_t* out_value, const char* desc) { + const uint8_t* p = ctx->data + ctx->offset; + const uint8_t* end = ctx->data + ctx->section_end; + size_t bytes_read = wasm_read_i32_leb128(p, end, out_value); + if (!bytes_read) + RAISE_ERROR("unable to read i32 leb128: %s", desc); + ctx->offset += bytes_read; +} + static void in_i64_leb128(Context* ctx, uint64_t* out_value, const char* desc) { const uint8_t* p = ctx->data + ctx->offset; const uint8_t* end = ctx->data + ctx->section_end; @@ -465,6 +481,7 @@ static WasmBool skip_until_section(Context* ctx, RAISE_ERROR("invalid section size: extends past end"); if (section_code == WASM_BINARY_SECTION_CUSTOM) { + CALLBACK_CTX(begin_section, section_code, *section_size); WasmStringSlice section_name; in_str(ctx, §ion_name, "section name"); handle_custom_section(ctx, §ion_name, *section_size); @@ -478,6 +495,7 @@ static WasmBool skip_until_section(Context* ctx, } if (section_code == expected_code) { + CALLBACK_CTX(begin_section, section_code, *section_size); return WASM_TRUE; } else if (section_code < expected_code) { RAISE_ERROR("section %s out of order", s_section_name[section_code]); @@ -588,6 +606,14 @@ static WasmResult logging_begin_custom_section(WasmBinaryReaderContext* context, FORWARD(name, value0, value1); \ } +#define LOGGING_UINT32_UINT32_CTX(name, desc0, desc1) \ + static WasmResult logging_##name(WasmBinaryReaderContext* context, \ + uint32_t value0, uint32_t value1) { \ + LoggingContext* ctx = context->user_data; \ + LOGF(#name "(" desc0 ": %u, " desc1 ": %u)\n", value0, value1); \ + FORWARD_CTX(name, value0, value1); \ + } + #define LOGGING_OPCODE(name) \ static WasmResult logging_##name(WasmOpcode opcode, void* user_data) { \ LoggingContext* ctx = user_data; \ @@ -666,7 +692,9 @@ LOGGING_UINT32(on_elem_segment_count) LOGGING_UINT32_UINT32(begin_elem_segment, "index", "table_index") LOGGING_UINT32(begin_elem_segment_init_expr) LOGGING_UINT32(end_elem_segment_init_expr) -LOGGING_UINT32_UINT32(on_elem_segment_function_index_count, "index", "count") +LOGGING_UINT32_UINT32_CTX(on_elem_segment_function_index_count, + "index", + "count") LOGGING_UINT32_UINT32(on_elem_segment_function_index, "index", "func_index") LOGGING_UINT32(end_elem_segment) LOGGING_END(elem_section) @@ -1982,7 +2010,8 @@ WasmResult wasm_read_binary(WasmAllocator* allocator, uint32_t j, num_function_indexes; in_u32_leb128(ctx, &num_function_indexes, "elem segment function index count"); - CALLBACK(on_elem_segment_function_index_count, i, num_function_indexes); + CALLBACK_CTX(on_elem_segment_function_index_count, i, + num_function_indexes); for (j = 0; j < num_function_indexes; ++j) { uint32_t func_index; in_u32_leb128(ctx, &func_index, "elem segment function index"); |