julia icon indicating copy to clipboard operation
julia copied to clipboard

`String` constructor on a `view` can mutate parent

Open nhz2 opened this issue 1 year ago • 7 comments

This has happened since #53896

Here is a MWE.

julia> a = Memory{UInt8}(undef, 10);

julia> fill!(a, 0x01);

julia> String(view(a, 1:2))
"\x01\x01"

julia> a
0-element Memory{UInt8}

I expected a to not be changed.

This is causing issues in https://github.com/JuliaWeb/HTTP.jl/issues/1166 And I am also using String(view( in https://github.com/JuliaIO/ZipArchives.jl/blob/5bacade2f71e0c28e2aeba09d21a665ecad131cd/src/reader.jl#L106

nhz2 avatar Apr 19 '24 20:04 nhz2

I believe this is intended

see also: https://github.com/JuliaLang/julia/issues/32528

adienes avatar Apr 19 '24 20:04 adienes

The issue is that view protects the parent from being truncated by String in 1.10, but in 1.11.0-beta1 this is broken. If this is intended what is the correct way to protect the parent from being truncated?

nhz2 avatar Apr 19 '24 20:04 nhz2

In older versions, the view function also enforced a copy, which seems awkward to expect there. We should possibly check though that the truncation of the Memory object only applies if it is backed by a String (and doesn't make a copy)?

vtjnash avatar Apr 19 '24 22:04 vtjnash

Maybe the view method that converts a Memory to a Vector could be called something like make_vector to avoid confusion with normal view? The difference would be that the result of view would have a fixed size, and create a copy when passed to String.

nhz2 avatar Apr 22 '24 16:04 nhz2

Maybe https://github.com/JuliaLang/julia/pull/53896 should be reverted / rethought in light of this.

KristofferC avatar Apr 22 '24 18:04 KristofferC

We also possibly should not unsafely mutate this Memory in this case. That is somewhat more of an Array feature anyways that you should possibly lose when accessing Memory directly

vtjnash avatar Apr 22 '24 19:04 vtjnash

If I understand: https://github.com/JuliaLang/julia/blob/c38e7cd76ad5576a52e4726f78229e8c6e5cc212/src/genericmemory.c#L196-L207 correctly, there are two possible mutations, setting length to 0, and setting the byte after the end to null. Are String required to always be null terminated?

nhz2 avatar Apr 24 '24 19:04 nhz2

Fixed by #54927

nhz2 avatar Jul 31 '24 22:07 nhz2