diff --git a/Sources/WasmParser/LEB.swift b/Sources/WasmParser/LEB.swift index df99feec..7bbc0852 100644 --- a/Sources/WasmParser/LEB.swift +++ b/Sources/WasmParser/LEB.swift @@ -35,7 +35,7 @@ func decodeLEB128( @inlinable func decodeLEB128( - stream: Stream + stream: Stream, bitWidth: Int = IntType.bitWidth ) throws -> IntType where IntType: FixedWidthInteger, IntType: RawSignedInteger, Stream: ByteStream { let firstByte = try stream.consumeAny() var result = IntType.Unsigned(firstByte & 0b0111_1111) @@ -54,8 +54,8 @@ func decodeLEB128( result |= slice << shift // When we don't have enough bit width - if shift > (IntType.bitWidth - 7) { - let remainingBitWidth = IntType.bitWidth - Int(shift) + if shift > (bitWidth - 7) { + let remainingBitWidth = bitWidth - Int(shift) let continuationBit = (byte & 0b1000_0000) != 0 // When a next byte is expected if continuationBit { diff --git a/Sources/WasmParser/WasmParser.swift b/Sources/WasmParser/WasmParser.swift index f171ec5a..db7bb815 100644 --- a/Sources/WasmParser/WasmParser.swift +++ b/Sources/WasmParser/WasmParser.swift @@ -316,6 +316,10 @@ extension WasmParserError.Message { @usableFromInline static func invalidResultArity(expected: Int, actual: Int) -> Self { Self("invalid result arity: expected \(expected) but got \(actual)") } + + @usableFromInline static func invalidFunctionType(_ index: Int64) -> Self { + Self("invalid function type index: \(index), expected a unsigned 32-bit integer") + } } /// > Note: @@ -344,6 +348,11 @@ extension ByteStream { func parseSigned() throws -> T { try decodeLEB128(stream: self) } + + @usableFromInline + func parseVarSigned33() throws -> Int64 { + try decodeLEB128(stream: self, bitWidth: 33) + } } /// > Note: @@ -452,7 +461,11 @@ extension Parser { case 0x7C...0x7F, 0x70, 0x6F: return try .type(parseValueType()) default: - return try .funcType(TypeIndex(stream.consumeAny())) + let rawIndex = try stream.parseVarSigned33() + guard let index = TypeIndex(exactly: rawIndex) else { + throw makeError(.invalidFunctionType(rawIndex)) + } + return .funcType(index) } }