Skip to content

Commit 31bf76f

Browse files
authored
Merge pull request JuliaLang#33942 from JuliaLang/jn/33899
Fix a small number of invalid unsafe code [round 2]
2 parents 764ff06 + 60ec5f3 commit 31bf76f

File tree

5 files changed

+37
-29
lines changed

5 files changed

+37
-29
lines changed

base/stream.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,7 @@ function readuntil(x::LibuvStream, c::UInt8; keep::Bool=false)
917917
return bytes
918918
end
919919

920-
uv_write(s::LibuvStream, p::Vector{UInt8}) = uv_write(s, pointer(p), UInt(sizeof(p)))
920+
uv_write(s::LibuvStream, p::Vector{UInt8}) = GC.@preserve p uv_write(s, pointer(p), UInt(sizeof(p)))
921921

922922
# caller must have acquired the iolock
923923
function uv_write(s::LibuvStream, p::Ptr{UInt8}, n::UInt)
@@ -1036,8 +1036,9 @@ function write(s::LibuvStream, b::UInt8)
10361036
if buf !== nothing
10371037
iolock_begin()
10381038
if bytesavailable(buf) + 1 < buf.maxsize
1039+
n = write(buf, b)
10391040
iolock_end()
1040-
return write(buf, b)
1041+
return n
10411042
end
10421043
iolock_end()
10431044
end

base/strings/search.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ function _search(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer =
3434
return i == n+1 ? 0 : throw(BoundsError(a, i))
3535
end
3636
p = pointer(a)
37-
q = ccall(:memchr, Ptr{UInt8}, (Ptr{UInt8}, Int32, Csize_t), p+i-1, b, n-i+1)
38-
q == C_NULL ? 0 : Int(q-p+1)
37+
q = GC.@preserve a ccall(:memchr, Ptr{UInt8}, (Ptr{UInt8}, Int32, Csize_t), p+i-1, b, n-i+1)
38+
return q == C_NULL ? 0 : Int(q-p+1)
3939
end
4040

4141
function _search(a::ByteArray, b::AbstractChar, i::Integer = 1)
@@ -74,8 +74,8 @@ function _rsearch(a::Union{String,ByteArray}, b::Union{Int8,UInt8}, i::Integer =
7474
return i == n+1 ? 0 : throw(BoundsError(a, i))
7575
end
7676
p = pointer(a)
77-
q = ccall(:memrchr, Ptr{UInt8}, (Ptr{UInt8}, Int32, Csize_t), p, b, i)
78-
q == C_NULL ? 0 : Int(q-p+1)
77+
q = GC.@preserve a ccall(:memrchr, Ptr{UInt8}, (Ptr{UInt8}, Int32, Csize_t), p, b, i)
78+
return q == C_NULL ? 0 : Int(q-p+1)
7979
end
8080

8181
function _rsearch(a::ByteArray, b::AbstractChar, i::Integer = length(a))

base/strings/string.jl

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ codeunit(s::String) = UInt8
8787

8888
@inline function codeunit(s::String, i::Integer)
8989
@boundscheck checkbounds(s, i)
90-
GC.@preserve s unsafe_load(pointer(s, i))
90+
b = GC.@preserve s unsafe_load(pointer(s, i))
91+
return b
9192
end
9293

9394
## comparison ##
@@ -112,7 +113,7 @@ typemin(::String) = typemin(String)
112113

113114
## thisind, nextind ##
114115

115-
Base.@propagate_inbounds thisind(s::String, i::Int) = _thisind_str(s, i)
116+
@propagate_inbounds thisind(s::String, i::Int) = _thisind_str(s, i)
116117

117118
# s should be String or SubString{String}
118119
@inline function _thisind_str(s, i::Int)
@@ -133,7 +134,7 @@ Base.@propagate_inbounds thisind(s::String, i::Int) = _thisind_str(s, i)
133134
return i
134135
end
135136

136-
Base.@propagate_inbounds nextind(s::String, i::Int) = _nextind_str(s, i)
137+
@propagate_inbounds nextind(s::String, i::Int) = _nextind_str(s, i)
137138

138139
# s should be String or SubString{String}
139140
@inline function _nextind_str(s, i::Int)
@@ -251,7 +252,7 @@ getindex(s::String, r::UnitRange{<:Integer}) = s[Int(first(r)):Int(last(r))]
251252
j = nextind(s, j) - 1
252253
n = j - i + 1
253254
ss = _string_n(n)
254-
unsafe_copyto!(pointer(ss), pointer(s, i), n)
255+
GC.@preserve s ss unsafe_copyto!(pointer(ss), pointer(s, i), n)
255256
return ss
256257
end
257258

@@ -323,7 +324,7 @@ function repeat(c::Char, r::Integer)
323324
n = 4 - (leading_zeros(u | 0xff) >> 3)
324325
s = _string_n(n*r)
325326
p = pointer(s)
326-
if n == 1
327+
GC.@preserve s if n == 1
327328
ccall(:memset, Ptr{Cvoid}, (Ptr{UInt8}, Cint, Csize_t), p, u % UInt8, r)
328329
elseif n == 2
329330
p16 = reinterpret(Ptr{UInt16}, p)
@@ -340,7 +341,7 @@ function repeat(c::Char, r::Integer)
340341
unsafe_store!(p, b3, 3i + 3)
341342
end
342343
elseif n == 4
343-
p32 = reinterpret(Ptr{UInt32}, pointer(s))
344+
p32 = reinterpret(Ptr{UInt32}, p)
344345
for i = 1:r
345346
unsafe_store!(p32, u, i)
346347
end
@@ -349,11 +350,11 @@ function repeat(c::Char, r::Integer)
349350
end
350351

351352
function filter(f, s::String)
352-
out = Base.StringVector(sizeof(s))
353+
out = StringVector(sizeof(s))
353354
offset = 1
354355
for c in s
355356
if f(c)
356-
offset += Base.__unsafe_string!(out, c, offset)
357+
offset += __unsafe_string!(out, c, offset)
357358
end
358359
end
359360
resize!(out, offset-1)

base/strings/substring.jl

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@ convert(::Type{SubString{S}}, s::AbstractString) where {S<:AbstractString} =
5151
SubString(convert(S, s))
5252
convert(::Type{T}, s::T) where {T<:SubString} = s
5353

54-
String(s::SubString{String}) = unsafe_string(pointer(s.string, s.offset+1), s.ncodeunits)
54+
function String(s::SubString{String})
55+
parent = s.string
56+
copy = GC.@preserve parent unsafe_string(pointer(parent, s.offset+1), s.ncodeunits)
57+
return copy
58+
end
5559

5660
ncodeunits(s::SubString) = s.ncodeunits
5761
codeunit(s::SubString) = codeunit(s.string)
@@ -151,25 +155,27 @@ end
151155
string(a::String) = String(a)
152156
string(a::SubString{String}) = String(a)
153157

154-
@inline function __unsafe_string!(out, c::Char, offs::Integer)
158+
@inline function __unsafe_string!(out, c::Char, offs::Integer) # out is a (new) String (or StringVector)
155159
x = bswap(reinterpret(UInt32, c))
156160
n = ncodeunits(c)
157-
unsafe_store!(pointer(out, offs), x % UInt8)
158-
n == 1 && return n
159-
x >>= 8
160-
unsafe_store!(pointer(out, offs+1), x % UInt8)
161-
n == 2 && return n
162-
x >>= 8
163-
unsafe_store!(pointer(out, offs+2), x % UInt8)
164-
n == 3 && return n
165-
x >>= 8
166-
unsafe_store!(pointer(out, offs+3), x % UInt8)
161+
GC.@preserve out begin
162+
unsafe_store!(pointer(out, offs), x % UInt8)
163+
n == 1 && return n
164+
x >>= 8
165+
unsafe_store!(pointer(out, offs+1), x % UInt8)
166+
n == 2 && return n
167+
x >>= 8
168+
unsafe_store!(pointer(out, offs+2), x % UInt8)
169+
n == 3 && return n
170+
x >>= 8
171+
unsafe_store!(pointer(out, offs+3), x % UInt8)
172+
end
167173
return n
168174
end
169175

170176
@inline function __unsafe_string!(out, s::Union{String, SubString{String}}, offs::Integer)
171177
n = sizeof(s)
172-
unsafe_copyto!(pointer(out, offs), pointer(s), n)
178+
GC.@preserve s out unsafe_copyto!(pointer(out, offs), pointer(s), n)
173179
return n
174180
end
175181

@@ -200,7 +206,7 @@ function repeat(s::Union{String, SubString{String}}, r::Integer)
200206
ccall(:memset, Ptr{Cvoid}, (Ptr{UInt8}, Cint, Csize_t), out, b, r)
201207
else
202208
for i = 0:r-1
203-
unsafe_copyto!(pointer(out, i*n+1), pointer(s), n)
209+
GC.@preserve s out unsafe_copyto!(pointer(out, i*n+1), pointer(s), n)
204210
end
205211
end
206212
return out

base/strings/util.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ function replace(str::String, pat_repl::Pair; count::Integer=typemax(Int))
442442
out = IOBuffer(sizehint=floor(Int, 1.2sizeof(str)))
443443
while j != 0
444444
if i == a || i <= k
445-
unsafe_write(out, pointer(str, i), UInt(j-i))
445+
GC.@preserve str unsafe_write(out, pointer(str, i), UInt(j-i))
446446
_replace(out, repl, str, r, pattern)
447447
end
448448
if k < j

0 commit comments

Comments
 (0)