duktape
duktape copied to clipboard
How disable create class in JS code?
I reread a lot in the Wiki on the topic of banning the external constructor, but nowhere did I find C ++ code. Can I prevent the creation of an object from JS code? To give an error like in Chrome
new HTMLDocument ();
VM459: 1 Uncaught TypeError: Illegal constructor
at <anonymous>: 1: 1
But so that there are no problems with creating an object in C ++ code
All Duktape/C functions are "constructable" from script point of view, but you can reject such calls explicitly using https://duktape.org/api.html#duk_is_constructor_call:
if (duk_is_constructor_call(ctx)) {
duk_type_error(ctx, "not constructable");
}
Internally each function actually does have a separate CONSTRUCTABLE flag, and there are some internally created functions which are not constructable. But the C check quoted above produces roughly the same result; there's a small difference in the traceback because the function is entered before the error is thrown. The ability to control the CONSTRUCTABLE flag or create a non-constructable function needs to be added to the API IMO.
As for being able to create the instance from C code, you could use a structure such as this:
static void push_new_instance(duk_context *ctx) {
/* Push and initialize instance; leave it on stack. */
duk_push_object(ctx);
/* ... */
/* Finalize object's internal prototype, to inherit from what you want. */
duk_eval_string(ctx, "HTMLDocument.prototype"); // push whatever object you want to inherit from
duk_set_prototype(ctx, -2);
/* If it matters, set .constructor property. It usually has little impact. */
duk_eval_string(ctx, "HTMLDocument");
duk_put_prop_string(ctx, -2, "prototype");
}
duk_ret_t my_function(duk_context *ctx) {
if (duk_is_constructor_call(ctx)) {
duk_type_error(ctx, "not constructable");
}
/* XXX: Do what you want with a non-constructor call. */
}
Any calls to the constructor via scripts (or even C code) would be rejected. But you'd be able to create instance with push_new_instance()
.
Well, then there is still a small bug, or I don’t know, it can be so. When converting an object to a string, when no toString is specified, [object Object] is returned. Although the prototype object is different.
Could you try evaluating:
instance.toString === Object.prototype.toString
If this is true, then the inheritance chain (internal prototype) is still wrong.
You can also check what the prototype object is using:
Object.getPrototypeOf(instance)
and see which object that returns.
@kirill-782 Any update on this?