Skip to content

Commit

Permalink
fix reinterpret(Char, ::UInt32) for "unnatural" values (fix #29181) (#…
Browse files Browse the repository at this point in the history
…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)
  • Loading branch information
StefanKarpinski authored and KristofferC committed Feb 11, 2019
1 parent b3f1310 commit 4e8c807
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/datatype.c
Original file line number Diff line number Diff line change
Expand Up @@ -688,8 +688,9 @@ static jl_value_t *boxed_char_cache[128];
JL_DLLEXPORT jl_value_t *jl_box_char(uint32_t x)
{
jl_ptls_t ptls = jl_get_ptls_states();
if (0 < (int32_t)x)
return boxed_char_cache[x >> 24];
uint32_t u = bswap_32(x);
if (u < 128)
return boxed_char_cache[(uint8_t)u];
jl_value_t *v = jl_gc_alloc(ptls, sizeof(void*), jl_char_type);
*(uint32_t*)jl_data_ptr(v) = x;
return v;
Expand Down
7 changes: 7 additions & 0 deletions test/char.jl
Original file line number Diff line number Diff line change
Expand Up @@ -256,3 +256,10 @@ Base.codepoint(c::ASCIIChar) = reinterpret(UInt8, c)
@test_throws MethodError write(IOBuffer(), ASCIIChar('x'))
@test_throws MethodError read(IOBuffer('x'), ASCIIChar)
end

@testset "reinterpret(Char, ::UInt32)" begin
for s = 0:31
u = one(UInt32) << s
@test reinterpret(UInt32, reinterpret(Char, u)) === u
end
end

0 comments on commit 4e8c807

Please sign in to comment.