Skip to content

Commit a53f20e

Browse files
StefanKarpinskiKristofferC
authored andcommitted
fix reinterpret(Char, ::UInt32) for "unnatural" values (fix #29181) (#29192)
This code was assuming that character values only have bit-patterns that decoding a string can produce, but of course `reinterpret` can produce any bit pattern in a `Char` whatsoever. The fix doesn't use that assumption and only uses the cache for actual ASCII characters. (cherry picked from commit 88f74b7)
1 parent 073e5f4 commit a53f20e

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

src/datatype.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -688,8 +688,9 @@ static jl_value_t *boxed_char_cache[128];
688688
JL_DLLEXPORT jl_value_t *jl_box_char(uint32_t x)
689689
{
690690
jl_ptls_t ptls = jl_get_ptls_states();
691-
if (0 < (int32_t)x)
692-
return boxed_char_cache[x >> 24];
691+
uint32_t u = bswap_32(x);
692+
if (u < 128)
693+
return boxed_char_cache[(uint8_t)u];
693694
jl_value_t *v = jl_gc_alloc(ptls, sizeof(void*), jl_char_type);
694695
*(uint32_t*)jl_data_ptr(v) = x;
695696
return v;

test/char.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,10 @@ Base.codepoint(c::ASCIIChar) = reinterpret(UInt8, c)
256256
@test_throws MethodError write(IOBuffer(), ASCIIChar('x'))
257257
@test_throws MethodError read(IOBuffer('x'), ASCIIChar)
258258
end
259+
260+
@testset "reinterpret(Char, ::UInt32)" begin
261+
for s = 0:31
262+
u = one(UInt32) << s
263+
@test reinterpret(UInt32, reinterpret(Char, u)) === u
264+
end
265+
end

0 commit comments

Comments
 (0)