Skip to content

Commit 6219c01

Browse files
ianicandrewrk
authored andcommitted
Io.Writer fix dangling pointer
While underlying writer is Allocating writer buffer can grow in vtable.drain call. We should not hold pointer to the buffer before that call and use it after. This remembers positions instead of holding reference.
1 parent 3ee4252 commit 6219c01

File tree

1 file changed

+7
-6
lines changed

1 file changed

+7
-6
lines changed

lib/std/Io/Writer.zig

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -317,13 +317,14 @@ test "fixed buffer flush" {
317317
/// Calls `VTable.drain` but hides the last `preserve_len` bytes from the
318318
/// implementation, keeping them buffered.
319319
pub fn drainPreserve(w: *Writer, preserve_len: usize) Error!void {
320-
const temp_end = w.end -| preserve_len;
321-
const preserved = w.buffer[temp_end..w.end];
322-
w.end = temp_end;
323-
defer w.end += preserved.len;
320+
const preserved_head = w.end -| preserve_len;
321+
const preserved_tail = w.end;
322+
const preserved_len = preserved_tail - preserved_head;
323+
w.end = preserved_head;
324+
defer w.end += preserved_len;
324325
assert(0 == try w.vtable.drain(w, &.{""}, 1));
325-
assert(w.end <= temp_end + preserved.len);
326-
@memmove(w.buffer[w.end..][0..preserved.len], preserved);
326+
assert(w.end <= preserved_head + preserved_len);
327+
@memmove(w.buffer[w.end..][0..preserved_len], w.buffer[preserved_head..preserved_tail]);
327328
}
328329

329330
pub fn unusedCapacitySlice(w: *const Writer) []u8 {

0 commit comments

Comments
 (0)