Skip to content

Commit 20ad74a

Browse files
committed
Avoid reading TypedData type after dfree
[Bug #22101] (Backport)
1 parent b823e24 commit 20ad74a

1 file changed

Lines changed: 14 additions & 6 deletions

File tree

gc.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3476,29 +3476,37 @@ obj_free_object_id(rb_objspace_t *objspace, VALUE obj)
34763476
static bool
34773477
rb_data_free(rb_objspace_t *objspace, VALUE obj)
34783478
{
3479-
void *data = RTYPEDDATA_P(obj) ? RTYPEDDATA_GET_DATA(obj) : DATA_PTR(obj);
3479+
bool typed = RTYPEDDATA_P(obj);
3480+
void *data = typed ? RTYPEDDATA_GET_DATA(obj) : DATA_PTR(obj);
34803481
if (data) {
34813482
int free_immediately = false;
3483+
bool embedded = false;
3484+
bool free_embeddable_data = false;
34823485
void (*dfree)(void *);
34833486

3484-
if (RTYPEDDATA_P(obj)) {
3485-
free_immediately = (RANY(obj)->as.typeddata.type->flags & RUBY_TYPED_FREE_IMMEDIATELY) != 0;
3486-
dfree = RANY(obj)->as.typeddata.type->function.dfree;
3487+
if (typed) {
3488+
const rb_data_type_t *type = RTYPEDDATA_TYPE(obj);
3489+
dfree = type->function.dfree;
3490+
if (dfree) {
3491+
embedded = RTYPEDDATA_EMBEDDED_P(obj);
3492+
free_immediately = (type->flags & RUBY_TYPED_FREE_IMMEDIATELY) != 0;
3493+
free_embeddable_data = (type->flags & RUBY_TYPED_EMBEDDABLE) && !embedded;
3494+
}
34873495
}
34883496
else {
34893497
dfree = RANY(obj)->as.data.dfree;
34903498
}
34913499

34923500
if (dfree) {
34933501
if (dfree == RUBY_DEFAULT_FREE) {
3494-
if (!RTYPEDDATA_P(obj) || !RTYPEDDATA_EMBEDDED_P(obj)) {
3502+
if (!typed || !embedded) {
34953503
xfree(data);
34963504
RB_DEBUG_COUNTER_INC(obj_data_xfree);
34973505
}
34983506
}
34993507
else if (free_immediately) {
35003508
(*dfree)(data);
3501-
if (RTYPEDDATA_TYPE(obj)->flags & RUBY_TYPED_EMBEDDABLE && !RTYPEDDATA_EMBEDDED_P(obj)) {
3509+
if (free_embeddable_data) {
35023510
xfree(data);
35033511
}
35043512

0 commit comments

Comments
 (0)