From 10c07f9933e148253ecac048e125cc1901de2553 Mon Sep 17 00:00:00 2001 From: Kalle Olavi Niemitalo Date: Sat, 27 Jun 2009 19:48:56 +0300 Subject: [PATCH] Debian bug 534835: Check some SpiderMonkey return values Perhaps because of bug 981, if one opened hundreds of pages with elinks --remote openURL(...), then ELinks 0.11.4 could crash with a SIGSEGV in JS_InitClass called from spidermonkey_get_interpreter. SpiderMonkey ran out of memory and began returning NULL and JS_FALSE but ELinks didn't notice them and pressed on. Add some checks to avoid the crash, although the underlying out-of-memory error remains. --- NEWS | 2 ++ src/ecmascript/spidermonkey.c | 33 +++++++++++++++++++++++---------- src/scripting/smjs/elinks_object.c | 21 ++++++++++++--------- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/NEWS b/NEWS index 595191b9..cda35dfa 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,8 @@ ELinks 0.12pre4.GIT now: To be released as 0.12pre5, 0.12rc1, or even 0.12.0. This branch also includes the changes listed under ``ELinks 0.11.6.GIT now'' below. +* Debian bug 534835: Check the return values of some SpiderMonkey + functions, to avoid crashes if out of memory. * bug 1080: Support ``--dump-color-mode'' with ``--dump-charset UTF-8''. * minor bug 1017: To work around HTTP server bugs, disable protocol.http.compression by default, until ELinks can report diff --git a/src/ecmascript/spidermonkey.c b/src/ecmascript/spidermonkey.c index 267f81c5..78c3bcae 100644 --- a/src/ecmascript/spidermonkey.c +++ b/src/ecmascript/spidermonkey.c @@ -174,57 +174,70 @@ spidermonkey_get_interpreter(struct ecmascript_interpreter *interpreter) JS_SetErrorReporter(ctx, error_reporter); window_obj = JS_NewObject(ctx, (JSClass *) &window_class, NULL, NULL); - if (!window_obj) { - spidermonkey_put_interpreter(interpreter); - return NULL; - } - JS_InitStandardClasses(ctx, window_obj); - JS_DefineProperties(ctx, window_obj, (JSPropertySpec *) window_props); - spidermonkey_DefineFunctions(ctx, window_obj, window_funcs); - JS_SetPrivate(ctx, window_obj, interpreter->vs); /* to @window_class */ + if (!window_obj) goto release_and_fail; + if (!JS_InitStandardClasses(ctx, window_obj)) goto release_and_fail; + if (!JS_DefineProperties(ctx, window_obj, (JSPropertySpec *) window_props)) + goto release_and_fail; + if (!spidermonkey_DefineFunctions(ctx, window_obj, window_funcs)) + goto release_and_fail; + if (!JS_SetPrivate(ctx, window_obj, interpreter->vs)) /* to @window_class */ + goto release_and_fail; document_obj = spidermonkey_InitClass(ctx, window_obj, NULL, (JSClass *) &document_class, NULL, 0, (JSPropertySpec *) document_props, document_funcs, NULL, NULL); + if (!document_obj) goto release_and_fail; forms_obj = spidermonkey_InitClass(ctx, document_obj, NULL, (JSClass *) &forms_class, NULL, 0, (JSPropertySpec *) forms_props, forms_funcs, NULL, NULL); + if (!forms_obj) goto release_and_fail; history_obj = spidermonkey_InitClass(ctx, window_obj, NULL, (JSClass *) &history_class, NULL, 0, (JSPropertySpec *) NULL, history_funcs, NULL, NULL); + if (!history_obj) goto release_and_fail; location_obj = spidermonkey_InitClass(ctx, window_obj, NULL, (JSClass *) &location_class, NULL, 0, (JSPropertySpec *) location_props, location_funcs, NULL, NULL); + if (!location_obj) goto release_and_fail; menubar_obj = JS_InitClass(ctx, window_obj, NULL, (JSClass *) &menubar_class, NULL, 0, (JSPropertySpec *) unibar_props, NULL, NULL, NULL); - JS_SetPrivate(ctx, menubar_obj, "t"); /* to @menubar_class */ + if (!menubar_obj) goto release_and_fail; + if (!JS_SetPrivate(ctx, menubar_obj, "t")) /* to @menubar_class */ + goto release_and_fail; statusbar_obj = JS_InitClass(ctx, window_obj, NULL, (JSClass *) &statusbar_class, NULL, 0, (JSPropertySpec *) unibar_props, NULL, NULL, NULL); - JS_SetPrivate(ctx, statusbar_obj, "s"); /* to @statusbar_class */ + if (!statusbar_obj) goto release_and_fail; + if (!JS_SetPrivate(ctx, statusbar_obj, "s")) /* to @statusbar_class */ + goto release_and_fail; navigator_obj = JS_InitClass(ctx, window_obj, NULL, (JSClass *) &navigator_class, NULL, 0, (JSPropertySpec *) navigator_props, NULL, NULL, NULL); + if (!navigator_obj) goto release_and_fail; return ctx; + +release_and_fail: + spidermonkey_put_interpreter(interpreter); + return NULL; } void diff --git a/src/scripting/smjs/elinks_object.c b/src/scripting/smjs/elinks_object.c index 727bfda6..5a9b3944 100644 --- a/src/scripting/smjs/elinks_object.c +++ b/src/scripting/smjs/elinks_object.c @@ -134,16 +134,19 @@ smjs_get_elinks_object(void) jsobj = spidermonkey_InitClass(smjs_ctx, smjs_global_object, NULL, (JSClass *) &elinks_class, NULL, 0, NULL, elinks_funcs, NULL, NULL); + if (!jsobj) return NULL; - JS_DefineProperty(smjs_ctx, jsobj, "location", JSVAL_NULL, - elinks_get_location, elinks_set_location, - JSPROP_ENUMERATE | JSPROP_PERMANENT); + if (!JS_DefineProperty(smjs_ctx, jsobj, "location", JSVAL_NULL, + elinks_get_location, elinks_set_location, + JSPROP_ENUMERATE | JSPROP_PERMANENT)) + return NULL; - JS_DefineProperty(smjs_ctx, jsobj, "home", JSVAL_NULL, - elinks_get_home, JS_PropertyStub, - JSPROP_ENUMERATE - | JSPROP_PERMANENT - | JSPROP_READONLY); + if (!JS_DefineProperty(smjs_ctx, jsobj, "home", JSVAL_NULL, + elinks_get_home, JS_PropertyStub, + JSPROP_ENUMERATE + | JSPROP_PERMANENT + | JSPROP_READONLY)) + return NULL; return jsobj; } @@ -151,7 +154,7 @@ smjs_get_elinks_object(void) void smjs_init_elinks_object(void) { - smjs_elinks_object = smjs_get_elinks_object(); + smjs_elinks_object = smjs_get_elinks_object(); /* TODO: check NULL */ smjs_init_action_interface(); smjs_init_bookmarks_interface(); -- 2.11.4.GIT