mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-30 01:59:29 +00:00
Clean up the XDR properly even if JS_XDRScript fails. In particular, don't
double-free things. Bug 387572, r+sr=brendan
This commit is contained in:
parent
611a83d517
commit
10326593c7
@ -369,37 +369,37 @@ ReadScriptFromStream(JSContext *cx, nsIObjectInputStream *stream,
|
||||
xdr->userdata = stream;
|
||||
JS_XDRMemSetData(xdr, data, size);
|
||||
|
||||
if (JS_XDRScript(xdr, script)) {
|
||||
// Update data in case ::JS_XDRScript called back into C++ code to
|
||||
// read an XPCOM object.
|
||||
//
|
||||
// In that case, the serialization process must have flushed a run
|
||||
// of counted bytes containing JS data at the point where the XPCOM
|
||||
// object starts, after which an encoding C++ callback from the JS
|
||||
// XDR code must have written the XPCOM object directly into the
|
||||
// nsIObjectOutputStream.
|
||||
//
|
||||
// The deserialization process will XDR-decode counted bytes up to
|
||||
// but not including the XPCOM object, then call back into C++ to
|
||||
// read the object, then read more counted bytes and hand them off
|
||||
// to the JSXDRState, so more JS data can be decoded.
|
||||
//
|
||||
// This interleaving of JS XDR data and XPCOM object data may occur
|
||||
// several times beneath the call to ::JS_XDRScript, above. At the
|
||||
// end of the day, we need to free (via nsMemory) the data owned by
|
||||
// the JSXDRState. So we steal it back, nulling xdr's buffer so it
|
||||
// doesn't get passed to ::JS_free by ::JS_XDRDestroy.
|
||||
|
||||
uint32 length;
|
||||
data = static_cast<char*>(JS_XDRMemGetData(xdr, &length));
|
||||
if (data) {
|
||||
JS_XDRMemSetData(xdr, nsnull, 0);
|
||||
}
|
||||
JS_XDRDestroy(xdr);
|
||||
} else {
|
||||
if (!JS_XDRScript(xdr, script)) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Update data in case ::JS_XDRScript called back into C++ code to
|
||||
// read an XPCOM object.
|
||||
//
|
||||
// In that case, the serialization process must have flushed a run
|
||||
// of counted bytes containing JS data at the point where the XPCOM
|
||||
// object starts, after which an encoding C++ callback from the JS
|
||||
// XDR code must have written the XPCOM object directly into the
|
||||
// nsIObjectOutputStream.
|
||||
//
|
||||
// The deserialization process will XDR-decode counted bytes up to
|
||||
// but not including the XPCOM object, then call back into C++ to
|
||||
// read the object, then read more counted bytes and hand them off
|
||||
// to the JSXDRState, so more JS data can be decoded.
|
||||
//
|
||||
// This interleaving of JS XDR data and XPCOM object data may occur
|
||||
// several times beneath the call to ::JS_XDRScript, above. At the
|
||||
// end of the day, we need to free (via nsMemory) the data owned by
|
||||
// the JSXDRState. So we steal it back, nulling xdr's buffer so it
|
||||
// doesn't get passed to ::JS_free by ::JS_XDRDestroy.
|
||||
|
||||
uint32 length;
|
||||
data = static_cast<char*>(JS_XDRMemGetData(xdr, &length));
|
||||
if (data) {
|
||||
JS_XDRMemSetData(xdr, nsnull, 0);
|
||||
}
|
||||
JS_XDRDestroy(xdr);
|
||||
|
||||
// If data is null now, it must have been freed while deserializing an
|
||||
// XPCOM object (e.g., a principal) beneath ::JS_XDRScript.
|
||||
if (data) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user