mirror of
https://github.com/bellard/quickjs.git
synced 2024-11-22 21:58:12 +08:00
Fix runtime bugs
- fix string leak in `js_printf_internal` on errors - read `errno` before potential side effects in `js_os_stat`
This commit is contained in:
parent
c9e6c56c70
commit
48deab1aeb
@ -150,7 +150,7 @@ static JSValue js_printf_internal(JSContext *ctx,
|
|||||||
uint8_t cbuf[UTF8_CHAR_LEN_MAX+1];
|
uint8_t cbuf[UTF8_CHAR_LEN_MAX+1];
|
||||||
JSValue res;
|
JSValue res;
|
||||||
DynBuf dbuf;
|
DynBuf dbuf;
|
||||||
const char *fmt_str;
|
const char *fmt_str = NULL;
|
||||||
const uint8_t *fmt, *fmt_end;
|
const uint8_t *fmt, *fmt_end;
|
||||||
const uint8_t *p;
|
const uint8_t *p;
|
||||||
char *q;
|
char *q;
|
||||||
@ -251,7 +251,7 @@ static JSValue js_printf_internal(JSContext *ctx,
|
|||||||
string_arg = JS_ToCString(ctx, argv[i++]);
|
string_arg = JS_ToCString(ctx, argv[i++]);
|
||||||
if (!string_arg)
|
if (!string_arg)
|
||||||
goto fail;
|
goto fail;
|
||||||
int32_arg = unicode_from_utf8((uint8_t *)string_arg, UTF8_CHAR_LEN_MAX, &p);
|
int32_arg = unicode_from_utf8((const uint8_t *)string_arg, UTF8_CHAR_LEN_MAX, &p);
|
||||||
JS_FreeCString(ctx, string_arg);
|
JS_FreeCString(ctx, string_arg);
|
||||||
} else {
|
} else {
|
||||||
if (JS_ToInt32(ctx, &int32_arg, argv[i++]))
|
if (JS_ToInt32(ctx, &int32_arg, argv[i++]))
|
||||||
@ -355,6 +355,7 @@ static JSValue js_printf_internal(JSContext *ctx,
|
|||||||
return res;
|
return res;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
JS_FreeCString(ctx, fmt_str);
|
||||||
dbuf_free(&dbuf);
|
dbuf_free(&dbuf);
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
}
|
}
|
||||||
@ -2532,12 +2533,14 @@ static JSValue js_os_stat(JSContext *ctx, JSValueConst this_val,
|
|||||||
else
|
else
|
||||||
res = stat(path, &st);
|
res = stat(path, &st);
|
||||||
#endif
|
#endif
|
||||||
|
if (res < 0)
|
||||||
|
err = errno;
|
||||||
|
else
|
||||||
|
err = 0;
|
||||||
JS_FreeCString(ctx, path);
|
JS_FreeCString(ctx, path);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
err = errno;
|
|
||||||
obj = JS_NULL;
|
obj = JS_NULL;
|
||||||
} else {
|
} else {
|
||||||
err = 0;
|
|
||||||
obj = JS_NewObject(ctx);
|
obj = JS_NewObject(ctx);
|
||||||
if (JS_IsException(obj))
|
if (JS_IsException(obj))
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
|
20
quickjs.c
20
quickjs.c
@ -598,7 +598,7 @@ typedef struct JSFunctionBytecode {
|
|||||||
uint8_t backtrace_barrier : 1; /* stop backtrace on this function */
|
uint8_t backtrace_barrier : 1; /* stop backtrace on this function */
|
||||||
uint8_t read_only_bytecode : 1;
|
uint8_t read_only_bytecode : 1;
|
||||||
uint8_t is_direct_or_indirect_eval : 1; /* used by JS_GetScriptOrModuleName() */
|
uint8_t is_direct_or_indirect_eval : 1; /* used by JS_GetScriptOrModuleName() */
|
||||||
/* XXX: 4 bits available */
|
/* XXX: 10 bits available */
|
||||||
uint8_t *byte_code_buf; /* (self pointer) */
|
uint8_t *byte_code_buf; /* (self pointer) */
|
||||||
int byte_code_len;
|
int byte_code_len;
|
||||||
JSAtom func_name;
|
JSAtom func_name;
|
||||||
@ -1042,13 +1042,11 @@ static JSValue JS_EvalObject(JSContext *ctx, JSValueConst this_obj,
|
|||||||
JSValueConst val, int flags, int scope_idx);
|
JSValueConst val, int flags, int scope_idx);
|
||||||
JSValue __attribute__((format(printf, 2, 3))) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...);
|
JSValue __attribute__((format(printf, 2, 3))) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...);
|
||||||
static __maybe_unused void JS_DumpAtoms(JSRuntime *rt);
|
static __maybe_unused void JS_DumpAtoms(JSRuntime *rt);
|
||||||
static __maybe_unused void JS_DumpString(JSRuntime *rt,
|
static __maybe_unused void JS_DumpString(JSRuntime *rt, const JSString *p);
|
||||||
const JSString *p);
|
|
||||||
static __maybe_unused void JS_DumpObjectHeader(JSRuntime *rt);
|
static __maybe_unused void JS_DumpObjectHeader(JSRuntime *rt);
|
||||||
static __maybe_unused void JS_DumpObject(JSRuntime *rt, JSObject *p);
|
static __maybe_unused void JS_DumpObject(JSRuntime *rt, JSObject *p);
|
||||||
static __maybe_unused void JS_DumpGCObject(JSRuntime *rt, JSGCObjectHeader *p);
|
static __maybe_unused void JS_DumpGCObject(JSRuntime *rt, JSGCObjectHeader *p);
|
||||||
static __maybe_unused void JS_DumpValueShort(JSRuntime *rt,
|
static __maybe_unused void JS_DumpValueShort(JSRuntime *rt, JSValueConst val);
|
||||||
JSValueConst val);
|
|
||||||
static __maybe_unused void JS_DumpValue(JSContext *ctx, JSValueConst val);
|
static __maybe_unused void JS_DumpValue(JSContext *ctx, JSValueConst val);
|
||||||
static __maybe_unused void JS_PrintValue(JSContext *ctx,
|
static __maybe_unused void JS_PrintValue(JSContext *ctx,
|
||||||
const char *str,
|
const char *str,
|
||||||
@ -1057,14 +1055,11 @@ static __maybe_unused void JS_DumpShapes(JSRuntime *rt);
|
|||||||
static JSValue js_function_apply(JSContext *ctx, JSValueConst this_val,
|
static JSValue js_function_apply(JSContext *ctx, JSValueConst this_val,
|
||||||
int argc, JSValueConst *argv, int magic);
|
int argc, JSValueConst *argv, int magic);
|
||||||
static void js_array_finalizer(JSRuntime *rt, JSValue val);
|
static void js_array_finalizer(JSRuntime *rt, JSValue val);
|
||||||
static void js_array_mark(JSRuntime *rt, JSValueConst val,
|
static void js_array_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func);
|
||||||
JS_MarkFunc *mark_func);
|
|
||||||
static void js_object_data_finalizer(JSRuntime *rt, JSValue val);
|
static void js_object_data_finalizer(JSRuntime *rt, JSValue val);
|
||||||
static void js_object_data_mark(JSRuntime *rt, JSValueConst val,
|
static void js_object_data_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func);
|
||||||
JS_MarkFunc *mark_func);
|
|
||||||
static void js_c_function_finalizer(JSRuntime *rt, JSValue val);
|
static void js_c_function_finalizer(JSRuntime *rt, JSValue val);
|
||||||
static void js_c_function_mark(JSRuntime *rt, JSValueConst val,
|
static void js_c_function_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func);
|
||||||
JS_MarkFunc *mark_func);
|
|
||||||
static void js_bytecode_function_finalizer(JSRuntime *rt, JSValue val);
|
static void js_bytecode_function_finalizer(JSRuntime *rt, JSValue val);
|
||||||
static void js_bytecode_function_mark(JSRuntime *rt, JSValueConst val,
|
static void js_bytecode_function_mark(JSRuntime *rt, JSValueConst val,
|
||||||
JS_MarkFunc *mark_func);
|
JS_MarkFunc *mark_func);
|
||||||
@ -4190,7 +4185,7 @@ static JSValue JS_ConcatString1(JSContext *ctx,
|
|||||||
return JS_MKPTR(JS_TAG_STRING, p);
|
return JS_MKPTR(JS_TAG_STRING, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* op1 and op2 are converted to strings. For convience, op1 or op2 =
|
/* op1 and op2 are converted to strings. For convenience, op1 or op2 =
|
||||||
JS_EXCEPTION are accepted and return JS_EXCEPTION. */
|
JS_EXCEPTION are accepted and return JS_EXCEPTION. */
|
||||||
static JSValue JS_ConcatString(JSContext *ctx, JSValue op1, JSValue op2)
|
static JSValue JS_ConcatString(JSContext *ctx, JSValue op1, JSValue op2)
|
||||||
{
|
{
|
||||||
@ -17157,6 +17152,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
|
|||||||
|
|
||||||
op1 = sp[-1];
|
op1 = sp[-1];
|
||||||
pc += 4;
|
pc += 4;
|
||||||
|
/* quick and dirty test for JS_TAG_INT, JS_TAG_BOOL, JS_TAG_NULL and JS_TAG_UNDEFINED */
|
||||||
if ((uint32_t)JS_VALUE_GET_TAG(op1) <= JS_TAG_UNDEFINED) {
|
if ((uint32_t)JS_VALUE_GET_TAG(op1) <= JS_TAG_UNDEFINED) {
|
||||||
res = JS_VALUE_GET_INT(op1);
|
res = JS_VALUE_GET_INT(op1);
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user