133 Commits

Author SHA1 Message Date
Andrew Kelley
d83d79c032 std.Io.Reader: rework peekDelimiterInclusive
Now it's based on calling fillMore rather than an illegal aliased stream
into the Reader buffer.

This commit also includes a disambiguation block inspired by #25162. If
`StreamTooLong` was added to `RebaseError` then this logic could be
replaced by removing the exit condition from the while loop. That error
code would represent when `buffer` capacity is too small for an
operation, replacing the current use of asserts.
2025-10-08 19:30:36 -07:00
whatisaphone
b9f8b6ef06 Fix Reader.Limited end of stream conditions 2025-10-08 17:24:38 -07:00
mlugg
bf58b4e419 std.Io.Reader: fix delimiter bugs
Fix `takeDelimiter` and `takeDelimiterExclusive` tossing too many bytes
(#25132)

Also add/improve test coverage for all delimiter and sentinel methods,
update usages of `takeDelimiterExclusive` to not rely on the fixed bug,
tweak a handful of doc comments, and slightly simplify some logic.

I have not fixed #24950 in this commit because I am a little less
certain about the appropriate solution there.

Resolves: #25132

Co-authored-by: Andrew Kelley <andrew@ziglang.org>
2025-10-08 17:00:15 -07:00
Andrew Kelley
889942a8b7 std: fix sendFileReading not accounting for buffer
Related to 1d764c1fdf04829cec5974d82cec901825a80e49

Test case provided by:

Co-authored-by: Kendall Condon <goon.pri.low@gmail.com>
2025-10-08 16:45:38 -07:00
Ryan Liptak
328ae41468 Reader.peekDelimiterInclusive: Fix handling of stream implementations that return 0
Previously, the logic in peekDelimiterInclusive (when the delimiter was not found in the existing buffer) used the `n` returned from `r.vtable.stream` as the length of the slice to check, but it's valid for `vtable.stream` implementations to return 0 if they wrote to the buffer instead of `w`. In that scenario, the `indexOfScalarPos` would be given a 0-length slice so it would never be able to find the delimiter.

This commit changes the logic to assume that `r.vtable.stream` can both:
- return 0, and
- modify seek/end (i.e. it's also valid for a `vtable.stream` implementation to rebase)

Also introduces `std.testing.ReaderIndirect` which helps in being able to test against Reader implementations that return 0 from `stream`/`readVec`

Fixes #25428
2025-10-08 16:42:55 -07:00
Andrew Kelley
b824ca8494 Revert "Fix infinite loop in Reader.Limited"
This reverts commit 27aba2d776caf59bb6569934626af587fdba9c75.

I'd like to review this contribution more carefully, particularly with
the alternate implementation that is also open as a pull request
(#25109).

Reopens #25093
2025-10-07 14:35:08 -07:00
achan1989
27aba2d776 Fix infinite loop in Reader.Limited 2025-10-07 09:53:34 -07:00
Andrew Kelley
594cb38fcb
Merge pull request #25302 from ziglang/growCapacity
std: remove loop from growCapacity
2025-09-21 04:55:39 -07:00
Andrew Kelley
5ec0a7d8a5 coerce vectors to arrays rather than inline for 2025-09-20 18:33:00 -07:00
Ryan Liptak
3fbb88c4bd Reader.defaultReadVec: Workaround bad r.end += r.vtable.stream() behavior
If `r.end` is updated in the `stream` implementation, then it's possible that `r.end += ...` will behave unexpectedly. What seems to happen is that it reverts back to its value before the function call and then the increment happens. Here's a reproduction:

```zig
test "fill when stream modifies `end` and returns 0" {
    var buf: [3]u8 = undefined;
    var zero_reader = infiniteZeroes(&buf);

    _ = try zero_reader.fill(1);
    try std.testing.expectEqual(buf.len, zero_reader.end);
}

pub fn infiniteZeroes(buf: []u8) std.Io.Reader {
    return .{
        .vtable = &.{
            .stream = stream,
        },
        .buffer = buf,
        .end = 0,
        .seek = 0,
    };
}

fn stream(r: *std.Io.Reader, _: *std.Io.Writer, _: std.Io.Limit) std.Io.Reader.StreamError!usize {
    @memset(r.buffer[r.seek..], 0);
    r.end = r.buffer.len;
    return 0;
}
```

When `fill` is called, it will call into `vtable.readVec` which in this case is `defaultReadVec`. In `defaultReadVec`:

- Before the `r.end += r.vtable.stream` line, `r.end` will be 0
- In `r.vtable.stream`, `r.end` is modified to 3 and it returns 0
- After the `r.end += r.vtable.stream` line, `r.end` will be 0 instead of the expected 3

Separating the `r.end += stream();` into two lines fixes the problem (and this separation is done elsewhere in `Reader` so it seems possible that this class of bug has been encountered before).

Potentially related issues:

- https://github.com/ziglang/zig/issues/4021
- https://github.com/ziglang/zig/issues/12064
2025-09-20 18:31:38 -07:00
Andrew Kelley
0c1fbc4ea6 std: remove loop from growCapacity
I measured this against master branch and found no statistical
difference. Since this code is simpler and logically superior due to
always leaving sufficient unused capacity when growing, it is preferred
over status quo.
2025-09-20 14:34:18 -07:00
Andrew Kelley
eac2bbfec9 std.Io.Writer.writeSliceEndian: add compile error
check when an auto-layout struct is attempted to be memory reinterpreted
and written out. it would be writing undefined memory
2025-09-08 18:18:27 -07:00
Andrew Kelley
1d764c1fdf Revert "Merge pull request #24905 from gooncreeper/file-reader-buffered"
This reverts commit ac42eaaadd0650ffc281f9a1ed1a642fde8984b7, reversing
changes made to 9fa2394f8c00d060931d69fb6f342f7f2e3d826e.

I would like a chance to review this, please. I already spotted some
issues.
2025-09-05 11:26:38 -07:00
Kendall Condon
d26b532647 sendFileAll: use stream instead of sendFileReading
This is a simpler implementation and allows file_reader to do more
optimal streaming.
2025-09-04 17:26:52 -04:00
Kendall Condon
58dda3b10b fix sendFile implementations bypassing interface buffer
Also removes `File.Reader.read` since it is otherwise unused and is a
footgun.
2025-09-04 17:26:49 -04:00
Travis Staloch
1ec8a7ab4c Io.Writer.Allocating: test new *Aligned methods
* added initAligned()
* added missing @alignCast in toArrayListAligned()
2025-08-31 19:29:02 -07:00
Andrew Kelley
b7104231af
Merge pull request #25077 from ziglang/GenericReader
std.Io: delete GenericReader, AnyReader, FixedBufferStream; and related API breakage
2025-08-30 12:43:52 -07:00
Andrew Kelley
e2fdaea0b3 Revert "std.Io.Reader: work around llvm backend bug"
This reverts commit 530cc2c1111699d9d02ad9ebef94efa6b99f5205.

The compiler bug has been fixed.
2025-08-30 06:04:25 -07:00
Andrew Kelley
fadd268a60 upgrade more old API uses 2025-08-30 00:48:50 -07:00
Andrew Kelley
9a0970a12b rework std.Io.Writer.Allocating to support runtime-known alignment
Also, breaking API changes to:
* std.fs.Dir.readFileAlloc
* std.fs.Dir.readFileAllocOptions
2025-08-30 00:48:50 -07:00
Andrew Kelley
79f267f6b9 std.Io: delete GenericReader
and delete deprecated alias std.io
2025-08-29 17:14:26 -07:00
Andrew Kelley
558bea2a76 std.Io: delete CountingReader 2025-08-29 11:11:59 -07:00
Andrew Kelley
43fbc37a49 std.debug.Pdb: migrate more towards new Reader API
There was some bug in this branch, and rather than diagnosing it, I
fully finished porting over to new Reader API. Did it fix the bug?
2025-08-28 22:41:06 -07:00
Andrew Kelley
530cc2c111 std.Io.Reader: work around llvm backend bug
tracked by #25067 and I already have a fix cooking in another branch
2025-08-28 18:30:57 -07:00
Andrew Kelley
8023f3dceb fix not discarding delimiter
perhaps these APIs have the defaults backwards, eh?
2025-08-28 18:30:57 -07:00
Andrew Kelley
f7884961c2 update more to avoid GenericWriter 2025-08-28 18:30:57 -07:00
Andrew Kelley
9860dd475a std: delete most remaining uses of GenericWriter 2025-08-28 18:30:57 -07:00
Andrew Kelley
cc931660eb link.MachO: update to not use GenericWriter 2025-08-28 18:30:57 -07:00
Andrew Kelley
2dc6ddd7e8 std.Io.Writer: add toArrayList/fromArrayList 2025-08-28 18:30:57 -07:00
Andrew Kelley
57dbc9e74a std.Io: delete GenericWriter 2025-08-28 18:30:57 -07:00
Ryan Liptak
2b73c28cec Reader.appendRemaining: Take ownership of the full allocated slice
Before this commit, calling appendRemaining with an ArrayList where list.items.len != list.capacity could result in illegal behavior if the Writer.Allocating resized the list during the appendRemaining call.

Fixes #25057
2025-08-28 07:56:50 -07:00
TemariVirus
51a2c0feaf std.Io.Writer: fix upper case hex float formatting 2025-08-19 11:20:30 -07:00
Rohlem
81f5a7b8fd
never advance seek position in std.Io.Reader.peekDelimiterExclusive (#24899)
* extend std.Io.Reader.peekDelimiterExclusive test to repeat successful end-of-stream path (fails)

* fix std.Io.Reader.peekDelimiterExclusive to not advance seek position in successful end-of-stream path
2025-08-19 11:19:02 -07:00
Isaac Freund
551e009da7 Build.Step.Run: fix missing stdin buffer and flush
Writer.sendFileAll() asserts non-zero buffer capacity in the case that
the fallback is hit. It also requires the caller to flush. The buffer
may be bypassed as an optimization but this is not a guarantee.

Also improve the Writer documentation and add an earlier assert on
buffer capacity in sendFileAll().
2025-08-16 15:43:48 -07:00
Andrew Kelley
399bace2f2
Merge pull request #24874 from ziglang/tls-client
std: more reliable HTTP and TLS networking
2025-08-16 14:47:52 -07:00
Andrew Kelley
ef14c73245 Compilation: remove last instance of deprecatedReader
This also makes initStreaming preemptively disable file size checking.
2025-08-16 14:46:20 -07:00
Josh Wolfe
4fcdb08390 [std] fix compile error in std.Io.Writer.failing 2025-08-16 00:23:47 -07:00
Andrew Kelley
a0f9a5e78d std: more reliable HTTP and TLS networking
* std.Io.Reader: fix confused semantics of rebase. Before it was
  ambiguous whether it was supposed to be based on end or seek. Now it
  is clearly based on seek, with an added assertion for clarity.

* std.crypto.tls.Client: fix panic due to not enough buffer size
  available. Also, avoid unnecessary rebasing.

* std.http.Reader: introduce max_head_len to limit HTTP header length.
  This prevents crash in underlying reader which may require a minimum
  buffer length.

* std.http.Client: choose better buffer sizes for streams and TLS
  client. Crucially, the buffer shared by HTTP reader and TLS client
  needs to be big enough for all http headers *and* the max TLS record
  size. Bump HTTP header size default from 4K to 8K.

fixes #24872

I have noticed however that there are still fetch problems
2025-08-16 00:16:15 -07:00
Andrew Kelley
30b41dc510 std.compress.zstd.Decompress fixes
* std.Io.Reader: appendRemaining no longer supports alignment and has
  different rules about how exceeding limit. Fixed bug where it would
  return success instead of error.StreamTooLong like it was supposed to.

* std.Io.Reader: simplify appendRemaining and appendRemainingUnlimited
  to be implemented based on std.Io.Writer.Allocating

* std.Io.Writer: introduce unreachableRebase

* std.Io.Writer: remove minimum_unused_capacity from Allocating. maybe
  that flexibility could have been handy, but let's see if anyone
  actually needs it. The field is redundant with the superlinear growth
  of ArrayList capacity.

* std.Io.Writer: growingRebase also ensures total capacity on the
  preserve parameter, making it no longer necessary to do
  ensureTotalCapacity at the usage site of decompression streams.

* std.compress.flate.Decompress: fix rebase not taking into account seek

* std.compress.zstd.Decompress: split into "direct" and "indirect" usage
  patterns depending on whether a buffer is provided to init, matching
  how flate works. Remove some overzealous asserts that prevented buffer
  expansion from within rebase implementation.

* std.zig: fix readSourceFileToAlloc returning an overaligned slice
  which was difficult to free correctly.

fixes #24608
2025-08-15 10:44:35 -07:00
Andrew Kelley
af7e142485 std.Io.Writer: introduce rebase to the vtable
fixes #24814
2025-08-14 12:56:37 -07:00
Kendall Condon
4f639ff880 http: fix handling of limit in chunkedSendFile
`limit` in chunkedSendFile applies only to the file, not the entire
chunk. `limit` in sendFileHeader does not include the header.

Additionally adds a comment to clarify what `limit` applies to in
sendFileHeader and fixed a small bug in it (`drain` is able to return
less then `header.len`).
2025-08-13 13:14:01 -07:00
Isaac Freund
b8124d9c0b std.io.Writer.Allocating: rename getWritten() to written()
This "get" is useless noise and was copied from FixedBufferWriter.
Since this API has not yet landed in a release, now is a good time
to make the breaking change to fix this.
2025-08-13 01:43:52 -07:00
Andrew Kelley
749f10af49 std.ArrayList: make unmanaged the default 2025-08-11 15:52:49 -07:00
Jacob Young
60f8584927 Dwarf: port to new Writer API 2025-08-11 12:00:50 -07:00
Ryan Liptak
3280fc98f3 Writer: Delete writePreserve/writeAllPreserve
This is one way of partially addressing https://github.com/ziglang/zig/issues/24767

- These functions are unused
- These functions are untested
- These functions are broken
  + The same dangling pointer bug from 6219c015d8e8c958d96e5caa5ef0dbab9c414996 exists in `writePreserve`
  + The order of the bytes preserved in relation to the `bytes` being written can differ depending on unused buffer capacity at the time of the call and the drain implementation.

If there ends up being a need for these functions, they can be fixed and added back.
2025-08-10 19:49:02 -07:00
Andrew Kelley
0a1a738320
Merge pull request #24743 from ziglang/BufferedWriter
std.Io: delete BufferedWriter
2025-08-09 16:28:19 -07:00
Andrew Kelley
df46ee61c4 std.Io.Writer.Allocating: configurable bump amount 2025-08-08 19:22:08 -07:00
Andrew Kelley
045bb14897 zig std: fix build failures 2025-08-08 17:17:53 -07:00
Andrew Kelley
8c9dfcbd0f std.Io: remove BufferedWriter 2025-08-08 17:17:53 -07:00
Andrew Kelley
3d25a9c1e0 std.Io.Writer.Allocating.sendFile: use logicalPos
fixes #24754

tested with `zig build test-std -Dskip-release`
2025-08-08 14:21:57 -07:00