From 10326593c7f4ca4e55f81bc39805e0ccd0d0d3e5 Mon Sep 17 00:00:00 2001 From: "bzbarsky@mit.edu" Date: Tue, 10 Jul 2007 20:10:43 -0700 Subject: [PATCH] Clean up the XDR properly even if JS_XDRScript fails. In particular, don't double-free things. Bug 387572, r+sr=brendan --- .../xpconnect/loader/mozJSComponentLoader.cpp | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/js/src/xpconnect/loader/mozJSComponentLoader.cpp b/js/src/xpconnect/loader/mozJSComponentLoader.cpp index 44969aca19e7..f0454c06b546 100644 --- a/js/src/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/src/xpconnect/loader/mozJSComponentLoader.cpp @@ -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(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(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) {