AK: Use reference algorithms for LEB128 parsing

This fixes a bug in signed LEB128 parsing (sign extension stage)
which would sometimes cause debug info to look very strange.
This commit is contained in:
Andreas Kling 2020-11-08 22:36:31 +01:00
parent a2cfb7eb94
commit 81b7c072ed
Notes: sideshowbarker 2024-07-19 01:29:44 +09:00

View file

@ -96,9 +96,9 @@ public:
bool read_LEB128_unsigned(size_t& result) bool read_LEB128_unsigned(size_t& result)
{ {
const auto backup = m_offset; const auto backup = m_offset;
result = 0; result = 0;
size_t num_bytes = 0;
size_t shift = 0;
while (true) { while (true) {
if (eof()) { if (eof()) {
m_offset = backup; m_offset = backup;
@ -106,12 +106,11 @@ public:
return false; return false;
} }
const u8 byte = m_bytes[m_offset]; const u8 byte = m_bytes[m_offset++];
result = (result) | (static_cast<size_t>(byte & ~(1 << 7)) << (num_bytes * 7)); result |= (byte & 0x7f) << shift;
++m_offset; if (byte & 0x80)
if (!(byte & (1 << 7)))
break; break;
++num_bytes; shift += 7;
} }
return true; return true;
@ -122,9 +121,11 @@ public:
const auto backup = m_offset; const auto backup = m_offset;
result = 0; result = 0;
size_t num_bytes = 0; size_t shift = 0;
u8 byte = 0; u8 byte = 0;
size_t size = sizeof(ssize_t) * 8;
do { do {
if (eof()) { if (eof()) {
m_offset = backup; m_offset = backup;
@ -132,15 +133,13 @@ public:
return false; return false;
} }
byte = m_bytes[m_offset]; byte = m_bytes[m_offset++];
result = (result) | (static_cast<size_t>(byte & ~(1 << 7)) << (num_bytes * 7)); result |= (byte & 0x7f) << shift;
++m_offset;
++num_bytes;
} while (byte & (1 << 7)); } while (byte & (1 << 7));
if (num_bytes * 7 < sizeof(size_t) * 4 && (byte & 0x40)) { if (shift < size && (byte & 0x40)) {
// sign extend // sign extend
result |= ((size_t)(-1) << (num_bytes * 7)); result |= (0xffffffffu << shift);
} }
return true; return true;