Skip to content

Commit 95f950d

Browse files
committed
Fix: leb128: sign bit must be extended
1 parent 56d85ea commit 95f950d

File tree

2 files changed

+28
-15
lines changed

2 files changed

+28
-15
lines changed

source/binary/leb128.d

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
module binary.leb128;
2+
3+
private import std.bitmanip : read;
4+
5+
package T leb128(T)(ref const(ubyte)[] input)
6+
if (is(T == int) || is(T == uint))
7+
{
8+
T val = 0;
9+
uint shift = 0;
10+
enum size = 8 << 3;
11+
ubyte b;
12+
13+
while (true)
14+
{
15+
b = input.read!ubyte();
16+
val |= (b & 0x7F) << shift;
17+
shift += 7;
18+
if ((b & 0x80) == 0) break;
19+
}
20+
static if (is(T == int))
21+
{
22+
// sign bit must be extended.
23+
if (shift < size && (b & 0x40) != 0)
24+
val |= -(1 << shift);
25+
}
26+
return val;
27+
}

source/binary/mod.d

+1-15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module binary.mod;
22

33
import binary.instruction;
4+
import binary.leb128;
45
import binary.opcode;
56
import binary.section;
67
import binary.types;
@@ -103,21 +104,6 @@ Module decodeModule(ref const(ubyte)[] input)
103104

104105
private:
105106

106-
uint leb128(T)(ref const(ubyte)[] input)
107-
if (is(T == int) || is(T == uint))
108-
{
109-
T val = 0;
110-
uint shift = 0;
111-
while (true)
112-
{
113-
const b = input.read!ubyte();
114-
val |= (b & 0x7F) << shift;
115-
if ((b & 0x80) == 0) break;
116-
shift += 7;
117-
}
118-
return val;
119-
}
120-
121107
///
122108
Tuple!(SectionCode, uint) decodeSectionHeader(ref const(ubyte)[] input)
123109
{

0 commit comments

Comments
 (0)