Arwalk / zig-protobuf

a protobuf 3 implementation for zig.
MIT License
188 stars 20 forks source link

user error caused panic: integer cast truncated bits #34

Closed tjk closed 6 months ago

tjk commented 6 months ago

Will look into this more tomorrow, but wanted to share quickly in case it's obvious:

thread 1951688 panic: integer cast truncated bits
/home/tj/.cache/zig/p/1220d226686f6023fae80156c729382295c672d6ffaa746d2932d73f16bd9affc758/src/protobuf.zig:634:77: 0x2dc131 in decode_varint__anon_12288 (a)
        value += (@as(T, input[index] & 0x7F)) << (@as(std.math.Log2Int(T), @intCast(shift)));
                                                                            ^
/home/tj/.cache/zig/p/1220d226686f6023fae80156c729382295c672d6ffaa746d2932d73f16bd9affc758/src/protobuf.zig:729:51: 0x2ca405 in next (a)
            const tag_and_wire = try decode_varint(u32, state.input[state.current_index..]);

Debug prints:

std.math.Log2Int(T): u5 | shift: 0
std.math.Log2Int(T): u5 | shift: 7
std.math.Log2Int(T): u5 | shift: 14
std.math.Log2Int(T): u5 | shift: 21
std.math.Log2Int(T): u5 | shift: 28
std.math.Log2Int(T): u5 | shift: 35 <---- crashes here for obvious reasons

My proto is essentially this:

message m {
  optional uint32 a = 1;
  optional float b = 2;
  message C {
    optional string d = 1;
  }
  optional C c = 3;
}

And I'm sending the following over the wire:

const data = try client_server.encode(allocator);
// data: [_]u8{ 8, 240, 1, 21, 0, 112, 155, 69 }

which looks like it should decode correctly to:

Byte Range Field Number Type Content
0-3 1 varint As Int: 240
As Signed Int: 120
3-8 2 fixed32 As Int: 1167814656
As Float: 4974

Hopefully I'm not doing something silly. Thanks for the library!

Arwalk commented 6 months ago

Thanks for the report. I tried to reproduce the problem in 597b04f506fcd0a752a75fd0fedc34237fc1eb26 . Sadly (?), i don't have any problem decoding and encoding the data you provided in such a message.

Keeping it open still until we are sure of what's happening.

tjk commented 6 months ago

I just assumed it was making it across the wire correctly which of course was the most likely cause for the issue... debugging that but unless I reopen assume this just PEBACK. Thanks and sorry for wasting your time!


Confirmed. Was doing a ws.send(data: UInt8Array) assuming it was 'clamped' (not using proper byteLength / byteOffset since pointed to the full wasm memory buffer)

- ws.send(new Uint8Array(this.memory.buffer, ptr, len))
+ ws.send(this.memory.buffer.slice(ptr, ptr + len))
Arwalk commented 6 months ago

Good to know, for me ;)

Thanks for your interest, happy to help.