Skip to content

Make std.BitStack.pop return an optional #22282

@adurmk1

Description

@adurmk1

Zig Version

0.14.0-dev.2545+e2e363361

Steps to Reproduce and Observed Behavior

Call peek or push on an empty std.BitStack or call std.BitStack.peekWithState or std.BitStack.popWithState with a bit _len.* of 0.
This will result in an integer overflow panic due to subtracting from zero.

Code to reproduce

const std = @import("std");

pub fn main() !void {
    var bit_stack = std.BitStack.init(std.heap.page_allocator);
    defer bit_stack.deinit();
    _ = bit_stack.pop();
}

Panic output

thread 244661 panic: integer overflow
/usr/lib/zig/lib/std/BitStack.zig:58:33: 0x103c156 in peekWithState (test)
    const byte_index = (bit_len - 1) >> 3;
                                ^
/usr/lib/zig/lib/std/BitStack.zig:65:28: 0x103a64b in popWithState (test)
    const b = peekWithState(buf, bit_len.*);
                           ^
/usr/lib/zig/lib/std/BitStack.zig:42:24: 0x1038133 in pop (test)
    return popWithState(self.bytes.items, &self.bit_len);
                       ^
/home/art/test.zig:6:22: 0x1038095 in main (test)
    _ = bit_stack.pop();
                     ^
/usr/lib/zig/lib/std/start.zig:656:37: 0x1038041 in posixCallMainAndExit (test)
            const result = root.main() catch |err| {
                                    ^
/usr/lib/zig/lib/std/start.zig:271:5: 0x1037c4d in _start (test)
    asm volatile (switch (native_arch) {
    ^
???:?:?: 0x0 in ??? (???)

Expected Behavior

I think there are multiple ways to improve/fix this behaviour of these functions, they are ordered in decending order of practicality in my opinion:

  1. The functions should assert that self.bit_len/bit_len.* are greater than zero. This shouldn't affect the stdlib at all.
  2. The functions return a nullable type or an error union. This would cause some parts of stdlib like std.json.Scanner to have to be rewritten/fixed.
  3. Add a function like isEmpty to std.BitStack to make this behaviour more clear through the interface, this also shouldn't affect the stdlib.
  4. Document this behaviour of these functions in the doc comments, this could be done in addition to all the prior solutions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    breakingImplementing this issue could cause existing code to no longer compile or have different behavior.standard libraryThis issue involves writing Zig code for the standard library.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions