Is asn1 encoder broken?

Hello everyone. am working on something with SNMP and i wanted to use the ASN1 module from the std lib however when i tried to run this example i got this error message

pub fn main(init: std.process.Init) !void {
    const arena = init.arena;
    defer arena.deinit();

    const allocator = arena.allocator();

    const num: i32 =  20;

    var encoder = asn1.der.Encoder.init(allocator);

    try encoder.any(num); 
}

Error:

❯ zig build run
run
└─ run exe nsa1
   └─ compile exe nsa1 Debug native 1 errors
/home/misabear/.zvm/0.16.0/lib/std/crypto/codecs/asn1/der/Encoder.zig:120:47: error: root source file struct 'crypto.codecs.asn1.der.ArrayListReverse' has no member named 'Writer'
pub fn writer(self: *Encoder) ArrayListReverse.Writer {
                              ~~~~~~~~~~~~~~~~^~~~~~~
/home/misabear/.zvm/0.16.0/lib/std/crypto/codecs/asn1/der/ArrayListReverse.zig:1:1: note: struct declared here
//! An ArrayList that grows backwards. Counts nested prefix length fields
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
referenced by:
    length: /home/misabear/.zvm/0.16.0/lib/std/crypto/codecs/asn1/der/Encoder.zig:97:25
    anyTag__anon_33014: /home/misabear/.zvm/0.16.0/lib/std/crypto/codecs/asn1/der/Encoder.zig:74:20
    7 reference(s) hidden; use '-freference-trace=9' to see all references
error: 1 compilation errors
failed command: /home/misabear/.zvm/0.16.0/zig build-exe -ODebug --dep nsa1 -Mroot=/home/misabear/Desktop/zig/nsa1/src/main.zig -Mnsa1=/home/misabear/Desktop/zig/nsa1/src/root.zig --cache-dir .zig-cache --global-cache-dir /home/misabear/.cache/zig --name nsa1 --zig-lib-dir /home/misabear/.zvm/0.16.0/lib/ --listen=-

Build Summary: 0/5 steps succeeded (1 failed)
run transitive failure
└─ run exe nsa1 transitive failure
   ├─ compile exe nsa1 Debug native 1 errors
   └─ install transitive failure
      └─ install nsa1 transitive failure
         └─ compile exe nsa1 Debug native (reused)

error: the following build command failed with exit code 1:
.zig-cache/o/9dab6a593ececf3d3e8266548ab46aee/build /home/misabear/.zvm/0.16.0/zig /home/misabear/.zvm/0.16.0/lib /home/misabear/Desktop/zig/nsa1 .zig-cache /home/misabear/.cache/zig --seed 0x1abdc0b -Z50d67263d7e3b5b0 run

is the ASN broken or am i doing something wrong ??

The function it’s trying to call here (Encoder.writer()) is apparently deprecated - it isn’t present at all in the master branch and doesn’t appear to have any kind of replacement.
It seems like they started the deprecation process in 0.16.0, by removing this line from ArrayListReverse.zig:
pub const Writer = std.io.GenericWriter(*ArrayListReverse, Error, prependSliceSize);
This is because it was using a type which was deprecated with 0.16.0’s new std.Io.Writer.

The good news is that looking at the master branch, it appears that they’ve actually finished the conversion process for this API and it should work perfectly after you update.

1 Like

So if i used the master branch it should work find ?

Yeah pretty much

Thank you man Really appreciated :waving_hand:

By the way, if you wish to stick with stable Zig, you can often transplant selected sources from the newer std into your project.

In this case, you’d copy asn1.zig and the asn1 directory from Zig’s lib/std/crypto/codecs/ somewhere into your codebase and then do const asn1 = @import("asn1.zig") in your file. Note that the master branch has replaced @intFromEnum and @enumFromInt with @backingInt and @fromBackingInt, respectively, so you’d have to make that change.


One more thing: do not deinit the arena you get from std.process.Init. The std does that by itself and you cause a double-free by doing that.

1 Like

looking at ArenaAllocator.deinit, it appears to me to be safe to call more than once?

1 Like

It calls rawFree on the nodes and never sets the lists to null. The way I’m reading it, that causes a double-free when called twice. (It also segfaults when I test it, which is how I noticed it, so there’s that :grin:)

oh, fair enough! that sounds like a bug to me.

Not necessarily, deinits are generally not idempotent. What I would do is change the parameter type to *ArenaAllocator and put an arena.* = undefined; at the end, as is customary.

you totally right i missed that confused with other errors but thanks :melting_face:

Thank you for that note. I might just work with master or wait until 0.17 for more stable but for now i will be testing and playing around with the module