Skip to content

Commit 97c9186

Browse files
authored
Fix crashes in DUMP output (#350)
- avoid crashing on invalid atoms in `JS_AtomGetStrRT` - do not dump objects and function_bytecode during `JS_GC_PHASE_REMOVE_CYCLES` phase - fix crash in `print_lines` on null source
1 parent 56593f4 commit 97c9186

File tree

1 file changed

+26
-15
lines changed

1 file changed

+26
-15
lines changed

quickjs.c

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3012,19 +3012,22 @@ static const char *JS_AtomGetStrRT(JSRuntime *rt, char *buf, int buf_size,
30123012
{
30133013
if (__JS_AtomIsTaggedInt(atom)) {
30143014
snprintf(buf, buf_size, "%u", __JS_AtomToUInt32(atom));
3015-
} else {
3016-
JSAtomStruct *p;
3015+
} else if (atom == JS_ATOM_NULL) {
3016+
snprintf(buf, buf_size, "<null>");
3017+
} else if (atom >= rt->atom_size) {
30173018
assert(atom < rt->atom_size);
3018-
if (atom == JS_ATOM_NULL) {
3019-
snprintf(buf, buf_size, "<null>");
3019+
snprintf(buf, buf_size, "<invalid %x>", atom);
3020+
} else {
3021+
JSAtomStruct *p = rt->atom_array[atom];
3022+
if (atom_is_free(p)) {
3023+
assert(!atom_is_free(p));
3024+
snprintf(buf, buf_size, "<free %x>", atom);
30203025
} else {
30213026
int i, c;
30223027
char *q;
30233028
JSString *str;
30243029

30253030
q = buf;
3026-
p = rt->atom_array[atom];
3027-
assert(!atom_is_free(p));
30283031
str = p;
30293032
if (str) {
30303033
if (!str->is_wide_char) {
@@ -5454,12 +5457,16 @@ void __JS_FreeValueRT(JSRuntime *rt, JSValue v)
54545457

54555458
#ifdef DUMP_FREE
54565459
{
5457-
printf("Freeing ");
5458-
if (tag == JS_TAG_OBJECT) {
5459-
JS_DumpObject(rt, JS_VALUE_GET_OBJ(v));
5460-
} else {
5461-
JS_DumpValue(rt, v);
5462-
printf("\n");
5460+
/* Prevent invalid object access during GC */
5461+
if ((rt->gc_phase != JS_GC_PHASE_REMOVE_CYCLES)
5462+
|| (tag != JS_TAG_OBJECT && tag != JS_TAG_FUNCTION_BYTECODE)) {
5463+
printf("Freeing ");
5464+
if (tag == JS_TAG_OBJECT) {
5465+
JS_DumpObject(rt, JS_VALUE_GET_OBJ(v));
5466+
} else {
5467+
JS_DumpValue(rt, v);
5468+
printf("\n");
5469+
}
54635470
}
54645471
}
54655472
#endif
@@ -11708,7 +11715,11 @@ static __maybe_unused void JS_DumpValue(JSRuntime *rt, JSValue val)
1170811715
{
1170911716
JSFunctionBytecode *b = JS_VALUE_GET_PTR(val);
1171011717
char buf[ATOM_GET_STR_BUF_SIZE];
11711-
printf("[bytecode %s]", JS_AtomGetStrRT(rt, buf, sizeof(buf), b->func_name));
11718+
if (b->func_name) {
11719+
printf("[bytecode %s]", JS_AtomGetStrRT(rt, buf, sizeof(buf), b->func_name));
11720+
} else {
11721+
printf("[bytecode (anonymous)]");
11722+
}
1171211723
}
1171311724
break;
1171411725
case JS_TAG_OBJECT:
@@ -27476,7 +27487,7 @@ static void js_free_function_def(JSContext *ctx, JSFunctionDef *fd)
2747627487

2747727488
#ifdef DUMP_BYTECODE
2747827489
static const char *skip_lines(const char *p, int n) {
27479-
while (n-- > 0 && *p) {
27490+
while (p && n-- > 0 && *p) {
2748027491
while (*p && *p++ != '\n')
2748127492
continue;
2748227493
}
@@ -27486,7 +27497,7 @@ static const char *skip_lines(const char *p, int n) {
2748627497
static void print_lines(const char *source, int line, int line1) {
2748727498
const char *s = source;
2748827499
const char *p = skip_lines(s, line);
27489-
if (*p) {
27500+
if (p && *p) {
2749027501
while (line++ < line1) {
2749127502
p = skip_lines(s = p, 1);
2749227503
printf(";; %.*s", (int)(p - s), s);

0 commit comments

Comments
 (0)