Bug 640339: Ensure that generate-id doesn't leak heap addresses. r=peterv a=dveditz
authorJonas Sicking <jonas@sicking.cc>
Mon, 14 Mar 2011 21:49:53 -0700
changeset 27357 768b54fa2f7d795e61e2d0805fa9ea28d6e4de62
parent 27356 70422c4a7277ab056f797164c42332022806b26b
child 27358 f510ce76c1471bca5c9c9d21f2c983596d99e433
push id2689
push usersicking@mozilla.com
push dateTue, 15 Mar 2011 04:52:00 +0000
reviewerspeterv, dveditz
bugs640339
milestone1.9.1.18pre
Bug 640339: Ensure that generate-id doesn't leak heap addresses. r=peterv a=dveditz
content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
content/xslt/src/xpath/txXPathTreeWalker.h
content/xslt/src/xslt/txGenerateIdFunctionCall.cpp
--- a/content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
+++ b/content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
@@ -623,25 +623,27 @@ const char gPrintfFmtAttr[] = "id0x%08p-
 #define kFmtSizeAttr 32
 const char gPrintfFmt[] = "id0x%016p";
 const char gPrintfFmtAttr[] = "id0x%016p-%010i";
 #endif
 
 /* static */
 nsresult
 txXPathNodeUtils::getXSLTId(const txXPathNode& aNode,
+                            const txXPathNode& aBase,
                             nsAString& aResult)
 {
+    PRUword nodeid = ((PRUword)aNode.mNode) - ((PRUword)aBase.mNode);
     if (!aNode.isAttribute()) {
-        CopyASCIItoUTF16(nsPrintfCString(kFmtSize, gPrintfFmt, aNode.mNode),
+        CopyASCIItoUTF16(nsPrintfCString(kFmtSize, gPrintfFmt, nodeid),
                          aResult);
     }
     else {
         CopyASCIItoUTF16(nsPrintfCString(kFmtSizeAttr, gPrintfFmtAttr,
-                                         aNode.mNode, aNode.mIndex), aResult);
+                                         nodeid, aNode.mIndex), aResult);
     }
 
     return NS_OK;
 }
 
 /* static */
 void
 txXPathNodeUtils::getBaseURI(const txXPathNode& aNode, nsAString& aURI)
--- a/content/xslt/src/xpath/txXPathTreeWalker.h
+++ b/content/xslt/src/xpath/txXPathTreeWalker.h
@@ -122,17 +122,18 @@ public:
     static PRInt32 getNamespaceID(const txXPathNode& aNode);
     static void getNamespaceURI(const txXPathNode& aNode, nsAString& aURI);
     static PRUint16 getNodeType(const txXPathNode& aNode);
     static void appendNodeValue(const txXPathNode& aNode, nsAString& aResult);
     static PRBool isWhitespace(const txXPathNode& aNode);
     static txXPathNode* getDocument(const txXPathNode& aNode);
     static txXPathNode* getOwnerDocument(const txXPathNode& aNode);
     static PRInt32 getUniqueIdentifier(const txXPathNode& aNode);
-    static nsresult getXSLTId(const txXPathNode& aNode, nsAString& aResult);
+    static nsresult getXSLTId(const txXPathNode& aNode,
+                              const txXPathNode& aBase, nsAString& aResult);
     static void release(txXPathNode* aNode);
     static void getBaseURI(const txXPathNode& aNode, nsAString& aURI);
     static PRIntn comparePosition(const txXPathNode& aNode,
                                   const txXPathNode& aOtherNode);
     static PRBool localNameEquals(const txXPathNode& aNode,
                                   nsIAtom* aLocalName);
     static PRBool isRoot(const txXPathNode& aNode);
     static PRBool isElement(const txXPathNode& aNode);
--- a/content/xslt/src/xslt/txGenerateIdFunctionCall.cpp
+++ b/content/xslt/src/xslt/txGenerateIdFunctionCall.cpp
@@ -35,16 +35,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "txAtoms.h"
 #include "txIXPathContext.h"
 #include "txNodeSet.h"
 #include "txXPathTreeWalker.h"
 #include "txXSLTFunctions.h"
+#include "txExecutionState.h"
 
 /*
   Implementation of XSLT 1.0 extension function: generate-id
 */
 
 /**
  * Creates a new generate-id function call
 **/
@@ -63,23 +64,32 @@ GenerateIdFunctionCall::GenerateIdFuncti
 nsresult
 GenerateIdFunctionCall::evaluate(txIEvalContext* aContext,
                                  txAExprResult** aResult)
 {
     *aResult = nsnull;
     if (!requireParams(0, 1, aContext))
         return NS_ERROR_XPATH_BAD_ARGUMENT_COUNT;
 
+    txExecutionState* es = 
+        static_cast<txExecutionState*>(aContext->getPrivateContext());
+    if (!es) {
+        NS_ERROR(
+            "called xslt extension function \"current\" with wrong context");
+        return NS_ERROR_UNEXPECTED;
+    }
+
     nsresult rv = NS_OK;
     if (mParams.IsEmpty()) {
         StringResult* strRes;
         rv = aContext->recycler()->getStringResult(&strRes);
         NS_ENSURE_SUCCESS(rv, rv);
 
         txXPathNodeUtils::getXSLTId(aContext->getContextNode(),
+                                    es->getSourceDocument(),
                                     strRes->mValue);
 
         *aResult = strRes;
  
         return NS_OK;
     }
 
     nsRefPtr<txNodeSet> nodes;
@@ -92,17 +102,18 @@ GenerateIdFunctionCall::evaluate(txIEval
 
         return NS_OK;
     }
     
     StringResult* strRes;
     rv = aContext->recycler()->getStringResult(&strRes);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    txXPathNodeUtils::getXSLTId(nodes->get(0), strRes->mValue);
+    txXPathNodeUtils::getXSLTId(nodes->get(0), es->getSourceDocument(),
+                                strRes->mValue);
 
     *aResult = strRes;
  
     return NS_OK;
 }
 
 Expr::ResultType
 GenerateIdFunctionCall::getReturnType()