Improve deserializer error message for bytecode

Don't raise a "invalid tag 12" exception when encountering bytecode
and JS_READ_OBJ_BYTECODE is not set, because no one knows what "tag 12"
means without looking it up, not even quickjs maintainers.
This commit is contained in:
Ben Noordhuis 2024-10-24 09:09:40 +02:00
parent 4fbce79521
commit 0a79b84ef9
3 changed files with 32 additions and 3 deletions

View file

@ -837,6 +837,7 @@ static JSValue js_evalScript(JSContext *ctx, JSValue this_val,
JSValue ret; JSValue ret;
JSValue options_obj; JSValue options_obj;
BOOL backtrace_barrier = FALSE; BOOL backtrace_barrier = FALSE;
BOOL compile_only = FALSE;
BOOL is_async = FALSE; BOOL is_async = FALSE;
int flags; int flags;
@ -845,6 +846,9 @@ static JSValue js_evalScript(JSContext *ctx, JSValue this_val,
if (get_bool_option(ctx, &backtrace_barrier, options_obj, if (get_bool_option(ctx, &backtrace_barrier, options_obj,
"backtrace_barrier")) "backtrace_barrier"))
return JS_EXCEPTION; return JS_EXCEPTION;
if (get_bool_option(ctx, &compile_only, options_obj,
"compile_only"))
return JS_EXCEPTION;
if (get_bool_option(ctx, &is_async, options_obj, if (get_bool_option(ctx, &is_async, options_obj,
"async")) "async"))
return JS_EXCEPTION; return JS_EXCEPTION;
@ -860,6 +864,8 @@ static JSValue js_evalScript(JSContext *ctx, JSValue this_val,
flags = JS_EVAL_TYPE_GLOBAL; flags = JS_EVAL_TYPE_GLOBAL;
if (backtrace_barrier) if (backtrace_barrier)
flags |= JS_EVAL_FLAG_BACKTRACE_BARRIER; flags |= JS_EVAL_FLAG_BACKTRACE_BARRIER;
if (compile_only)
flags |= JS_EVAL_FLAG_COMPILE_ONLY;
if (is_async) if (is_async)
flags |= JS_EVAL_FLAG_ASYNC; flags |= JS_EVAL_FLAG_ASYNC;
ret = JS_Eval(ctx, str, len, "<evalScript>", flags); ret = JS_Eval(ctx, str, len, "<evalScript>", flags);

View file

@ -35473,12 +35473,14 @@ static JSValue JS_ReadObjectRec(BCReaderState *s)
break; break;
case BC_TAG_FUNCTION_BYTECODE: case BC_TAG_FUNCTION_BYTECODE:
if (!s->allow_bytecode) if (!s->allow_bytecode)
goto invalid_tag; goto no_allow_bytecode;
obj = JS_ReadFunctionTag(s); obj = JS_ReadFunctionTag(s);
break; break;
case BC_TAG_MODULE: case BC_TAG_MODULE:
if (!s->allow_bytecode) if (!s->allow_bytecode) {
goto invalid_tag; no_allow_bytecode:
return JS_ThrowSyntaxError(ctx, "no bytecode allowed");
}
obj = JS_ReadModule(s); obj = JS_ReadModule(s);
break; break;
case BC_TAG_OBJECT: case BC_TAG_OBJECT:

View file

@ -1,3 +1,4 @@
import * as std from "std";
import * as bjson from "bjson"; import * as bjson from "bjson";
import { assert } from "./assert.js"; import { assert } from "./assert.js";
@ -227,6 +228,25 @@ function bjson_test_symbol()
assert(o, r); assert(o, r);
} }
function bjson_test_bytecode()
{
var buf, o, r, e;
o = std.evalScript(";(function f(o){ return o.i })", {compile_only: true});
buf = bjson.write(o, /*JS_WRITE_OBJ_BYTECODE*/(1 << 0));
try {
bjson.read(buf, 0, buf.byteLength);
} catch (_e) {
e = _e;
}
assert(String(e), "SyntaxError: no bytecode allowed");
// can't really do anything with |o| at the moment,
// no way to pass it to JS_EvalFunction
o = bjson.read(buf, 0, buf.byteLength, /*JS_READ_OBJ_BYTECODE*/(1 << 0));
assert(String(o), "[function bytecode]");
}
function bjson_test_fuzz() function bjson_test_fuzz()
{ {
var corpus = [ var corpus = [
@ -277,6 +297,7 @@ function bjson_test_all()
bjson_test_map(); bjson_test_map();
bjson_test_set(); bjson_test_set();
bjson_test_symbol(); bjson_test_symbol();
bjson_test_bytecode();
bjson_test_fuzz(); bjson_test_fuzz();
} }