Piotr Caban : msxml3: Don't use libxml namespaces stack.

Alexandre Julliard julliard at winehq.org
Mon Oct 31 12:49:07 CDT 2011


Module: wine
Branch: master
Commit: 619c2dcd08654e27665713f25c767066a6bf1d11
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=619c2dcd08654e27665713f25c767066a6bf1d11

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon Oct 31 12:32:59 2011 +0100

msxml3: Don't use libxml namespaces stack.

---

 dlls/msxml3/saxreader.c |  116 +++++++++++++++++++++++++++++++++++-----------
 1 files changed, 88 insertions(+), 28 deletions(-)

diff --git a/dlls/msxml3/saxreader.c b/dlls/msxml3/saxreader.c
index 2045863..35b0c04 100644
--- a/dlls/msxml3/saxreader.c
+++ b/dlls/msxml3/saxreader.c
@@ -115,7 +115,12 @@ typedef struct _saxlocator
     BOOL vbInterface;
     int nsStackSize;
     int nsStackLast;
-    int *nsStack;
+    struct nsstack
+    {
+        const xmlChar *ptr;
+        BSTR prefix;
+        BSTR uri;
+    } *nsStack;
 
     int attributesSize;
     int nb_attributes;
@@ -255,27 +260,57 @@ static inline BOOL has_error_handler(const saxlocator *locator)
           (!locator->vbInterface && locator->saxreader->errorHandler);
 }
 
-static HRESULT namespacePush(saxlocator *locator, int ns)
+static HRESULT namespacePush(saxlocator *locator, const xmlChar *prefix,
+        const xmlChar *uri)
 {
     if(locator->nsStackLast>=locator->nsStackSize)
     {
-        int *new_stack;
+        struct nsstack *new_stack;
 
         new_stack = HeapReAlloc(GetProcessHeap(), 0,
-                locator->nsStack, sizeof(int)*locator->nsStackSize*2);
+                locator->nsStack, sizeof(struct nsstack)*locator->nsStackSize*2);
         if(!new_stack) return E_OUTOFMEMORY;
         locator->nsStack = new_stack;
         locator->nsStackSize *= 2;
     }
-    locator->nsStack[locator->nsStackLast++] = ns;
+
+    locator->nsStack[locator->nsStackLast].ptr = uri;
+    if(uri)
+    {
+        locator->nsStack[locator->nsStackLast].prefix = bstr_from_xmlChar(prefix);
+        if(!locator->nsStack[locator->nsStackLast].prefix)
+            return E_OUTOFMEMORY;
+        locator->nsStack[locator->nsStackLast].uri = bstr_from_xmlChar(uri);
+        if(!locator->nsStack[locator->nsStackLast].uri)
+        {
+            SysFreeString(locator->nsStack[locator->nsStackLast].prefix);
+            return E_OUTOFMEMORY;
+        }
+    }
+    else
+    {
+        locator->nsStack[locator->nsStackLast].prefix = NULL;
+        locator->nsStack[locator->nsStackLast].uri = NULL;
+    }
+
+    locator->nsStackLast++;
 
     return S_OK;
 }
 
-static int namespacePop(saxlocator *locator)
+static HRESULT namespacePop(saxlocator *locator)
 {
-    if(locator->nsStackLast == 0) return 0;
-    return locator->nsStack[--locator->nsStackLast];
+    if(locator->nsStackLast == 0)
+    {
+        ERR("namespace stack is empty\n");
+        return E_UNEXPECTED;
+    }
+
+    SysFreeString(locator->nsStack[--locator->nsStackLast].prefix);
+    SysFreeString(locator->nsStack[locator->nsStackLast].uri);
+    locator->nsStack[locator->nsStackLast].prefix = NULL;
+    locator->nsStack[locator->nsStackLast].uri = NULL;
+    return S_OK;
 }
 
 static BOOL bstr_pool_insert(struct bstrpool *pool, BSTR pool_entry)
@@ -1165,7 +1200,16 @@ static void libxmlStartElementNS(
         index++;
     update_position(This, (xmlChar*)This->pParserCtxt->input->cur+index);
 
-    hr = namespacePush(This, nb_namespaces);
+    hr = namespacePush(This, NULL, NULL);
+    for(index=0; hr==S_OK && index<nb_namespaces; index++)
+        hr = namespacePush(This, namespaces[2*index], namespaces[2*index+1]);
+    if(hr != S_OK)
+    {
+        for(; index>=0; index--)
+            namespacePop(This);
+        namespacePop(This);
+    }
+
     if(hr==S_OK && has_content_handler(This))
     {
         for(index=0; index<nb_namespaces; index++)
@@ -1217,11 +1261,11 @@ static void libxmlEndElementNS(
         const xmlChar *prefix,
         const xmlChar *URI)
 {
-    BSTR NamespaceUri, LocalName, QName, Prefix;
+    BSTR NamespaceUri, LocalName, QName;
     saxlocator *This = ctx;
     HRESULT hr;
     xmlChar *end;
-    int nsNr, index;
+    struct nsstack *elem = &This->nsStack[This->nsStackLast-1];
 
     end = (xmlChar*)This->pParserCtxt->input->cur;
     if(This->saxreader->version >= MSXML6) {
@@ -1234,8 +1278,6 @@ static void libxmlEndElementNS(
 
     update_position(This, end);
 
-    nsNr = namespacePop(This);
-
     if(has_content_handler(This))
     {
         NamespaceUri = pooled_bstr_from_xmlChar(&This->saxreader->pool, URI);
@@ -1263,53 +1305,69 @@ static void libxmlEndElementNS(
 
         if(This->saxreader->version >= MSXML6)
         {
-            for(index=This->pParserCtxt->nsNr-nsNr*2;
-                    index<This->pParserCtxt->nsNr; index+=2)
-            {
-                Prefix = pooled_bstr_from_xmlChar(&This->saxreader->pool, This->pParserCtxt->nsTab[index]);
+            while(elem->ptr) {
+                elem--;
+            }
+            elem++;
 
+            while(elem < &This->nsStack[This->nsStackLast]) {
                 if(This->vbInterface)
                     hr = IVBSAXContentHandler_endPrefixMapping(
-                            This->saxreader->vbcontentHandler, &Prefix);
+                            This->saxreader->vbcontentHandler, &elem->prefix);
                 else
                     hr = ISAXContentHandler_endPrefixMapping(
                             This->saxreader->contentHandler,
-                            Prefix, SysStringLen(Prefix));
+                            elem->prefix, SysStringLen(elem->prefix));
 
-                if(FAILED(hr))
+                if(hr != S_OK)
                 {
                     format_error_message_from_id(This, hr);
                     return;
                 }
+
+                elem++;
+            }
+
+            elem--;
+            while(elem->ptr) {
+                namespacePop(This);
+                elem--;
             }
         }
         else
         {
-            for(index=This->pParserCtxt->nsNr-2;
-                    index>=This->pParserCtxt->nsNr-nsNr*2; index-=2)
-            {
-                Prefix = pooled_bstr_from_xmlChar(&This->saxreader->pool, This->pParserCtxt->nsTab[index]);
+            while(1) {
+                if(!elem->ptr)
+                    break;
 
                 if(This->vbInterface)
                     hr = IVBSAXContentHandler_endPrefixMapping(
-                            This->saxreader->vbcontentHandler, &Prefix);
+                            This->saxreader->vbcontentHandler, &elem->prefix);
                 else
                     hr = ISAXContentHandler_endPrefixMapping(
                             This->saxreader->contentHandler,
-                            Prefix, SysStringLen(Prefix));
+                            elem->prefix, SysStringLen(elem->prefix));
 
-                if(hr != S_OK)
+                if(FAILED(hr))
                 {
                     format_error_message_from_id(This, hr);
                     return;
                 }
+
+                namespacePop(This);
+                elem--;
             }
         }
     }
     else
     {
         This->nb_attributes = 0;
+        while(elem->ptr) {
+            namespacePop(This);
+            elem--;
+        }
     }
+    namespacePop(This);
 
     update_position(This, NULL);
 }
@@ -1806,6 +1864,8 @@ static ULONG WINAPI isaxlocator_Release(
 
         SysFreeString(This->publicId);
         SysFreeString(This->systemId);
+        while(This->nsStackLast)
+            namespacePop(This);
         heap_free(This->nsStack);
 
         for(index=0; index<This->nb_attributes; index++)
@@ -1927,7 +1987,7 @@ static HRESULT SAXLocator_create(saxreader *reader, saxlocator **ppsaxlocator, B
     locator->ret = S_OK;
     locator->nsStackSize = 8;
     locator->nsStackLast = 0;
-    locator->nsStack = heap_alloc(sizeof(int)*locator->nsStackSize);
+    locator->nsStack = heap_alloc(sizeof(struct nsstack)*locator->nsStackSize);
     if(!locator->nsStack)
     {
         ISAXXMLReader_Release(&reader->ISAXXMLReader_iface);




More information about the wine-cvs mailing list