shithub: libmujs

Download patch

ref: eed8a67a496bedd388858b45dab2b7210bdedd6e
parent: 70a299c76bc26bfe9bfbe2264abc8d39bea66fee
author: Tor Andersson <tor.andersson@artifex.com>
date: Mon Dec 6 10:40:50 EST 2021

Bug 704750 and 704751: Save transient js_toobject in stack slot.

Prevent use-after-free if GC is triggered while a js_toobject is held.

This is the same stack clobbering approach used for js_tostring, etc.

--- a/jsvalue.c
+++ b/jsvalue.c
@@ -385,17 +385,21 @@
 /* ToObject() on a value */
 js_Object *jsV_toobject(js_State *J, js_Value *v)
 {
+	js_Object *o;
 	switch (v->type) {
 	default:
-	case JS_TSHRSTR: return jsV_newstring(J, v->u.shrstr);
 	case JS_TUNDEFINED: js_typeerror(J, "cannot convert undefined to object");
 	case JS_TNULL: js_typeerror(J, "cannot convert null to object");
-	case JS_TBOOLEAN: return jsV_newboolean(J, v->u.boolean);
-	case JS_TNUMBER: return jsV_newnumber(J, v->u.number);
-	case JS_TLITSTR: return jsV_newstring(J, v->u.litstr);
-	case JS_TMEMSTR: return jsV_newstring(J, v->u.memstr->p);
 	case JS_TOBJECT: return v->u.object;
+	case JS_TSHRSTR: o = jsV_newstring(J, v->u.shrstr); break;
+	case JS_TLITSTR: o = jsV_newstring(J, v->u.litstr); break;
+	case JS_TMEMSTR: o = jsV_newstring(J, v->u.memstr->p); break;
+	case JS_TBOOLEAN: o = jsV_newboolean(J, v->u.boolean); break;
+	case JS_TNUMBER: o = jsV_newnumber(J, v->u.number); break;
 	}
+	v->type = JS_TOBJECT;
+	v->u.object = o;
+	return o;
 }
 
 void js_newobjectx(js_State *J)