Skip to content

Commit 1c89535

Browse files
authored
fix #34159, crash in deserialize caused by recent layout changes (#34163)
1 parent 4a8ea8c commit 1c89535

File tree

1 file changed

+40
-33
lines changed

1 file changed

+40
-33
lines changed

src/dump.c

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,25 +1082,46 @@ static void jl_serialize_value_(jl_serializer_state *s, jl_value_t *v, int as_li
10821082
}
10831083

10841084
char *data = (char*)jl_data_ptr(v);
1085-
size_t i, np = t->layout->npointers;
1086-
const char *start = data;
1087-
for (i = 0; i < np; i++) {
1088-
uint32_t ptr = jl_ptr_offset(t, i);
1089-
jl_value_t **fld = &((jl_value_t**)data)[ptr];
1090-
if ((const char*)fld != start)
1091-
ios_write(s->s, start, (const char*)fld - start);
1092-
jl_value_t *e = *fld;
1093-
JL_GC_PROMISE_ROOTED(e);
1094-
if (t->mutabl && e && jl_is_cpointer(e) && jl_unbox_voidpointer(e) != (void*)-1 && jl_unbox_voidpointer(e) != NULL)
1095-
// reset Ptr fields to C_NULL (but keep MAP_FAILED / INVALID_HANDLE)
1096-
jl_serialize_cnull(s, jl_typeof(e));
1097-
else
1098-
jl_serialize_value(s, e);
1099-
start = (const char*)&fld[1];
1100-
}
1101-
data += jl_datatype_size(t);
1102-
if (data != start)
1103-
ios_write(s->s, start, data - start);
1085+
size_t i, j, np = t->layout->npointers;
1086+
uint32_t nf = t->layout->nfields;
1087+
char *last = data;
1088+
for (i = 0, j = 0; i < nf+1; i++) {
1089+
char *ptr = data + (i < nf ? jl_field_offset(t, i) : jl_datatype_size(t));
1090+
if (j < np) {
1091+
char *prevptr = (char*)&((jl_value_t**)data)[jl_ptr_offset(t, j)];
1092+
while (ptr > prevptr) {
1093+
// previous field contained pointers; write them and their interleaved data
1094+
if (prevptr > last)
1095+
ios_write(s->s, last, prevptr - last);
1096+
jl_value_t *e = *(jl_value_t**)prevptr;
1097+
JL_GC_PROMISE_ROOTED(e);
1098+
if (t->mutabl && e && jl_field_isptr(t, i - 1) && jl_is_cpointer(e) &&
1099+
jl_unbox_voidpointer(e) != (void*)-1 && jl_unbox_voidpointer(e) != NULL)
1100+
// reset Ptr fields to C_NULL (but keep MAP_FAILED / INVALID_HANDLE)
1101+
jl_serialize_cnull(s, jl_typeof(e));
1102+
else
1103+
jl_serialize_value(s, e);
1104+
last = prevptr + sizeof(jl_value_t*);
1105+
j++;
1106+
if (j < np)
1107+
prevptr = (char*)&((jl_value_t**)data)[jl_ptr_offset(t, j)];
1108+
else
1109+
break;
1110+
}
1111+
}
1112+
if (i == nf)
1113+
break;
1114+
if (t->mutabl && jl_is_cpointer_type(jl_field_type(t, i)) && *(void**)ptr != (void*)-1) {
1115+
if (ptr > last)
1116+
ios_write(s->s, last, ptr - last);
1117+
char *n = NULL;
1118+
ios_write(s->s, (char*)&n, sizeof(n));
1119+
last = ptr + sizeof(n);
1120+
}
1121+
}
1122+
char *ptr = data + jl_datatype_size(t);
1123+
if (ptr > last)
1124+
ios_write(s->s, last, ptr - last);
11041125
}
11051126
}
11061127

@@ -1943,20 +1964,6 @@ static void jl_deserialize_struct(jl_serializer_state *s, jl_value_t *v) JL_GC_D
19431964
data += jl_datatype_size(dt);
19441965
if (data != start)
19451966
ios_read(s->s, start, data - start);
1946-
if (dt->mutabl) {
1947-
char *data = (char*)jl_data_ptr(v);
1948-
uint32_t nf = dt->layout->nfields;
1949-
for (i = 0; i < nf; i++) {
1950-
jl_value_t *t = jl_field_type(dt, i);
1951-
if (jl_is_cpointer_type(t)) {
1952-
// reset Ptr fields to C_NULL
1953-
// (although permit MAP_FAILED / INVALID_HANDLE to remain unchanged)
1954-
size_t ptr = jl_field_offset(dt, i);
1955-
if (*(void**)(data + ptr) != (void*)-1)
1956-
*(void**)(data + ptr) = NULL;
1957-
}
1958-
}
1959-
}
19601967
if (dt == jl_typemap_entry_type) {
19611968
jl_typemap_entry_t *entry = (jl_typemap_entry_t*)v;
19621969
if (entry->max_world == ~(size_t)0) {

0 commit comments

Comments
 (0)