mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
AK: Port LEB128
to the new AK::Stream
This commit is contained in:
parent
31f59855b4
commit
787f4d639a
Notes:
sideshowbarker
2024-07-17 03:14:39 +09:00
Author: https://github.com/timschumi Commit: https://github.com/SerenityOS/serenity/commit/787f4d639a Pull-request: https://github.com/SerenityOS/serenity/pull/17248 Reviewed-by: https://github.com/ADKaster ✅
10 changed files with 120 additions and 209 deletions
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <AK/DeprecatedStream.h>
|
||||
#include <AK/LEB128.h>
|
||||
#include <AK/MemMem.h>
|
||||
#include <AK/Vector.h>
|
||||
|
||||
|
@ -74,12 +73,6 @@ public:
|
|||
return m_bytes[m_offset];
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
bool read_LEB128_unsigned(ValueType& result) { return LEB128::read_unsigned(*this, result); }
|
||||
|
||||
template<typename ValueType>
|
||||
bool read_LEB128_signed(ValueType& result) { return LEB128::read_signed(*this, result); }
|
||||
|
||||
ReadonlyBytes bytes() const { return m_bytes; }
|
||||
size_t offset() const { return m_offset; }
|
||||
size_t remaining() const { return m_bytes.size() - m_offset; }
|
||||
|
|
42
AK/LEB128.h
42
AK/LEB128.h
|
@ -6,36 +6,32 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/DeprecatedStream.h>
|
||||
#include <AK/NumericLimits.h>
|
||||
#include <AK/Stream.h>
|
||||
#include <AK/Types.h>
|
||||
|
||||
namespace AK {
|
||||
|
||||
struct LEB128 {
|
||||
template<typename ValueType = size_t>
|
||||
static bool read_unsigned(DeprecatedInputStream& stream, ValueType& result)
|
||||
static ErrorOr<void> read_unsigned(AK::Stream& stream, ValueType& result)
|
||||
{
|
||||
result = 0;
|
||||
size_t num_bytes = 0;
|
||||
while (true) {
|
||||
if (stream.unreliable_eof()) {
|
||||
stream.set_fatal_error();
|
||||
return false;
|
||||
}
|
||||
u8 byte = 0;
|
||||
stream >> byte;
|
||||
if (stream.has_any_error())
|
||||
return false;
|
||||
if (stream.is_eof())
|
||||
return Error::from_string_literal("Stream reached end-of-file while reading LEB128 value");
|
||||
|
||||
auto byte = TRY(stream.read_value<u8>());
|
||||
|
||||
ValueType masked_byte = byte & ~(1 << 7);
|
||||
bool const shift_too_large_for_result = num_bytes * 7 > sizeof(ValueType) * 8;
|
||||
if (shift_too_large_for_result)
|
||||
return false;
|
||||
return Error::from_string_literal("Read value contains more bits than fit the chosen ValueType");
|
||||
|
||||
bool const shift_too_large_for_byte = ((masked_byte << (num_bytes * 7)) >> (num_bytes * 7)) != masked_byte;
|
||||
if (shift_too_large_for_byte)
|
||||
return false;
|
||||
return Error::from_string_literal("Read byte is too large to fit the chosen ValueType");
|
||||
|
||||
result = (result) | (masked_byte << (num_bytes * 7));
|
||||
if (!(byte & (1 << 7)))
|
||||
|
@ -43,11 +39,11 @@ struct LEB128 {
|
|||
++num_bytes;
|
||||
}
|
||||
|
||||
return true;
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename ValueType = ssize_t>
|
||||
static bool read_signed(DeprecatedInputStream& stream, ValueType& result)
|
||||
static ErrorOr<void> read_signed(AK::Stream& stream, ValueType& result)
|
||||
{
|
||||
// Note: We read into a u64 to simplify the parsing logic;
|
||||
// result is range checked into ValueType after parsing.
|
||||
|
@ -59,24 +55,20 @@ struct LEB128 {
|
|||
result = 0;
|
||||
|
||||
do {
|
||||
if (stream.unreliable_eof()) {
|
||||
stream.set_fatal_error();
|
||||
return false;
|
||||
}
|
||||
if (stream.is_eof())
|
||||
return Error::from_string_literal("Stream reached end-of-file while reading LEB128 value");
|
||||
|
||||
stream >> byte;
|
||||
if (stream.has_any_error())
|
||||
return false;
|
||||
byte = TRY(stream.read_value<u8>());
|
||||
|
||||
// note: 64 bit assumptions!
|
||||
u64 masked_byte = byte & ~(1 << 7);
|
||||
bool const shift_too_large_for_result = num_bytes * 7 >= 64;
|
||||
if (shift_too_large_for_result)
|
||||
return false;
|
||||
return Error::from_string_literal("Read value contains more bits than fit the chosen ValueType");
|
||||
|
||||
bool const shift_too_large_for_byte = (num_bytes * 7) == 63 && masked_byte != 0x00 && masked_byte != 0x7Fu;
|
||||
if (shift_too_large_for_byte)
|
||||
return false;
|
||||
return Error::from_string_literal("Read byte is too large to fit the chosen ValueType");
|
||||
|
||||
temp = (temp) | (masked_byte << (num_bytes * 7));
|
||||
++num_bytes;
|
||||
|
@ -90,12 +82,12 @@ struct LEB128 {
|
|||
// Now that we've accumulated into an i64, make sure it fits into result
|
||||
if constexpr (sizeof(ValueType) < sizeof(u64)) {
|
||||
if (temp > NumericLimits<ValueType>::max() || temp < NumericLimits<ValueType>::min())
|
||||
return false;
|
||||
return Error::from_string_literal("Temporary value does not fit the result type");
|
||||
}
|
||||
|
||||
result = static_cast<ValueType>(temp);
|
||||
|
||||
return true;
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/DeprecatedMemoryStream.h>
|
||||
#include <AK/LEB128.h>
|
||||
#include <AK/MemoryStream.h>
|
||||
#include <AK/NumericLimits.h>
|
||||
#include <LibTest/TestCase.h>
|
||||
|
||||
|
@ -14,48 +14,42 @@ TEST_CASE(single_byte)
|
|||
u32 output = {};
|
||||
i32 output_signed = {};
|
||||
u8 buf[] = { 0x00 };
|
||||
DeprecatedInputMemoryStream stream({ buf, sizeof(buf) });
|
||||
auto stream = MUST(FixedMemoryStream::construct(ReadonlyBytes { buf, sizeof(buf) }));
|
||||
|
||||
// less than/eq 0b0011_1111, signed == unsigned == raw byte
|
||||
for (u8 i = 0u; i <= 0x3F; ++i) {
|
||||
buf[0] = i;
|
||||
|
||||
stream.seek(0);
|
||||
EXPECT(LEB128::read_unsigned(stream, output));
|
||||
MUST(stream->seek(0));
|
||||
EXPECT(!LEB128::read_unsigned(*stream, output).is_error());
|
||||
EXPECT_EQ(output, i);
|
||||
EXPECT(!stream.handle_any_error());
|
||||
|
||||
stream.seek(0);
|
||||
EXPECT(LEB128::read_signed(stream, output_signed));
|
||||
MUST(stream->seek(0));
|
||||
EXPECT(!LEB128::read_signed(*stream, output_signed).is_error());
|
||||
EXPECT_EQ(output_signed, i);
|
||||
EXPECT(!stream.handle_any_error());
|
||||
}
|
||||
|
||||
// 0b0100_0000 to 0b0111_1111 unsigned == byte, signed = {{ 26'b(-1), 6'b(byte) }}
|
||||
for (u8 i = 0x40u; i < 0x80; ++i) {
|
||||
buf[0] = i;
|
||||
|
||||
stream.seek(0);
|
||||
EXPECT(LEB128::read_unsigned(stream, output));
|
||||
MUST(stream->seek(0));
|
||||
EXPECT(!LEB128::read_unsigned(*stream, output).is_error());
|
||||
EXPECT_EQ(output, i);
|
||||
EXPECT(!stream.handle_any_error());
|
||||
|
||||
stream.seek(0);
|
||||
EXPECT(LEB128::read_signed(stream, output_signed));
|
||||
MUST(stream->seek(0));
|
||||
EXPECT(!LEB128::read_signed(*stream, output_signed).is_error());
|
||||
EXPECT_EQ(output_signed, (i | (-1 & (~0x3F))));
|
||||
EXPECT(!stream.handle_any_error());
|
||||
}
|
||||
// MSB set, but input too short
|
||||
for (u16 i = 0x80; i <= 0xFF; ++i) {
|
||||
buf[0] = static_cast<u8>(i);
|
||||
|
||||
stream.seek(0);
|
||||
EXPECT(!LEB128::read_unsigned(stream, output));
|
||||
EXPECT(stream.handle_any_error());
|
||||
MUST(stream->seek(0));
|
||||
EXPECT(LEB128::read_unsigned(*stream, output).is_error());
|
||||
|
||||
stream.seek(0);
|
||||
EXPECT(!LEB128::read_signed(stream, output_signed));
|
||||
EXPECT(stream.handle_any_error());
|
||||
MUST(stream->seek(0));
|
||||
EXPECT(LEB128::read_signed(*stream, output_signed).is_error());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +58,7 @@ TEST_CASE(two_bytes)
|
|||
u32 output = {};
|
||||
i32 output_signed = {};
|
||||
u8 buf[] = { 0x00, 0x1 };
|
||||
DeprecatedInputMemoryStream stream({ buf, sizeof(buf) });
|
||||
auto stream = MUST(FixedMemoryStream::construct(ReadonlyBytes { buf, sizeof(buf) }));
|
||||
|
||||
// Only test with first byte expecting more, otherwise equivalent to single byte case
|
||||
for (u16 i = 0x80; i <= 0xFF; ++i) {
|
||||
|
@ -74,43 +68,37 @@ TEST_CASE(two_bytes)
|
|||
for (u8 j = 0u; j <= 0x3F; ++j) {
|
||||
buf[1] = j;
|
||||
|
||||
stream.seek(0);
|
||||
EXPECT(LEB128::read_unsigned(stream, output));
|
||||
MUST(stream->seek(0));
|
||||
EXPECT(!LEB128::read_unsigned(*stream, output).is_error());
|
||||
EXPECT_EQ(output, (static_cast<u32>(j) << 7) + (i & 0x7F));
|
||||
EXPECT(!stream.handle_any_error());
|
||||
|
||||
stream.seek(0);
|
||||
EXPECT(LEB128::read_signed(stream, output_signed));
|
||||
MUST(stream->seek(0));
|
||||
EXPECT(!LEB128::read_signed(*stream, output_signed).is_error());
|
||||
EXPECT_EQ(output_signed, (static_cast<i32>(j) << 7) + (i & 0x7F));
|
||||
EXPECT(!stream.handle_any_error());
|
||||
}
|
||||
|
||||
// 0b0100_0000 to 0b0111_1111: unsigned == (j << 7) + (7 MSB of i), signed == {{ 19'b(-1), 6'b(j), 7'b(i) }}
|
||||
for (u8 j = 0x40u; j < 0x80; ++j) {
|
||||
buf[1] = j;
|
||||
|
||||
stream.seek(0);
|
||||
EXPECT(LEB128::read_unsigned(stream, output));
|
||||
MUST(stream->seek(0));
|
||||
EXPECT(!LEB128::read_unsigned(*stream, output).is_error());
|
||||
EXPECT_EQ(output, (static_cast<u32>(j) << 7) + (i & 0x7F));
|
||||
EXPECT(!stream.handle_any_error());
|
||||
|
||||
stream.seek(0);
|
||||
EXPECT(LEB128::read_signed(stream, output_signed));
|
||||
MUST(stream->seek(0));
|
||||
EXPECT(!LEB128::read_signed(*stream, output_signed).is_error());
|
||||
EXPECT_EQ(output_signed, ((static_cast<i32>(j) << 7) + (i & 0x7F)) | (-1 & (~0x3FFF)));
|
||||
EXPECT(!stream.handle_any_error());
|
||||
}
|
||||
|
||||
// MSB set on last byte, but input too short
|
||||
for (u16 j = 0x80; j <= 0xFF; ++j) {
|
||||
buf[1] = static_cast<u8>(j);
|
||||
|
||||
stream.seek(0);
|
||||
EXPECT(!LEB128::read_unsigned(stream, output));
|
||||
EXPECT(stream.handle_any_error());
|
||||
MUST(stream->seek(0));
|
||||
EXPECT(LEB128::read_unsigned(*stream, output).is_error());
|
||||
|
||||
stream.seek(0);
|
||||
EXPECT(!LEB128::read_signed(stream, output_signed));
|
||||
EXPECT(stream.handle_any_error());
|
||||
MUST(stream->seek(0));
|
||||
EXPECT(LEB128::read_signed(*stream, output_signed).is_error());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -120,31 +108,27 @@ TEST_CASE(overflow_sizeof_output_unsigned)
|
|||
u8 u32_max_plus_one[] = { 0x80, 0x80, 0x80, 0x80, 0x10 };
|
||||
{
|
||||
u32 out = 0;
|
||||
DeprecatedInputMemoryStream stream({ u32_max_plus_one, sizeof(u32_max_plus_one) });
|
||||
EXPECT(!LEB128::read_unsigned(stream, out));
|
||||
auto stream = MUST(FixedMemoryStream::construct(ReadonlyBytes { u32_max_plus_one, sizeof(u32_max_plus_one) }));
|
||||
EXPECT(LEB128::read_unsigned(*stream, out).is_error());
|
||||
EXPECT_EQ(out, 0u);
|
||||
EXPECT(!stream.handle_any_error());
|
||||
|
||||
u64 out64 = 0;
|
||||
stream.seek(0);
|
||||
EXPECT(LEB128::read_unsigned(stream, out64));
|
||||
MUST(stream->seek(0));
|
||||
EXPECT(!LEB128::read_unsigned(*stream, out64).is_error());
|
||||
EXPECT_EQ(out64, static_cast<u64>(NumericLimits<u32>::max()) + 1);
|
||||
EXPECT(!stream.handle_any_error());
|
||||
}
|
||||
|
||||
u8 u32_max[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0x0F };
|
||||
{
|
||||
u32 out = 0;
|
||||
DeprecatedInputMemoryStream stream({ u32_max, sizeof(u32_max) });
|
||||
EXPECT(LEB128::read_unsigned(stream, out));
|
||||
auto stream = MUST(FixedMemoryStream::construct(ReadonlyBytes { u32_max, sizeof(u32_max) }));
|
||||
EXPECT(!LEB128::read_unsigned(*stream, out).is_error());
|
||||
EXPECT_EQ(out, NumericLimits<u32>::max());
|
||||
EXPECT(!stream.handle_any_error());
|
||||
|
||||
u64 out64 = 0;
|
||||
stream.seek(0);
|
||||
EXPECT(LEB128::read_unsigned(stream, out64));
|
||||
MUST(stream->seek(0));
|
||||
EXPECT(!LEB128::read_unsigned(*stream, out64).is_error());
|
||||
EXPECT_EQ(out64, NumericLimits<u32>::max());
|
||||
EXPECT(!stream.handle_any_error());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,60 +137,52 @@ TEST_CASE(overflow_sizeof_output_signed)
|
|||
u8 i32_max_plus_one[] = { 0x80, 0x80, 0x80, 0x80, 0x08 };
|
||||
{
|
||||
i32 out = 0;
|
||||
DeprecatedInputMemoryStream stream({ i32_max_plus_one, sizeof(i32_max_plus_one) });
|
||||
EXPECT(!LEB128::read_signed(stream, out));
|
||||
auto stream = MUST(FixedMemoryStream::construct(ReadonlyBytes { i32_max_plus_one, sizeof(i32_max_plus_one) }));
|
||||
EXPECT(LEB128::read_signed(*stream, out).is_error());
|
||||
EXPECT_EQ(out, 0);
|
||||
EXPECT(!stream.handle_any_error());
|
||||
|
||||
i64 out64 = 0;
|
||||
stream.seek(0);
|
||||
EXPECT(LEB128::read_signed(stream, out64));
|
||||
MUST(stream->seek(0));
|
||||
EXPECT(!LEB128::read_signed(*stream, out64).is_error());
|
||||
EXPECT_EQ(out64, static_cast<i64>(NumericLimits<i32>::max()) + 1);
|
||||
EXPECT(!stream.handle_any_error());
|
||||
}
|
||||
|
||||
u8 i32_max[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0x07 };
|
||||
{
|
||||
i32 out = 0;
|
||||
DeprecatedInputMemoryStream stream({ i32_max, sizeof(i32_max) });
|
||||
EXPECT(LEB128::read_signed(stream, out));
|
||||
auto stream = MUST(FixedMemoryStream::construct(ReadonlyBytes { i32_max, sizeof(i32_max) }));
|
||||
EXPECT(!LEB128::read_signed(*stream, out).is_error());
|
||||
EXPECT_EQ(out, NumericLimits<i32>::max());
|
||||
EXPECT(!stream.handle_any_error());
|
||||
|
||||
i64 out64 = 0;
|
||||
stream.seek(0);
|
||||
EXPECT(LEB128::read_signed(stream, out64));
|
||||
MUST(stream->seek(0));
|
||||
EXPECT(!LEB128::read_signed(*stream, out64).is_error());
|
||||
EXPECT_EQ(out64, NumericLimits<i32>::max());
|
||||
EXPECT(!stream.handle_any_error());
|
||||
}
|
||||
|
||||
u8 i32_min_minus_one[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0x77 };
|
||||
{
|
||||
i32 out = 0;
|
||||
DeprecatedInputMemoryStream stream({ i32_min_minus_one, sizeof(i32_min_minus_one) });
|
||||
EXPECT(!LEB128::read_signed(stream, out));
|
||||
auto stream = MUST(FixedMemoryStream::construct(ReadonlyBytes { i32_min_minus_one, sizeof(i32_min_minus_one) }));
|
||||
EXPECT(LEB128::read_signed(*stream, out).is_error());
|
||||
EXPECT_EQ(out, 0);
|
||||
EXPECT(!stream.handle_any_error());
|
||||
|
||||
i64 out64 = 0;
|
||||
stream.seek(0);
|
||||
EXPECT(LEB128::read_signed(stream, out64));
|
||||
MUST(stream->seek(0));
|
||||
EXPECT(!LEB128::read_signed(*stream, out64).is_error());
|
||||
EXPECT_EQ(out64, static_cast<i64>(NumericLimits<i32>::min()) - 1);
|
||||
EXPECT(!stream.handle_any_error());
|
||||
}
|
||||
|
||||
u8 i32_min[] = { 0x80, 0x80, 0x80, 0x80, 0x78 };
|
||||
{
|
||||
i32 out = 0;
|
||||
DeprecatedInputMemoryStream stream({ i32_min, sizeof(i32_min) });
|
||||
EXPECT(LEB128::read_signed(stream, out));
|
||||
auto stream = MUST(FixedMemoryStream::construct(ReadonlyBytes { i32_min, sizeof(i32_min) }));
|
||||
EXPECT(!LEB128::read_signed(*stream, out).is_error());
|
||||
EXPECT_EQ(out, NumericLimits<i32>::min());
|
||||
EXPECT(!stream.handle_any_error());
|
||||
|
||||
i64 out64 = 0;
|
||||
stream.seek(0);
|
||||
EXPECT(LEB128::read_signed(stream, out64));
|
||||
MUST(stream->seek(0));
|
||||
EXPECT(!LEB128::read_signed(*stream, out64).is_error());
|
||||
EXPECT_EQ(out64, NumericLimits<i32>::min());
|
||||
EXPECT(!stream.handle_any_error());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,18 +23,17 @@ ErrorOr<void> AbbreviationsMap::populate_map()
|
|||
{
|
||||
auto abbreviation_stream = TRY(FixedMemoryStream::construct(m_dwarf_info.abbreviation_data()));
|
||||
TRY(abbreviation_stream->discard(m_offset));
|
||||
Core::Stream::WrapInAKInputStream wrapped_abbreviation_stream { *abbreviation_stream };
|
||||
|
||||
while (!abbreviation_stream->is_eof()) {
|
||||
size_t abbreviation_code = 0;
|
||||
LEB128::read_unsigned(wrapped_abbreviation_stream, abbreviation_code);
|
||||
TRY(LEB128::read_unsigned(*abbreviation_stream, abbreviation_code));
|
||||
// An abbreviation code of 0 marks the end of the
|
||||
// abbreviations for a given compilation unit
|
||||
if (abbreviation_code == 0)
|
||||
break;
|
||||
|
||||
size_t tag {};
|
||||
LEB128::read_unsigned(wrapped_abbreviation_stream, tag);
|
||||
TRY(LEB128::read_unsigned(*abbreviation_stream, tag));
|
||||
|
||||
auto has_children = TRY(abbreviation_stream->read_value<u8>());
|
||||
|
||||
|
@ -46,15 +45,15 @@ ErrorOr<void> AbbreviationsMap::populate_map()
|
|||
do {
|
||||
size_t attribute_value = 0;
|
||||
size_t form_value = 0;
|
||||
LEB128::read_unsigned(wrapped_abbreviation_stream, attribute_value);
|
||||
LEB128::read_unsigned(wrapped_abbreviation_stream, form_value);
|
||||
TRY(LEB128::read_unsigned(*abbreviation_stream, attribute_value));
|
||||
TRY(LEB128::read_unsigned(*abbreviation_stream, form_value));
|
||||
|
||||
current_attribute_specification.attribute = static_cast<Attribute>(attribute_value);
|
||||
current_attribute_specification.form = static_cast<AttributeDataForm>(form_value);
|
||||
|
||||
if (current_attribute_specification.form == AttributeDataForm::ImplicitConst) {
|
||||
ssize_t data_value;
|
||||
LEB128::read_signed(wrapped_abbreviation_stream, data_value);
|
||||
TRY(LEB128::read_signed(*abbreviation_stream, data_value));
|
||||
current_attribute_specification.value = data_value;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,6 @@ ErrorOr<void> AddressRangesV5::for_each_range(Function<void(Range)> callback)
|
|||
{
|
||||
// Dwarf version 5, section 2.17.3 "Non-Contiguous Address Ranges"
|
||||
|
||||
Core::Stream::WrapInAKInputStream wrapped_range_lists_stream { *m_range_lists_stream };
|
||||
|
||||
Optional<FlatPtr> current_base_address;
|
||||
while (!m_range_lists_stream->is_eof()) {
|
||||
auto entry_type = TRY(m_range_lists_stream->read_value<u8>());
|
||||
|
@ -33,7 +31,7 @@ ErrorOr<void> AddressRangesV5::for_each_range(Function<void(Range)> callback)
|
|||
}
|
||||
case RangeListEntryType::BaseAddressX: {
|
||||
FlatPtr index;
|
||||
LEB128::read_unsigned(wrapped_range_lists_stream, index);
|
||||
TRY(LEB128::read_unsigned(*m_range_lists_stream, index));
|
||||
current_base_address = TRY(m_compilation_unit.get_address(index));
|
||||
break;
|
||||
}
|
||||
|
@ -47,29 +45,29 @@ ErrorOr<void> AddressRangesV5::for_each_range(Function<void(Range)> callback)
|
|||
return Error::from_string_literal("Expected base_address for rangelist");
|
||||
|
||||
size_t start_offset, end_offset;
|
||||
LEB128::read_unsigned(wrapped_range_lists_stream, start_offset);
|
||||
LEB128::read_unsigned(wrapped_range_lists_stream, end_offset);
|
||||
TRY(LEB128::read_unsigned(*m_range_lists_stream, start_offset));
|
||||
TRY(LEB128::read_unsigned(*m_range_lists_stream, end_offset));
|
||||
callback(Range { start_offset + *base_address, end_offset + *base_address });
|
||||
break;
|
||||
}
|
||||
case RangeListEntryType::StartLength: {
|
||||
auto start = TRY(m_range_lists_stream->read_value<FlatPtr>());
|
||||
size_t length;
|
||||
LEB128::read_unsigned(wrapped_range_lists_stream, length);
|
||||
TRY(LEB128::read_unsigned(*m_range_lists_stream, length));
|
||||
callback(Range { start, start + length });
|
||||
break;
|
||||
}
|
||||
case RangeListEntryType::StartXEndX: {
|
||||
size_t start, end;
|
||||
LEB128::read_unsigned(wrapped_range_lists_stream, start);
|
||||
LEB128::read_unsigned(wrapped_range_lists_stream, end);
|
||||
TRY(LEB128::read_unsigned(*m_range_lists_stream, start));
|
||||
TRY(LEB128::read_unsigned(*m_range_lists_stream, end));
|
||||
callback(Range { TRY(m_compilation_unit.get_address(start)), TRY(m_compilation_unit.get_address(end)) });
|
||||
break;
|
||||
}
|
||||
case RangeListEntryType::StartXLength: {
|
||||
size_t start, length;
|
||||
LEB128::read_unsigned(wrapped_range_lists_stream, start);
|
||||
LEB128::read_unsigned(wrapped_range_lists_stream, length);
|
||||
TRY(LEB128::read_unsigned(*m_range_lists_stream, start));
|
||||
TRY(LEB128::read_unsigned(*m_range_lists_stream, length));
|
||||
auto start_addr = TRY(m_compilation_unit.get_address(start));
|
||||
callback(Range { start_addr, start_addr + length });
|
||||
break;
|
||||
|
|
|
@ -26,8 +26,7 @@ ErrorOr<void> DIE::rehydrate_from(u32 offset, Optional<u32> parent_offset)
|
|||
auto stream = TRY(FixedMemoryStream::construct(m_compilation_unit.dwarf_info().debug_info_data()));
|
||||
// Note: We can't just slice away from the input data here, since get_attribute_value will try to recover the original offset using seek().
|
||||
TRY(stream->seek(m_offset));
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { *stream };
|
||||
LEB128::read_unsigned(wrapped_stream, m_abbreviation_code);
|
||||
TRY(LEB128::read_unsigned(*stream, m_abbreviation_code));
|
||||
m_data_offset = TRY(stream->tell());
|
||||
|
||||
if (m_abbreviation_code == 0) {
|
||||
|
|
|
@ -121,18 +121,14 @@ ErrorOr<AttributeValue> DwarfInfo::get_attribute_value(AttributeDataForm form, s
|
|||
}
|
||||
case AttributeDataForm::SData: {
|
||||
i64 data;
|
||||
Core::Stream::WrapInAKInputStream wrapped_debug_info_stream { debug_info_stream };
|
||||
LEB128::read_signed(wrapped_debug_info_stream, data);
|
||||
VERIFY(!wrapped_debug_info_stream.has_any_error());
|
||||
TRY(LEB128::read_signed(debug_info_stream, data));
|
||||
value.m_type = AttributeValue::Type::SignedNumber;
|
||||
value.m_data.as_signed = data;
|
||||
break;
|
||||
}
|
||||
case AttributeDataForm::UData: {
|
||||
u64 data;
|
||||
Core::Stream::WrapInAKInputStream wrapped_debug_info_stream { debug_info_stream };
|
||||
LEB128::read_unsigned(wrapped_debug_info_stream, data);
|
||||
VERIFY(!wrapped_debug_info_stream.has_any_error());
|
||||
TRY(LEB128::read_unsigned(debug_info_stream, data));
|
||||
value.m_type = AttributeValue::Type::UnsignedNumber;
|
||||
value.m_data.as_unsigned = data;
|
||||
break;
|
||||
|
@ -174,9 +170,7 @@ ErrorOr<AttributeValue> DwarfInfo::get_attribute_value(AttributeDataForm form, s
|
|||
}
|
||||
case AttributeDataForm::ExprLoc: {
|
||||
size_t length;
|
||||
Core::Stream::WrapInAKInputStream wrapped_debug_info_stream { debug_info_stream };
|
||||
LEB128::read_unsigned(wrapped_debug_info_stream, length);
|
||||
VERIFY(!wrapped_debug_info_stream.has_any_error());
|
||||
TRY(LEB128::read_unsigned(debug_info_stream, length));
|
||||
value.m_type = AttributeValue::Type::DwarfExpression;
|
||||
TRY(assign_raw_bytes_value(length));
|
||||
break;
|
||||
|
@ -209,9 +203,7 @@ ErrorOr<AttributeValue> DwarfInfo::get_attribute_value(AttributeDataForm form, s
|
|||
case AttributeDataForm::Block: {
|
||||
value.m_type = AttributeValue::Type::RawBytes;
|
||||
size_t length;
|
||||
Core::Stream::WrapInAKInputStream wrapped_debug_info_stream { debug_info_stream };
|
||||
LEB128::read_unsigned(wrapped_debug_info_stream, length);
|
||||
VERIFY(!wrapped_debug_info_stream.has_any_error());
|
||||
TRY(LEB128::read_unsigned(debug_info_stream, length));
|
||||
TRY(assign_raw_bytes_value(length));
|
||||
break;
|
||||
}
|
||||
|
@ -249,9 +241,7 @@ ErrorOr<AttributeValue> DwarfInfo::get_attribute_value(AttributeDataForm form, s
|
|||
}
|
||||
case AttributeDataForm::StrX: {
|
||||
size_t index;
|
||||
Core::Stream::WrapInAKInputStream wrapped_debug_info_stream { debug_info_stream };
|
||||
LEB128::read_unsigned(wrapped_debug_info_stream, index);
|
||||
VERIFY(!wrapped_debug_info_stream.has_any_error());
|
||||
TRY(LEB128::read_unsigned(debug_info_stream, index));
|
||||
value.m_type = AttributeValue::Type::String;
|
||||
value.m_data.as_unsigned = index;
|
||||
break;
|
||||
|
@ -276,18 +266,14 @@ ErrorOr<AttributeValue> DwarfInfo::get_attribute_value(AttributeDataForm form, s
|
|||
}
|
||||
case AttributeDataForm::AddrX: {
|
||||
size_t index;
|
||||
Core::Stream::WrapInAKInputStream wrapped_debug_info_stream { debug_info_stream };
|
||||
LEB128::read_unsigned(wrapped_debug_info_stream, index);
|
||||
VERIFY(!wrapped_debug_info_stream.has_any_error());
|
||||
TRY(LEB128::read_unsigned(debug_info_stream, index));
|
||||
value.m_type = AttributeValue::Type::Address;
|
||||
value.m_data.as_unsigned = index;
|
||||
break;
|
||||
}
|
||||
case AttributeDataForm::RngListX: {
|
||||
size_t index;
|
||||
Core::Stream::WrapInAKInputStream wrapped_debug_info_stream { debug_info_stream };
|
||||
LEB128::read_unsigned(wrapped_debug_info_stream, index);
|
||||
VERIFY(!wrapped_debug_info_stream.has_any_error());
|
||||
TRY(LEB128::read_unsigned(debug_info_stream, index));
|
||||
value.m_type = AttributeValue::Type::UnsignedNumber;
|
||||
value.m_data.as_unsigned = index;
|
||||
break;
|
||||
|
|
|
@ -38,8 +38,6 @@ ErrorOr<void> LineProgram::parse_unit_header()
|
|||
|
||||
ErrorOr<void> LineProgram::parse_path_entries(Function<void(PathEntry& entry)> callback, PathListType list_type)
|
||||
{
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { m_stream };
|
||||
|
||||
if (m_unit_header.version() >= 5) {
|
||||
auto path_entry_format_count = TRY(m_stream.read_value<u8>());
|
||||
|
||||
|
@ -47,16 +45,16 @@ ErrorOr<void> LineProgram::parse_path_entries(Function<void(PathEntry& entry)> c
|
|||
|
||||
for (u8 i = 0; i < path_entry_format_count; i++) {
|
||||
UnderlyingType<ContentType> content_type;
|
||||
LEB128::read_unsigned(wrapped_stream, content_type);
|
||||
TRY(LEB128::read_unsigned(m_stream, content_type));
|
||||
|
||||
UnderlyingType<AttributeDataForm> data_form;
|
||||
LEB128::read_unsigned(wrapped_stream, data_form);
|
||||
TRY(LEB128::read_unsigned(m_stream, data_form));
|
||||
|
||||
format_descriptions.empend(static_cast<ContentType>(content_type), static_cast<AttributeDataForm>(data_form));
|
||||
}
|
||||
|
||||
size_t paths_count = 0;
|
||||
LEB128::read_unsigned(wrapped_stream, paths_count);
|
||||
TRY(LEB128::read_unsigned(m_stream, paths_count));
|
||||
|
||||
for (size_t i = 0; i < paths_count; i++) {
|
||||
PathEntry entry;
|
||||
|
@ -88,10 +86,10 @@ ErrorOr<void> LineProgram::parse_path_entries(Function<void(PathEntry& entry)> c
|
|||
entry.path = path;
|
||||
if (list_type == PathListType::Filenames) {
|
||||
size_t directory_index = 0;
|
||||
LEB128::read_unsigned(wrapped_stream, directory_index);
|
||||
TRY(LEB128::read_unsigned(m_stream, directory_index));
|
||||
size_t _unused = 0;
|
||||
LEB128::read_unsigned(wrapped_stream, _unused); // skip modification time
|
||||
LEB128::read_unsigned(wrapped_stream, _unused); // skip file size
|
||||
TRY(LEB128::read_unsigned(m_stream, _unused)); // skip modification time
|
||||
TRY(LEB128::read_unsigned(m_stream, _unused)); // skip file size
|
||||
entry.directory_index = directory_index;
|
||||
dbgln_if(DWARF_DEBUG, "file: {}, directory index: {}", path, directory_index);
|
||||
}
|
||||
|
@ -99,7 +97,6 @@ ErrorOr<void> LineProgram::parse_path_entries(Function<void(PathEntry& entry)> c
|
|||
}
|
||||
}
|
||||
|
||||
VERIFY(!wrapped_stream.has_any_error());
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -160,11 +157,8 @@ void LineProgram::reset_registers()
|
|||
|
||||
ErrorOr<void> LineProgram::handle_extended_opcode()
|
||||
{
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { m_stream };
|
||||
|
||||
size_t length = 0;
|
||||
LEB128::read_unsigned(wrapped_stream, length);
|
||||
TRY(wrapped_stream.try_handle_any_error());
|
||||
TRY(LEB128::read_unsigned(m_stream, length));
|
||||
|
||||
auto sub_opcode = TRY(m_stream.read_value<u8>());
|
||||
|
||||
|
@ -183,8 +177,7 @@ ErrorOr<void> LineProgram::handle_extended_opcode()
|
|||
case ExtendedOpcodes::SetDiscriminator: {
|
||||
dbgln_if(DWARF_DEBUG, "SetDiscriminator");
|
||||
size_t discriminator;
|
||||
LEB128::read_unsigned(wrapped_stream, discriminator);
|
||||
TRY(wrapped_stream.try_handle_any_error());
|
||||
TRY(LEB128::read_unsigned(m_stream, discriminator));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -196,8 +189,6 @@ ErrorOr<void> LineProgram::handle_extended_opcode()
|
|||
}
|
||||
ErrorOr<void> LineProgram::handle_standard_opcode(u8 opcode)
|
||||
{
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { m_stream };
|
||||
|
||||
switch (opcode) {
|
||||
case StandardOpcodes::Copy: {
|
||||
append_to_line_info();
|
||||
|
@ -205,8 +196,7 @@ ErrorOr<void> LineProgram::handle_standard_opcode(u8 opcode)
|
|||
}
|
||||
case StandardOpcodes::AdvancePc: {
|
||||
size_t operand = 0;
|
||||
LEB128::read_unsigned(wrapped_stream, operand);
|
||||
TRY(wrapped_stream.try_handle_any_error());
|
||||
TRY(LEB128::read_unsigned(m_stream, operand));
|
||||
size_t delta = operand * m_unit_header.min_instruction_length();
|
||||
dbgln_if(DWARF_DEBUG, "AdvancePC by: {} to: {:p}", delta, m_address + delta);
|
||||
m_address += delta;
|
||||
|
@ -214,8 +204,7 @@ ErrorOr<void> LineProgram::handle_standard_opcode(u8 opcode)
|
|||
}
|
||||
case StandardOpcodes::SetFile: {
|
||||
size_t new_file_index = 0;
|
||||
LEB128::read_unsigned(wrapped_stream, new_file_index);
|
||||
TRY(wrapped_stream.try_handle_any_error());
|
||||
TRY(LEB128::read_unsigned(m_stream, new_file_index));
|
||||
dbgln_if(DWARF_DEBUG, "SetFile: new file index: {}", new_file_index);
|
||||
m_file_index = new_file_index;
|
||||
break;
|
||||
|
@ -224,15 +213,13 @@ ErrorOr<void> LineProgram::handle_standard_opcode(u8 opcode)
|
|||
// not implemented
|
||||
dbgln_if(DWARF_DEBUG, "SetColumn");
|
||||
size_t new_column;
|
||||
LEB128::read_unsigned(wrapped_stream, new_column);
|
||||
TRY(wrapped_stream.try_handle_any_error());
|
||||
TRY(LEB128::read_unsigned(m_stream, new_column));
|
||||
|
||||
break;
|
||||
}
|
||||
case StandardOpcodes::AdvanceLine: {
|
||||
ssize_t line_delta;
|
||||
LEB128::read_signed(wrapped_stream, line_delta);
|
||||
TRY(wrapped_stream.try_handle_any_error());
|
||||
TRY(LEB128::read_signed(m_stream, line_delta));
|
||||
VERIFY(line_delta >= 0 || m_line >= (size_t)(-line_delta));
|
||||
m_line += line_delta;
|
||||
dbgln_if(DWARF_DEBUG, "AdvanceLine: {}", m_line);
|
||||
|
@ -253,8 +240,7 @@ ErrorOr<void> LineProgram::handle_standard_opcode(u8 opcode)
|
|||
}
|
||||
case StandardOpcodes::SetIsa: {
|
||||
size_t isa;
|
||||
LEB128::read_unsigned(wrapped_stream, isa);
|
||||
TRY(wrapped_stream.try_handle_any_error());
|
||||
TRY(LEB128::read_unsigned(m_stream, isa));
|
||||
dbgln_if(DWARF_DEBUG, "SetIsa: {}", isa);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -27,8 +27,7 @@ static auto parse_vector(AK::Stream& stream)
|
|||
if constexpr (requires { T::parse(stream); }) {
|
||||
using ResultT = typename decltype(T::parse(stream))::ValueType;
|
||||
size_t count;
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { stream };
|
||||
if (!LEB128::read_unsigned(wrapped_stream, count))
|
||||
if (LEB128::read_unsigned(stream, count).is_error())
|
||||
return ParseResult<Vector<ResultT>> { with_eof_check(stream, ParseError::ExpectedSize) };
|
||||
|
||||
Vector<ResultT> entries;
|
||||
|
@ -41,22 +40,19 @@ static auto parse_vector(AK::Stream& stream)
|
|||
return ParseResult<Vector<ResultT>> { move(entries) };
|
||||
} else {
|
||||
size_t count;
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { stream };
|
||||
if (!LEB128::read_unsigned(wrapped_stream, count))
|
||||
if (LEB128::read_unsigned(stream, count).is_error())
|
||||
return ParseResult<Vector<T>> { with_eof_check(stream, ParseError::ExpectedSize) };
|
||||
|
||||
Vector<T> entries;
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
if constexpr (IsSame<T, size_t>) {
|
||||
size_t value;
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { stream };
|
||||
if (!LEB128::read_unsigned(wrapped_stream, value))
|
||||
if (LEB128::read_unsigned(stream, value).is_error())
|
||||
return ParseResult<Vector<T>> { with_eof_check(stream, ParseError::ExpectedSize) };
|
||||
entries.append(value);
|
||||
} else if constexpr (IsSame<T, ssize_t>) {
|
||||
ssize_t value;
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { stream };
|
||||
if (!LEB128::read_signed(wrapped_stream, value))
|
||||
if (LEB128::read_signed(stream, value).is_error())
|
||||
return ParseResult<Vector<T>> { with_eof_check(stream, ParseError::ExpectedSize) };
|
||||
entries.append(value);
|
||||
} else if constexpr (IsSame<T, u8>) {
|
||||
|
@ -191,15 +187,13 @@ ParseResult<Limits> Limits::parse(AK::Stream& stream)
|
|||
return with_eof_check(stream, ParseError::InvalidTag);
|
||||
|
||||
size_t min;
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { stream };
|
||||
if (!LEB128::read_unsigned(wrapped_stream, min))
|
||||
if (LEB128::read_unsigned(stream, min).is_error())
|
||||
return with_eof_check(stream, ParseError::ExpectedSize);
|
||||
|
||||
Optional<u32> max;
|
||||
if (flag) {
|
||||
size_t value;
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { stream };
|
||||
if (!LEB128::read_unsigned(wrapped_stream, value))
|
||||
if (LEB128::read_unsigned(stream, value).is_error())
|
||||
return with_eof_check(stream, ParseError::ExpectedSize);
|
||||
max = value;
|
||||
}
|
||||
|
@ -270,8 +264,7 @@ ParseResult<BlockType> BlockType::parse(AK::Stream& stream)
|
|||
new_stream.unread({ &kind, 1 });
|
||||
|
||||
ssize_t index_value;
|
||||
Core::Stream::WrapInAKInputStream wrapped_new_stream { new_stream };
|
||||
if (!LEB128::read_signed(wrapped_new_stream, index_value))
|
||||
if (LEB128::read_signed(new_stream, index_value).is_error())
|
||||
return with_eof_check(stream, ParseError::ExpectedIndex);
|
||||
|
||||
if (index_value < 0) {
|
||||
|
@ -414,15 +407,13 @@ ParseResult<Vector<Instruction>> Instruction::parse(AK::Stream& stream, Instruct
|
|||
case Instructions::i64_store8.value():
|
||||
case Instructions::i64_store16.value():
|
||||
case Instructions::i64_store32.value(): {
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { stream };
|
||||
|
||||
// op (align offset)
|
||||
size_t align;
|
||||
if (!LEB128::read_unsigned(wrapped_stream, align))
|
||||
if (LEB128::read_unsigned(stream, align).is_error())
|
||||
return with_eof_check(stream, ParseError::InvalidInput);
|
||||
|
||||
size_t offset;
|
||||
if (!LEB128::read_unsigned(wrapped_stream, offset))
|
||||
if (LEB128::read_unsigned(stream, offset).is_error())
|
||||
return with_eof_check(stream, ParseError::InvalidInput);
|
||||
|
||||
resulting_instructions.append(Instruction { opcode, MemoryArgument { static_cast<u32>(align), static_cast<u32>(offset) } });
|
||||
|
@ -466,8 +457,7 @@ ParseResult<Vector<Instruction>> Instruction::parse(AK::Stream& stream, Instruct
|
|||
}
|
||||
case Instructions::i32_const.value(): {
|
||||
i32 value;
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { stream };
|
||||
if (!LEB128::read_signed(wrapped_stream, value))
|
||||
if (LEB128::read_signed(stream, value).is_error())
|
||||
return with_eof_check(stream, ParseError::ExpectedSignedImmediate);
|
||||
|
||||
resulting_instructions.append(Instruction { opcode, value });
|
||||
|
@ -476,8 +466,7 @@ ParseResult<Vector<Instruction>> Instruction::parse(AK::Stream& stream, Instruct
|
|||
case Instructions::i64_const.value(): {
|
||||
// op literal
|
||||
i64 value;
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { stream };
|
||||
if (!LEB128::read_signed(wrapped_stream, value))
|
||||
if (LEB128::read_signed(stream, value).is_error())
|
||||
return with_eof_check(stream, ParseError::ExpectedSignedImmediate);
|
||||
|
||||
resulting_instructions.append(Instruction { opcode, value });
|
||||
|
@ -677,8 +666,7 @@ ParseResult<Vector<Instruction>> Instruction::parse(AK::Stream& stream, Instruct
|
|||
case 0xfc: {
|
||||
// These are multibyte instructions.
|
||||
u32 selector;
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { stream };
|
||||
if (!LEB128::read_unsigned(wrapped_stream, selector))
|
||||
if (LEB128::read_unsigned(stream, selector).is_error())
|
||||
return with_eof_check(stream, ParseError::InvalidInput);
|
||||
switch (selector) {
|
||||
case Instructions::i32_trunc_sat_f32_s_second:
|
||||
|
@ -955,8 +943,7 @@ ParseResult<ExportSection::Export> ExportSection::Export::parse(AK::Stream& stre
|
|||
auto tag = tag_or_error.release_value();
|
||||
|
||||
size_t index;
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { stream };
|
||||
if (!LEB128::read_unsigned(wrapped_stream, index))
|
||||
if (LEB128::read_unsigned(stream, index).is_error())
|
||||
return with_eof_check(stream, ParseError::ExpectedIndex);
|
||||
|
||||
switch (tag) {
|
||||
|
@ -1152,8 +1139,7 @@ ParseResult<Locals> Locals::parse(AK::Stream& stream)
|
|||
{
|
||||
ScopeLogger<WASM_BINPARSER_DEBUG> logger("Locals"sv);
|
||||
size_t count;
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { stream };
|
||||
if (!LEB128::read_unsigned(wrapped_stream, count))
|
||||
if (LEB128::read_unsigned(stream, count).is_error())
|
||||
return with_eof_check(stream, ParseError::InvalidSize);
|
||||
|
||||
if (count > Constants::max_allowed_function_locals_per_type)
|
||||
|
@ -1182,8 +1168,7 @@ ParseResult<CodeSection::Code> CodeSection::Code::parse(AK::Stream& stream)
|
|||
{
|
||||
ScopeLogger<WASM_BINPARSER_DEBUG> logger("Code"sv);
|
||||
size_t size;
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { stream };
|
||||
if (!LEB128::read_unsigned(wrapped_stream, size))
|
||||
if (LEB128::read_unsigned(stream, size).is_error())
|
||||
return with_eof_check(stream, ParseError::InvalidSize);
|
||||
|
||||
auto constrained_stream = ConstrainedStream { stream, size };
|
||||
|
@ -1260,8 +1245,7 @@ ParseResult<DataCountSection> DataCountSection::parse([[maybe_unused]] AK::Strea
|
|||
{
|
||||
ScopeLogger<WASM_BINPARSER_DEBUG> logger("DataCountSection"sv);
|
||||
u32 value;
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { stream };
|
||||
if (!LEB128::read_unsigned(wrapped_stream, value)) {
|
||||
if (LEB128::read_unsigned(stream, value).is_error()) {
|
||||
if (stream.is_eof()) {
|
||||
// The section simply didn't contain anything.
|
||||
return DataCountSection { {} };
|
||||
|
@ -1297,8 +1281,7 @@ ParseResult<Module> Module::parse(AK::Stream& stream)
|
|||
auto section_id = section_id_or_error.release_value();
|
||||
|
||||
size_t section_size;
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { stream };
|
||||
if (!LEB128::read_unsigned(wrapped_stream, section_size))
|
||||
if (LEB128::read_unsigned(stream, section_size).is_error())
|
||||
return with_eof_check(stream, ParseError::ExpectedSize);
|
||||
|
||||
auto section_stream = ConstrainedStream { stream, section_size };
|
||||
|
|
|
@ -66,8 +66,7 @@ struct GenericIndexParser {
|
|||
static ParseResult<T> parse(AK::Stream& stream)
|
||||
{
|
||||
size_t value;
|
||||
Core::Stream::WrapInAKInputStream wrapped_stream { stream };
|
||||
if (!LEB128::read_unsigned(wrapped_stream, value))
|
||||
if (LEB128::read_unsigned(stream, value).is_error())
|
||||
return with_eof_check(stream, ParseError::ExpectedIndex);
|
||||
return T { value };
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue