Skip to content

Commit 86bc521

Browse files
authored
Fix unsigned wrap around in lpad/rpad/string allocation (#32161)
Fixes #32160
1 parent dea4940 commit 86bc521

File tree

4 files changed

+11
-2
lines changed

4 files changed

+11
-2
lines changed

base/strings/util.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ function lpad(
243243
n::Integer,
244244
p::Union{AbstractChar,AbstractString}=' ',
245245
) :: String
246-
m = n - length(s)
246+
m = signed(n) - length(s)
247247
m 0 && return string(s)
248248
l = length(p)
249249
q, r = divrem(m, l)
@@ -270,7 +270,7 @@ function rpad(
270270
n::Integer,
271271
p::Union{AbstractChar,AbstractString}=' ',
272272
) :: String
273-
m = n - length(s)
273+
m = signed(n) - length(s)
274274
m 0 && return string(s)
275275
l = length(p)
276276
q, r = divrem(m, l)

src/array.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,8 @@ JL_DLLEXPORT jl_value_t *jl_array_to_string(jl_array_t *a)
471471
JL_DLLEXPORT jl_value_t *jl_pchar_to_string(const char *str, size_t len)
472472
{
473473
size_t sz = sizeof(size_t) + len + 1; // add space for trailing \nul protector and size
474+
if (sz < len) // overflow
475+
jl_throw(jl_memory_exception);
474476
if (len == 0)
475477
return jl_an_empty_string;
476478
jl_value_t *s = jl_gc_alloc_(jl_get_ptls_states(), sz, jl_string_type); // force inlining
@@ -483,6 +485,8 @@ JL_DLLEXPORT jl_value_t *jl_pchar_to_string(const char *str, size_t len)
483485
JL_DLLEXPORT jl_value_t *jl_alloc_string(size_t len)
484486
{
485487
size_t sz = sizeof(size_t) + len + 1; // add space for trailing \nul protector and size
488+
if (sz < len) // overflow
489+
jl_throw(jl_memory_exception);
486490
if (len == 0)
487491
return jl_an_empty_string;
488492
jl_value_t *s = jl_gc_alloc_(jl_get_ptls_states(), sz, jl_string_type); // force inlining

test/strings/basic.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,8 @@ end
606606
@test repeat(s, 3) === S
607607
@test repeat(S, 3) === S*S*S
608608
end
609+
# Issue #32160 (string allocation unsigned overflow)
610+
@test_throws OutOfMemoryError repeat('x', typemax(Csize_t))
609611
end
610612
@testset "issue #12495: check that logical indexing attempt raises ArgumentError" begin
611613
@test_throws ArgumentError "abc"[[true, false, true]]

test/strings/util.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
@test rpad("αβ", 8, "¹₂³") == "αβ¹₂³¹₂³"
4242
@test lpad("αβ", 9, "¹₂³") == "¹₂³¹₂³¹αβ"
4343
@test rpad("αβ", 9, "¹₂³") == "αβ¹₂³¹₂³¹"
44+
# Issue #32160 (unsigned underflow in lpad/rpad)
45+
@test lpad("xx", UInt(1), " ") == "xx"
46+
@test rpad("xx", UInt(1), " ") == "xx"
4447
end
4548

4649
# string manipulation

0 commit comments

Comments
 (0)