mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
Bug 1016: Avoid JSFunctionSpec.
(cherry picked from commit 6bfaa7ca8d
)
Conflicts:
src/ecmascript/spidermonkey/form.c
src/scripting/smjs/elinks_object.c
This commit is contained in:
parent
28d2c6ef9a
commit
ed17eb18df
2
NEWS
2
NEWS
@ -311,6 +311,8 @@ To be released as 0.11.4.
|
||||
* critical bug 945: don't crash if a Lua script calls e.g. error(nil)
|
||||
* critical bug 1003: don't crash if a smart URI rewrite template gets
|
||||
too few parameters
|
||||
* critical bug 1016: avoid JSFunctionSpec for better compatibility
|
||||
across versions of SpiderMonkey
|
||||
* major bug 956: don't reuse pointers to SpiderMonkey objects that may
|
||||
have been collected as garbage. This fix causes bug 954.
|
||||
* CVE-2007-2027: check if the program path contains "src/" before
|
||||
|
@ -183,32 +183,32 @@ spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter)
|
||||
}
|
||||
JS_InitStandardClasses(ctx, window_obj);
|
||||
JS_DefineProperties(ctx, window_obj, (JSPropertySpec *) window_props);
|
||||
JS_DefineFunctions(ctx, window_obj, (JSFunctionSpec *) window_funcs);
|
||||
spidermonkey_DefineFunctions(ctx, window_obj, window_funcs);
|
||||
JS_SetPrivate(ctx, window_obj, interpreter->vs); /* to @window_class */
|
||||
|
||||
document_obj = JS_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &document_class, NULL, 0,
|
||||
(JSPropertySpec *) document_props,
|
||||
(JSFunctionSpec *) document_funcs,
|
||||
NULL, NULL);
|
||||
document_obj = spidermonkey_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &document_class, NULL, 0,
|
||||
(JSPropertySpec *) document_props,
|
||||
document_funcs,
|
||||
NULL, NULL);
|
||||
|
||||
forms_obj = JS_InitClass(ctx, document_obj, NULL,
|
||||
(JSClass *) &forms_class, NULL, 0,
|
||||
(JSPropertySpec *) forms_props,
|
||||
(JSFunctionSpec *) forms_funcs,
|
||||
NULL, NULL);
|
||||
forms_obj = spidermonkey_InitClass(ctx, document_obj, NULL,
|
||||
(JSClass *) &forms_class, NULL, 0,
|
||||
(JSPropertySpec *) forms_props,
|
||||
forms_funcs,
|
||||
NULL, NULL);
|
||||
|
||||
history_obj = JS_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &history_class, NULL, 0,
|
||||
(JSPropertySpec *) NULL,
|
||||
(JSFunctionSpec *) history_funcs,
|
||||
NULL, NULL);
|
||||
history_obj = spidermonkey_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &history_class, NULL, 0,
|
||||
(JSPropertySpec *) NULL,
|
||||
history_funcs,
|
||||
NULL, NULL);
|
||||
|
||||
location_obj = JS_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &location_class, NULL, 0,
|
||||
(JSPropertySpec *) location_props,
|
||||
(JSFunctionSpec *) location_funcs,
|
||||
NULL, NULL);
|
||||
location_obj = spidermonkey_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &location_class, NULL, 0,
|
||||
(JSPropertySpec *) location_props,
|
||||
location_funcs,
|
||||
NULL, NULL);
|
||||
|
||||
menubar_obj = JS_InitClass(ctx, window_obj, NULL,
|
||||
(JSClass *) &menubar_class, NULL, 0,
|
||||
|
@ -2,6 +2,6 @@ top_builddir=../../..
|
||||
include $(top_builddir)/Makefile.config
|
||||
INCLUDES += $(SPIDERMONKEY_CFLAGS)
|
||||
|
||||
OBJS = document.o form.o location.o navigator.o unibar.o window.o
|
||||
OBJS = document.o form.o location.o navigator.o unibar.o util.o window.o
|
||||
|
||||
include $(top_srcdir)/Makefile.lib
|
||||
|
@ -245,7 +245,7 @@ document_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
static JSBool document_write(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
static JSBool document_writeln(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
const JSFunctionSpec document_funcs[] = {
|
||||
const spidermonkeyFunctionSpec document_funcs[] = {
|
||||
{ "write", document_write, 1 },
|
||||
{ "writeln", document_writeln, 1 },
|
||||
{ NULL }
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "ecmascript/spidermonkey/util.h"
|
||||
|
||||
extern const JSClass document_class;
|
||||
extern const JSFunctionSpec document_funcs[];
|
||||
extern const spidermonkeyFunctionSpec document_funcs[];
|
||||
extern const JSPropertySpec document_props[];
|
||||
|
||||
#endif
|
||||
|
@ -133,7 +133,7 @@ static JSBool input_click(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv
|
||||
static JSBool input_focus(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
static JSBool input_select(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
static const JSFunctionSpec input_funcs[] = {
|
||||
static const spidermonkeyFunctionSpec input_funcs[] = {
|
||||
{ "blur", input_blur, 0 },
|
||||
{ "click", input_click, 0 },
|
||||
{ "focus", input_focus, 0 },
|
||||
@ -567,7 +567,7 @@ get_input_object(JSContext *ctx, JSObject *jsform, long number)
|
||||
JSObject *jsinput = JS_NewObject(ctx, (JSClass *) &input_class, NULL, jsform);
|
||||
|
||||
JS_DefineProperties(ctx, jsinput, (JSPropertySpec *) input_props);
|
||||
JS_DefineFunctions(ctx, jsinput, (JSFunctionSpec *) input_funcs);
|
||||
spidermonkey_DefineFunctions(ctx, jsinput, input_funcs);
|
||||
JS_SetReservedSlot(ctx, jsinput, JSRS_INPUT_FSINDEX, INT_TO_JSVAL(number));
|
||||
return jsinput;;
|
||||
}
|
||||
@ -616,7 +616,7 @@ static const JSClass form_elements_class = {
|
||||
static JSBool form_elements_item(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
static JSBool form_elements_namedItem(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
static const JSFunctionSpec form_elements_funcs[] = {
|
||||
static const spidermonkeyFunctionSpec form_elements_funcs[] = {
|
||||
{ "item", form_elements_item, 1 },
|
||||
{ "namedItem", form_elements_namedItem, 1 },
|
||||
{ NULL }
|
||||
@ -855,7 +855,7 @@ static const JSPropertySpec form_props[] = {
|
||||
static JSBool form_reset(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
static JSBool form_submit(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
static const JSFunctionSpec form_funcs[] = {
|
||||
static const spidermonkeyFunctionSpec form_funcs[] = {
|
||||
{ "reset", form_reset, 0 },
|
||||
{ "submit", form_submit, 0 },
|
||||
{ NULL }
|
||||
@ -933,7 +933,8 @@ form_get_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
JSObject *jsform_elems = JS_NewObject(ctx, (JSClass *) &form_elements_class, NULL, obj);
|
||||
|
||||
JS_DefineProperties(ctx, jsform_elems, (JSPropertySpec *) form_elements_props);
|
||||
JS_DefineFunctions(ctx, jsform_elems, (JSFunctionSpec *) form_elements_funcs);
|
||||
spidermonkey_DefineFunctions(ctx, jsform_elems,
|
||||
form_elements_funcs);
|
||||
object_to_jsval(ctx, vp, jsform_elems);
|
||||
/* SM will cache this property value for us so we create this
|
||||
* just once per form. */
|
||||
@ -1162,7 +1163,7 @@ get_form_object(JSContext *ctx, JSObject *jsdoc, struct form_view *fv)
|
||||
JSObject *jsform = JS_NewObject(ctx, (JSClass *) &form_class, NULL, jsdoc);
|
||||
|
||||
JS_DefineProperties(ctx, jsform, (JSPropertySpec *) form_props);
|
||||
JS_DefineFunctions(ctx, jsform, (JSFunctionSpec *) form_funcs);
|
||||
spidermonkey_DefineFunctions(ctx, jsform, form_funcs);
|
||||
JS_SetPrivate(ctx, jsform, fv); /* to @form_class */
|
||||
fv->ecmascript_obj = jsform;
|
||||
return fv->ecmascript_obj;
|
||||
@ -1181,7 +1182,7 @@ const JSClass forms_class = {
|
||||
static JSBool forms_item(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
static JSBool forms_namedItem(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
const JSFunctionSpec forms_funcs[] = {
|
||||
const spidermonkeyFunctionSpec forms_funcs[] = {
|
||||
{ "item", forms_item, 1 },
|
||||
{ "namedItem", forms_namedItem, 1 },
|
||||
{ NULL }
|
||||
|
@ -7,7 +7,7 @@
|
||||
struct form_view;
|
||||
|
||||
extern const JSClass forms_class;
|
||||
extern const JSFunctionSpec forms_funcs[];
|
||||
extern const spidermonkeyFunctionSpec forms_funcs[];
|
||||
extern const JSPropertySpec forms_props[];
|
||||
|
||||
JSObject *get_form_object(JSContext *ctx, JSObject *jsdoc, struct form_view *fv);
|
||||
|
@ -57,7 +57,7 @@ const JSClass history_class = {
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
};
|
||||
|
||||
const JSFunctionSpec history_funcs[] = {
|
||||
const spidermonkeyFunctionSpec history_funcs[] = {
|
||||
{ "back", history_back, 0 },
|
||||
{ "forward", history_forward, 0 },
|
||||
{ "go", history_go, 1 },
|
||||
@ -224,7 +224,7 @@ location_set_property(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
|
||||
static JSBool location_toString(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
const JSFunctionSpec location_funcs[] = {
|
||||
const spidermonkeyFunctionSpec location_funcs[] = {
|
||||
{ "toString", location_toString, 0 },
|
||||
{ "toLocaleString", location_toString, 0 },
|
||||
{ NULL }
|
||||
|
@ -7,10 +7,10 @@
|
||||
struct document_view;
|
||||
|
||||
extern const JSClass history_class;
|
||||
extern const JSFunctionSpec history_funcs[];
|
||||
extern const spidermonkeyFunctionSpec history_funcs[];
|
||||
|
||||
extern const JSClass location_class;
|
||||
extern const JSFunctionSpec location_funcs[];
|
||||
extern const spidermonkeyFunctionSpec location_funcs[];
|
||||
extern const JSPropertySpec location_props[];
|
||||
|
||||
void location_goto(struct document_view *doc_view, unsigned char *url);
|
||||
|
60
src/ecmascript/spidermonkey/util.c
Normal file
60
src/ecmascript/spidermonkey/util.c
Normal file
@ -0,0 +1,60 @@
|
||||
/* Better compatibility across versions of SpiderMonkey. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "elinks.h"
|
||||
|
||||
#include "ecmascript/spidermonkey/util.h"
|
||||
|
||||
/** An ELinks-specific replacement for JS_DefineFunctions().
|
||||
*
|
||||
* @relates spidermonkeyFunctionSpec */
|
||||
JSBool
|
||||
spidermonkey_DefineFunctions(JSContext *cx, JSObject *obj,
|
||||
const spidermonkeyFunctionSpec *fs)
|
||||
{
|
||||
for (; fs->name; fs++) {
|
||||
if (!JS_DefineFunction(cx, obj, fs->name, fs->call,
|
||||
fs->nargs, 0))
|
||||
return JS_FALSE;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/** An ELinks-specific replacement for JS_InitClass().
|
||||
*
|
||||
* @relates spidermonkeyFunctionSpec */
|
||||
JSObject *
|
||||
spidermonkey_InitClass(JSContext *cx, JSObject *obj,
|
||||
JSObject *parent_proto, JSClass *clasp,
|
||||
JSNative constructor, uintN nargs,
|
||||
JSPropertySpec *ps,
|
||||
const spidermonkeyFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps,
|
||||
const spidermonkeyFunctionSpec *static_fs)
|
||||
{
|
||||
JSObject *proto = JS_InitClass(cx, obj, parent_proto, clasp,
|
||||
constructor, nargs,
|
||||
ps, NULL, static_ps, NULL);
|
||||
|
||||
if (proto == NULL)
|
||||
return NULL;
|
||||
|
||||
if (fs) {
|
||||
if (!spidermonkey_DefineFunctions(cx, proto, fs))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (static_fs) {
|
||||
JSObject *cons_obj = JS_GetConstructor(cx, proto);
|
||||
|
||||
if (cons_obj == NULL)
|
||||
return NULL;
|
||||
if (!spidermonkey_DefineFunctions(cx, cons_obj, static_fs))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
@ -99,4 +99,29 @@ jsval_to_string(JSContext *ctx, jsval *vp)
|
||||
return empty_string_or_(JS_GetStringBytes(JS_ValueToString(ctx, val)));
|
||||
}
|
||||
|
||||
/** An ELinks-specific replacement for JSFunctionSpec.
|
||||
*
|
||||
* Bug 1016: In SpiderMonkey 1.7 bundled with XULRunner 1.8, jsapi.h
|
||||
* defines JSFunctionSpec in different ways depending on whether
|
||||
* MOZILLA_1_8_BRANCH is defined, and there is no obvious way for
|
||||
* ELinks to check whether MOZILLA_1_8_BRANCH was defined when the
|
||||
* library was built. Avoid the unstable JSFunctionSpec definitions
|
||||
* and use this ELinks-specific structure instead. */
|
||||
typedef struct spidermonkeyFunctionSpec {
|
||||
const char *name;
|
||||
JSNative call;
|
||||
uint8 nargs;
|
||||
/* ELinks does not use "flags" and "extra" so omit them here. */
|
||||
} spidermonkeyFunctionSpec;
|
||||
|
||||
JSBool spidermonkey_DefineFunctions(JSContext *cx, JSObject *obj,
|
||||
const spidermonkeyFunctionSpec *fs);
|
||||
JSObject *spidermonkey_InitClass(JSContext *cx, JSObject *obj,
|
||||
JSObject *parent_proto, JSClass *clasp,
|
||||
JSNative constructor, uintN nargs,
|
||||
JSPropertySpec *ps,
|
||||
const spidermonkeyFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps,
|
||||
const spidermonkeyFunctionSpec *static_fs);
|
||||
|
||||
#endif
|
||||
|
@ -302,7 +302,7 @@ static JSBool window_alert(JSContext *ctx, JSObject *obj, uintN argc, jsval *arg
|
||||
static JSBool window_open(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
static JSBool window_setTimeout(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
const JSFunctionSpec window_funcs[] = {
|
||||
const spidermonkeyFunctionSpec window_funcs[] = {
|
||||
{ "alert", window_alert, 1 },
|
||||
{ "open", window_open, 3 },
|
||||
{ "setTimeout", window_setTimeout, 2 },
|
||||
|
@ -6,6 +6,6 @@
|
||||
|
||||
extern const JSClass window_class;
|
||||
extern const JSPropertySpec window_props[];
|
||||
extern const JSFunctionSpec window_funcs[];
|
||||
extern const spidermonkeyFunctionSpec window_funcs[];
|
||||
|
||||
#endif
|
||||
|
@ -69,7 +69,7 @@ elinks_set_location(JSContext *ctx, JSObject *obj, jsval id, jsval *vp)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* @elinks_funcs{"alert"} */
|
||||
/* function "alert" in the object returned by smjs_get_elinks_object() */
|
||||
static JSBool
|
||||
elinks_alert(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
@ -90,7 +90,7 @@ elinks_alert(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* @elinks_funcs{"execute"} */
|
||||
/* function "execute" in the object returned by smjs_get_elinks_object() */
|
||||
static JSBool
|
||||
elinks_execute(JSContext *ctx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
@ -117,12 +117,6 @@ static const JSClass elinks_class = {
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
};
|
||||
|
||||
static const JSFunctionSpec elinks_funcs[] = {
|
||||
{ "alert", elinks_alert, 1 },
|
||||
{ "execute", elinks_execute, 1 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static JSObject *
|
||||
smjs_get_elinks_object(void)
|
||||
{
|
||||
@ -133,7 +127,22 @@ smjs_get_elinks_object(void)
|
||||
|
||||
jsobj = JS_InitClass(smjs_ctx, smjs_global_object, NULL,
|
||||
(JSClass *) &elinks_class, NULL, 0, NULL,
|
||||
(JSFunctionSpec *) elinks_funcs, NULL, NULL);
|
||||
(JSFunctionSpec *) NULL, NULL, NULL);
|
||||
|
||||
/* Bug 1016: In SpiderMonkey 1.7 bundled with XULRunner 1.8,
|
||||
* jsapi.h defines JSFunctionSpec in different ways depending
|
||||
* on whether MOZILLA_1_8_BRANCH is defined, and there is no
|
||||
* obvious way for ELinks to check whether MOZILLA_1_8_BRANCH
|
||||
* was defined when the library was built. Avoid the unstable
|
||||
* JSFunctionSpec definitions and instead use JS_DefineFunction
|
||||
* directly.
|
||||
*
|
||||
* In elinks/src/ecmascript/spidermonkey/, there is an
|
||||
* ELinks-specific replacement for JSFunctionSpec; however, to
|
||||
* keep the modules independent, elinks/src/scripting/smjs/
|
||||
* does not use that. */
|
||||
JS_DefineFunction(smjs_ctx, jsobj, "alert", elinks_alert, 1, 0);
|
||||
JS_DefineFunction(smjs_ctx, jsobj, "execute", elinks_execute, 1, 0);
|
||||
|
||||
JS_DefineProperty(smjs_ctx, jsobj, "location", JSVAL_NULL,
|
||||
elinks_get_location, elinks_set_location,
|
||||
|
Loading…
Reference in New Issue
Block a user