Skip to content

v0.2.2

Choose a tag to compare

@samooth samooth released this 26 Sep 18:29
· 37 commits to main since this release
0.2.2

First release from the samooth/httpx.zig mirror, based on upstream v0.2.0.

Fix

The template cache borrow was never actually protected. get returned
&entry.ast with the entry stored inline in a StringHashMap, so the pointer
targeted the map's value storage. A concurrent invalidate or put could dangle
it while activeRenders still counted the render as live.

The retirement logic was sound but addressed the wrong thing: it copied the AST
into garbage and deferred ast.deinit(), which protects the AST's heap
buffers — not the map slot, released the moment fetchRemove runs.

Impact: any server rendering templates from more than one thread while
invalidating (hot reload, dev mode, a file watcher) could segfault.

The map now stores heap pointers, so a borrow survives until freeEntry, which
the existing counter already deferred.

Security

  • DNS transaction IDs — now io.random instead of a DefaultPrng seeded
    with millisNow(); a classic cache-poisoning surface.
  • QUIC connection IDs — io.randomSecure. The seed parameter was removed
    because it invited callers to pass a clock, which is how both production sites
    went wrong. RFC 9000 Section 8.2 requires unpredictable CIDs.
  • CSRF tokens — new generateCsrfTokenSecure(io, out), which cannot be
    misused. generateCsrfToken(std.Random, ...) is now test-only: its signature
    invited a non-cryptographic PRNG and a therefore predictable token.
  • entropy_hygiene_test blocks reintroducing DefaultPrng under tls/,
    quic/connection.zig, net/dns.zig and web/middleware/security.zig.

Features

  • X25519MLKEM768 post-quantum key exchange (client side). Offered first, with
    plain X25519 as a fallback so peers without PQ support pick it directly instead
    of forcing a HelloRetryRequest. Not offered over QUIC: the 1216-byte share
    exceeds the Initial packet buffer and needs CRYPTO frame fragmentation
    (RFC 9000 Section 14).

Infrastructure

  • CI runs the suite in ReleaseFast — the only mode that catches
    stack-lifetime bugs, where a slice of a returned frame is harmless in Debug and
    reads garbage in ReleaseFast. Five such defects reached main through that gap.
  • Three latent fd-after-close races fixed in the socks4, socks5 and client pool
    test servers.