1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-20 00:15:31 +00: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:
Kalle Olavi Niemitalo 2008-06-17 00:25:59 +03:00 committed by Kalle Olavi Niemitalo
parent 28d2c6ef9a
commit ed17eb18df
14 changed files with 144 additions and 47 deletions

2
NEWS
View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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 }

View File

@ -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

View File

@ -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 }

View File

@ -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);

View File

@ -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 }

View File

@ -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);

View 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;
}

View File

@ -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

View File

@ -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 },

View File

@ -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

View File

@ -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,