Closed Bug 630735 Opened 13 years ago Closed 13 years ago

NodeVector isn't GC-safe

Categories

(Core :: JavaScript Engine, defect)

Other Branch
defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: jorendorff, Assigned: dherman)

Details

(Whiteboard: fixed-in-tracemonkey)

Attachments

(1 file)

gczeal(2);
var s = '';
for (var i = 0; i < 1000; i++)
    s += i + ',';
Reflect.parse('[' + s + ']', {loc: false});

Assertion failure: addr % sizeof(FreeCell) == 0, at d:\dev\tracemonkey\js\src\jsgc.h:367


jsreflect.cpp defines NodeVector this way:
    typedef Vector<Value, 8> NodeVector;
and it is only used on the stack. If I understand correctly, that will be safe for the first 8 Values. After that, the vector's storage is malloc'd, and the GC does not pursue the pointer from the Vector to the heap.

So I think it needs to be, instead:
    typedef AutoValueVector NodeVector;
and we'll also have to change every place one is declared, to pass the cx to the constructor.
Group: core-security
Any chance of content getting hold of Reflect or content causing chrome to act on it?
Not exposed to chrome. Shell-only. Unless it, like, uses ctypes to extract the functions from the FF binary. But I'll post a patch asap.

Dave
In that case we don't have to hide this. But yes, please fix.
Group: core-security
Switching to AutoValueVector is trivial (Vector already takes cx in its constructor) but it still crashes on

    gczeal(2), Reflect.parse(uneval(new Array(1000)), {loc:false})

Will investigate.

Dave
This patch includes the suggested fix, and also eliminates the bogus uses of JS_DestroyScript() in shell/js.cpp.

Dave
Assignee: general → dherman
Attachment #509129 - Flags: review?
Attachment #509129 - Flags: review? → review?(jorendorff)
Comment on attachment 509129 [details] [diff] [review]
use AutoValueVector for NodeVector, eliminate JS_DestroyScript

In shell/js.cpp, Load:
>+        ok = !script
>+             ? JS_FALSE
>+             : !compileOnly
>+             ? JS_ExecuteScript(cx, thisobj, script, NULL)
>+             : JS_TRUE;
>         if (!ok)
>             return JS_FALSE;
>     }

Thanks for getting rid of these JS_DestroyScript calls. Merely as a matter of style, please change these lines to:

        if (!script)
            return JS_FALSE;

        if (!compileOnly && !JS_ExecuteScript(cx, thisobj, script, NULL))
            return JS_FALSE;
    }

r=me with that.
Attachment #509129 - Flags: review?(jorendorff) → review+
Or, if you really want to write an expression, avoid ?: expressions with true or false in one arm:

 a ? false : b => a && b
 a ? true : b  => a || b

(with !! as needed to canonicalize ints as bools).

/be
http://hg.mozilla.org/tracemonkey/rev/53403b41c153
Whiteboard: fixed-in-tracemonkey
Late for a drive-by, just wanted to say: please use true and false now, not JS_TRUE and JS_FALSE, even with JSBool return type. The C++ bools convert nicely. It's the other direction that requires !!.

/be
> a ? false : b => a && b

Er, of course:

  a ? b : false => a && b

/be
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: