Skip to content

Commit 3a84b51

Browse files
authored
Fix dropped bytes when bulk reading from uv streams with oversized buffers (#35695)
In readbytes!(s::UVStream, buf::AbstractVector{UInt8}, nb), we wrap `buf` in a PipeBuffer of maxsize nb and swap it in as the main buffer for the stream `s`. However, when we inform libuv of the size of the buffer, we instead use the size of the underlying array, which can be larger. In that case, we probably either drop bytes or override something that the user did not want overriden.
1 parent d5b329a commit 3a84b51

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

base/stream.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ end
495495
function alloc_request(buffer::IOBuffer, recommended_size::UInt)
496496
ensureroom(buffer, Int(recommended_size))
497497
ptr = buffer.append ? buffer.size + 1 : buffer.ptr
498-
nb = length(buffer.data) - ptr + 1
498+
nb = min(length(buffer.data), buffer.maxsize) - ptr + 1
499499
return (pointer(buffer.data, ptr), nb)
500500
end
501501

test/read.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,3 +596,18 @@ end
596596
seekstart(io)
597597
@test_throws ErrorException read!(io, @view z[4:6])
598598
end
599+
600+
# Bulk read from pipe
601+
let p = Pipe()
602+
data = rand(UInt8, Base.SZ_UNBUFFERED_IO + 100)
603+
Base.link_pipe!(p, reader_supports_async=true, writer_supports_async=true)
604+
t = @async write(p.in, data)
605+
@test read(p.out, UInt8) == data[1]
606+
data_read = Vector{UInt8}(undef, 10*Base.SZ_UNBUFFERED_IO)
607+
nread = readbytes!(p.out, data_read, Base.SZ_UNBUFFERED_IO + 50)
608+
@test nread == Base.SZ_UNBUFFERED_IO + 50
609+
@test data_read[1:nread] == data[2:nread+1]
610+
@test read(p.out, 49) == data[end-48:end]
611+
wait(t)
612+
close(p)
613+
end

0 commit comments

Comments
 (0)