Nikolay Sivov : msxml3: Fix ignorable whitespace detection in case of formatting text nodes.

Alexandre Julliard julliard at winehq.org
Wed May 15 14:20:00 CDT 2013


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed May 15 00:18:07 2013 +0400

msxml3: Fix ignorable whitespace detection in case of formatting text nodes.

---

 dlls/msxml3/domdoc.c       |   12 +++++++++---
 dlls/msxml3/tests/domdoc.c |   33 +++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c
index e98fa72..4c7237a 100644
--- a/dlls/msxml3/domdoc.c
+++ b/dlls/msxml3/domdoc.c
@@ -416,20 +416,26 @@ static void sax_characters(void *ctx, const xmlChar *ch, int len)
 
     if (ctxt->node)
     {
+        xmlChar cur = *(ctxt->input->cur);
+
         /* Characters are reported with multiple calls, for example each charref is reported with a separate
            call and then parser appends it to a single text node or creates a new node if not created.
            It's not possible to tell if it's ignorable data or not just looking at data itself cause it could be
-           a space chars that separate charrefs or similar case. We only need to skip leading and trailing spaces,
+           space chars that separate charrefs or similar case. We only need to skip leading and trailing spaces,
            or whole node if it has nothing but space chars, so to detect leading space node->last is checked that
            contains text node pointer if already created, trailing spaces are detected directly looking at parser input
-           for next '<' opening bracket - similar logic is used by libxml2 itself.
+           for next '<' opening bracket - similar logic is used by libxml2 itself. Basically 'cur' == '<' means the last
+           chunk of char data, in case it's not the last chunk we check for previously added node type and if it's not
+           a text node it's safe to ignore.
 
            Note that during domdoc_loadXML() the xmlDocPtr->_private data is not available. */
+
         if (!This->properties->preserving &&
             !is_preserving_whitespace(ctxt->node) &&
             strn_isspace(ch, len) &&
             (!ctxt->node->last ||
-            ((ctxt->node->last && (*ctxt->input->cur) == '<'))))
+            ((ctxt->node->last && (cur == '<' || ctxt->node->last->type != XML_TEXT_NODE))
+           )))
             return;
     }
 
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index cc79d4b..20b9609 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -385,6 +385,15 @@ static const WCHAR szComplete6[] = {
     '<','o','p','e','n','>','<','/','o','p','e','n','>','\n',0
 };
 
+static const char complete7[] = {
+    "<?xml version=\"1.0\"?>\n\t"
+    "<root>\n"
+    "\t<a/>\n"
+    "\t<b/>\n"
+    "\t<c/>\n"
+    "</root>"
+};
+
 #define DECL_WIN_1252 \
 "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
 
@@ -4212,7 +4221,11 @@ static void test_preserve_charref(IXMLDOMDocument2 *doc, VARIANT_BOOL preserve)
 static void test_whitespace(void)
 {
     IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4;
+    IXMLDOMNodeList *list;
+    IXMLDOMElement *root;
     VARIANT_BOOL b;
+    HRESULT hr;
+    LONG len;
 
     doc1 = create_document(&IID_IXMLDOMDocument2);
     doc2 = create_document(&IID_IXMLDOMDocument2);
@@ -4286,6 +4299,26 @@ static void test_whitespace(void)
     /* text with char references */
     test_preserve_charref(doc1, VARIANT_TRUE);
     test_preserve_charref(doc1, VARIANT_FALSE);
+
+    /* formatting whitespaces */
+    hr = IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_FALSE);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IXMLDOMDocument2_loadXML(doc1, _bstr_(complete7), &b);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(b == VARIANT_TRUE, "for %x\n", b);
+
+    hr = IXMLDOMDocument2_get_documentElement(doc1, &root);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    hr = IXMLDOMElement_get_childNodes(root, &list);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    len = 0;
+    hr = IXMLDOMNodeList_get_length(list, &len);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(len == 3, "got %d\n", len);
+    IXMLDOMNodeList_Release(list);
+    IXMLDOMElement_Release(root);
+
     IXMLDOMDocument2_Release(doc1);
 
     free_bstrs();




More information about the wine-cvs mailing list