Skip to content

Commit b104cee

Browse files
mbaumanvtjnash
authored andcommitted
Fix off-by-one error in string reallocation (#23493)
and ensure that array to string conversions do not cross GC size boundaries
1 parent 00e2075 commit b104cee

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

src/array.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ JL_DLLEXPORT jl_value_t *jl_array_to_string(jl_array_t *a)
435435
{
436436
if (a->flags.how == 3 && a->offset == 0 && a->elsize == 1 &&
437437
(jl_array_ndims(a) != 1 ||
438-
!(a->maxsize+sizeof(void*)+1 > GC_MAX_SZCLASS && jl_array_nrows(a)+sizeof(void*)+1 <= GC_MAX_SZCLASS))) {
438+
((a->maxsize + sizeof(void*) + 1 <= GC_MAX_SZCLASS) == (jl_array_len(a) + sizeof(void*) + 1 <= GC_MAX_SZCLASS)))) {
439439
jl_value_t *o = jl_array_data_owner(a);
440440
if (jl_is_string(o)) {
441441
a->flags.isshared = 1;
@@ -616,7 +616,8 @@ static int NOINLINE array_resize_buffer(jl_array_t *a, size_t newlen)
616616
nbytes++;
617617
oldnbytes++;
618618
}
619-
if (!a->flags.ptrarray && jl_is_uniontype(jl_tparam0(jl_typeof(a)))) {
619+
int is_discriminated_union = !a->flags.ptrarray && jl_is_uniontype(jl_tparam0(jl_typeof(a)));
620+
if (is_discriminated_union) {
620621
nbytes += newlen;
621622
oldnbytes += oldlen;
622623
}
@@ -627,15 +628,15 @@ static int NOINLINE array_resize_buffer(jl_array_t *a, size_t newlen)
627628
a->data = jl_gc_managed_realloc(olddata, nbytes, oldnbytes,
628629
a->flags.isaligned, (jl_value_t*)a);
629630
}
630-
else if (a->flags.how == 3 && jl_is_string(jl_array_data_owner(a))) {
631+
else if (a->flags.how == 3 && jl_is_string(jl_array_data_owner(a)) && !is_discriminated_union) {
631632
// if data is in a String, keep it that way
632633
jl_value_t *s;
633634
if (a->flags.isshared) {
634-
s = jl_alloc_string(nbytes);
635+
s = jl_alloc_string(nbytes - (elsz == 1));
635636
newbuf = 1;
636637
}
637638
else {
638-
s = jl_gc_realloc_string(jl_array_data_owner(a), nbytes);
639+
s = jl_gc_realloc_string(jl_array_data_owner(a), nbytes - (elsz == 1));
639640
}
640641
jl_array_data_owner(a) = s;
641642
jl_gc_wb(a, s);

0 commit comments

Comments
 (0)