mirror of
https://github.com/bellard/quickjs.git
synced 2024-11-22 21:58:12 +08:00
fixed crash when resizing property shapes in case of OOM (github issue #129)
This commit is contained in:
parent
7414e5f67f
commit
b4d80502b6
41
quickjs.c
41
quickjs.c
@ -4468,6 +4468,7 @@ static no_inline int resize_properties(JSContext *ctx, JSShape **psh,
|
|||||||
JSShapeProperty *pr;
|
JSShapeProperty *pr;
|
||||||
void *sh_alloc;
|
void *sh_alloc;
|
||||||
intptr_t h;
|
intptr_t h;
|
||||||
|
JSShape *old_sh;
|
||||||
|
|
||||||
sh = *psh;
|
sh = *psh;
|
||||||
new_size = max_int(count, sh->prop_size * 3 / 2);
|
new_size = max_int(count, sh->prop_size * 3 / 2);
|
||||||
@ -4483,19 +4484,21 @@ static no_inline int resize_properties(JSContext *ctx, JSShape **psh,
|
|||||||
new_hash_size = sh->prop_hash_mask + 1;
|
new_hash_size = sh->prop_hash_mask + 1;
|
||||||
while (new_hash_size < new_size)
|
while (new_hash_size < new_size)
|
||||||
new_hash_size = 2 * new_hash_size;
|
new_hash_size = 2 * new_hash_size;
|
||||||
|
/* resize the property shapes. Using js_realloc() is not possible in
|
||||||
|
case the GC runs during the allocation */
|
||||||
|
old_sh = sh;
|
||||||
|
sh_alloc = js_malloc(ctx, get_shape_size(new_hash_size, new_size));
|
||||||
|
if (!sh_alloc)
|
||||||
|
return -1;
|
||||||
|
sh = get_shape_from_alloc(sh_alloc, new_hash_size);
|
||||||
|
list_del(&old_sh->header.link);
|
||||||
|
/* copy all the shape properties */
|
||||||
|
memcpy(sh, old_sh,
|
||||||
|
sizeof(JSShape) + sizeof(sh->prop[0]) * old_sh->prop_count);
|
||||||
|
list_add_tail(&sh->header.link, &ctx->rt->gc_obj_list);
|
||||||
|
|
||||||
if (new_hash_size != (sh->prop_hash_mask + 1)) {
|
if (new_hash_size != (sh->prop_hash_mask + 1)) {
|
||||||
JSShape *old_sh;
|
|
||||||
/* resize the hash table and the properties */
|
/* resize the hash table and the properties */
|
||||||
old_sh = sh;
|
|
||||||
sh_alloc = js_malloc(ctx, get_shape_size(new_hash_size, new_size));
|
|
||||||
if (!sh_alloc)
|
|
||||||
return -1;
|
|
||||||
sh = get_shape_from_alloc(sh_alloc, new_hash_size);
|
|
||||||
list_del(&old_sh->header.link);
|
|
||||||
/* copy all the fields and the properties */
|
|
||||||
memcpy(sh, old_sh,
|
|
||||||
sizeof(JSShape) + sizeof(sh->prop[0]) * old_sh->prop_count);
|
|
||||||
list_add_tail(&sh->header.link, &ctx->rt->gc_obj_list);
|
|
||||||
new_hash_mask = new_hash_size - 1;
|
new_hash_mask = new_hash_size - 1;
|
||||||
sh->prop_hash_mask = new_hash_mask;
|
sh->prop_hash_mask = new_hash_mask;
|
||||||
memset(prop_hash_end(sh) - new_hash_size, 0,
|
memset(prop_hash_end(sh) - new_hash_size, 0,
|
||||||
@ -4507,20 +4510,12 @@ static no_inline int resize_properties(JSContext *ctx, JSShape **psh,
|
|||||||
prop_hash_end(sh)[-h - 1] = i + 1;
|
prop_hash_end(sh)[-h - 1] = i + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
js_free(ctx, get_alloc_from_shape(old_sh));
|
|
||||||
} else {
|
} else {
|
||||||
/* only resize the properties */
|
/* just copy the previous hash table */
|
||||||
list_del(&sh->header.link);
|
memcpy(prop_hash_end(sh) - new_hash_size, prop_hash_end(old_sh) - new_hash_size,
|
||||||
sh_alloc = js_realloc(ctx, get_alloc_from_shape(sh),
|
sizeof(prop_hash_end(sh)[0]) * new_hash_size);
|
||||||
get_shape_size(new_hash_size, new_size));
|
|
||||||
if (unlikely(!sh_alloc)) {
|
|
||||||
/* insert again in the GC list */
|
|
||||||
list_add_tail(&sh->header.link, &ctx->rt->gc_obj_list);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
sh = get_shape_from_alloc(sh_alloc, new_hash_size);
|
|
||||||
list_add_tail(&sh->header.link, &ctx->rt->gc_obj_list);
|
|
||||||
}
|
}
|
||||||
|
js_free(ctx, get_alloc_from_shape(old_sh));
|
||||||
*psh = sh;
|
*psh = sh;
|
||||||
sh->prop_size = new_size;
|
sh->prop_size = new_size;
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user