[libxslt] Fix <xsl:number level="any"/> for non-element nodes



commit 8345634c5482ca04293ae1862d52fa9dd764aeca
Author: Nick Wellnhofer <wellnhofer aevum de>
Date:   Sat Aug 13 20:43:04 2016 +0200

    Fix <xsl:number level="any"/> for non-element nodes
    
    Fix counting of nodes with <xsl:number level="any"/> when the current
    node is a
    
    - comment
    - processing instruction
    - attribute
    - text node
    - namespace node
    
    The old code skipped the current node and preceding siblings for these
    node types.
    
    Thanks to Martin Honnen for the report. Fixes bug #769756:
    
    https://bugzilla.gnome.org/show_bug.cgi?id=769756

 libxslt/numbers.c         |   49 ++++++++++++++++++--------------------------
 tests/docs/bug-195.xml    |    9 ++++++++
 tests/docs/bug-196.xml    |    9 ++++++++
 tests/docs/bug-197.xml    |    6 +++++
 tests/docs/bug-198.xml    |    2 +
 tests/docs/bug-199.xml    |    6 +++++
 tests/general/bug-195.out |    8 +++++++
 tests/general/bug-195.xsl |   19 +++++++++++++++++
 tests/general/bug-196.out |    7 ++++++
 tests/general/bug-196.xsl |   19 +++++++++++++++++
 tests/general/bug-197.out |    6 +++++
 tests/general/bug-197.xsl |   16 ++++++++++++++
 tests/general/bug-198.out |    2 +
 tests/general/bug-198.xsl |   17 +++++++++++++++
 tests/general/bug-199.out |    6 +++++
 tests/general/bug-199.xsl |   18 ++++++++++++++++
 16 files changed, 170 insertions(+), 29 deletions(-)
---
diff --git a/libxslt/numbers.c b/libxslt/numbers.c
index e769c42..d1549b4 100644
--- a/libxslt/numbers.c
+++ b/libxslt/numbers.c
@@ -616,25 +616,7 @@ xsltNumberFormatGetAnyLevel(xsltTransformContextPtr context,
 {
     int amount = 0;
     int cnt = 0;
-    xmlNodePtr cur;
-
-    /* select the starting node */
-    switch (node->type) {
-       case XML_ELEMENT_NODE:
-           cur = node;
-           break;
-       case XML_ATTRIBUTE_NODE:
-           cur = ((xmlAttrPtr) node)->parent;
-           break;
-       case XML_TEXT_NODE:
-       case XML_PI_NODE:
-       case XML_COMMENT_NODE:
-           cur = node->parent;
-           break;
-       default:
-           cur = NULL;
-           break;
-    }
+    xmlNodePtr cur = node;
 
     while (cur != NULL) {
        /* process current node */
@@ -653,16 +635,25 @@ xsltNumberFormatGetAnyLevel(xsltTransformContextPtr context,
             (cur->type == XML_HTML_DOCUMENT_NODE))
            break; /* while */
 
-       while ((cur->prev != NULL) && ((cur->prev->type == XML_DTD_NODE) ||
-              (cur->prev->type == XML_XINCLUDE_START) ||
-              (cur->prev->type == XML_XINCLUDE_END)))
-           cur = cur->prev;
-       if (cur->prev != NULL) {
-           for (cur = cur->prev; cur->last != NULL; cur = cur->last);
-       } else {
-           cur = cur->parent;
-       }
-
+        if (cur->type == XML_NAMESPACE_DECL) {
+            /*
+            * The XPath module stores the parent of a namespace node in
+            * the ns->next field.
+            */
+            cur = (xmlNodePtr) ((xmlNsPtr) cur)->next;
+        } else if (cur->type == XML_ATTRIBUTE_NODE) {
+            cur = cur->parent;
+        } else {
+            while ((cur->prev != NULL) && ((cur->prev->type == XML_DTD_NODE) ||
+                   (cur->prev->type == XML_XINCLUDE_START) ||
+                   (cur->prev->type == XML_XINCLUDE_END)))
+                cur = cur->prev;
+            if (cur->prev != NULL) {
+                for (cur = cur->prev; cur->last != NULL; cur = cur->last);
+            } else {
+                cur = cur->parent;
+            }
+        }
     }
 
     array[amount++] = (double) cnt;
diff --git a/tests/docs/bug-195.xml b/tests/docs/bug-195.xml
new file mode 100644
index 0000000..4b5f3b0
--- /dev/null
+++ b/tests/docs/bug-195.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- first comment -->
+<root>
+    <!-- second comment -->
+    <foo>
+        <!-- third comment -->
+    </foo>
+</root>
+<!-- fourth comment -->
diff --git a/tests/docs/bug-196.xml b/tests/docs/bug-196.xml
new file mode 100644
index 0000000..d82bb84
--- /dev/null
+++ b/tests/docs/bug-196.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?pi first?>
+<root>
+    <?pi second?>
+    <foo>
+        <?pi third?>
+    </foo>
+</root>
+<?pi fourth?>
diff --git a/tests/docs/bug-197.xml b/tests/docs/bug-197.xml
new file mode 100644
index 0000000..ae79392
--- /dev/null
+++ b/tests/docs/bug-197.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root attr="1">
+    <foo attr="2">
+        <bar attr="3"/>
+    </foo>
+</root>
diff --git a/tests/docs/bug-198.xml b/tests/docs/bug-198.xml
new file mode 100644
index 0000000..ad6e2ca
--- /dev/null
+++ b/tests/docs/bug-198.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root>a<foo>b<bar>c</bar>d</foo>e</root>
diff --git a/tests/docs/bug-199.xml b/tests/docs/bug-199.xml
new file mode 100644
index 0000000..47a355a
--- /dev/null
+++ b/tests/docs/bug-199.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root xmlns:a="a">
+    <foo xmlns:a="b">
+        <bar xmlns:a="c"/>
+    </foo>
+</root>
diff --git a/tests/general/bug-195.out b/tests/general/bug-195.out
new file mode 100644
index 0000000..b129fbc
--- /dev/null
+++ b/tests/general/bug-195.out
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<!-- first comment  id="1"-->
+<root>
+    <!-- second comment  id="2"-->
+    <foo>
+        <!-- third comment  id="3"-->
+    </foo>
+</root><!-- fourth comment  id="4"-->
diff --git a/tests/general/bug-195.xsl b/tests/general/bug-195.xsl
new file mode 100644
index 0000000..8c9e126
--- /dev/null
+++ b/tests/general/bug-195.xsl
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.0">
+
+    <xsl:template match="node()|@*">
+        <xsl:copy>
+            <xsl:apply-templates select="node()|@*" />
+        </xsl:copy>
+    </xsl:template>
+
+    <xsl:template match="comment()">
+        <xsl:comment>
+            <xsl:value-of select="."/>
+            <xsl:text> id="</xsl:text>
+            <xsl:number count="comment()" level="any" />
+            <xsl:text>"</xsl:text>
+        </xsl:comment>
+    </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tests/general/bug-196.out b/tests/general/bug-196.out
new file mode 100644
index 0000000..76fd9aa
--- /dev/null
+++ b/tests/general/bug-196.out
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<?pi first id="1"?><root>
+    <?pi second id="2"?>
+    <foo>
+        <?pi third id="3"?>
+    </foo>
+</root><?pi fourth id="4"?>
diff --git a/tests/general/bug-196.xsl b/tests/general/bug-196.xsl
new file mode 100644
index 0000000..d5030f2
--- /dev/null
+++ b/tests/general/bug-196.xsl
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.0">
+
+    <xsl:template match="node()|@*">
+        <xsl:copy>
+            <xsl:apply-templates select="node()|@*" />
+        </xsl:copy>
+    </xsl:template>
+
+    <xsl:template match="processing-instruction()">
+        <xsl:processing-instruction name="{name()}">
+            <xsl:value-of select="."/>
+            <xsl:text> id="</xsl:text>
+            <xsl:number count="processing-instruction()" level="any" />
+            <xsl:text>"</xsl:text>
+        </xsl:processing-instruction>
+    </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tests/general/bug-197.out b/tests/general/bug-197.out
new file mode 100644
index 0000000..47d838a
--- /dev/null
+++ b/tests/general/bug-197.out
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<root attr="1">
+    <foo attr="1">
+        <bar attr="1"/>
+    </foo>
+</root>
diff --git a/tests/general/bug-197.xsl b/tests/general/bug-197.xsl
new file mode 100644
index 0000000..e9ab169
--- /dev/null
+++ b/tests/general/bug-197.xsl
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.0">
+
+    <xsl:template match="node()|@*">
+        <xsl:copy>
+            <xsl:apply-templates select="node()|@*" />
+        </xsl:copy>
+    </xsl:template>
+
+    <xsl:template match="@*">
+        <xsl:attribute name="{name()}">
+            <xsl:number count="@*" level="any" />
+        </xsl:attribute>
+    </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tests/general/bug-198.out b/tests/general/bug-198.out
new file mode 100644
index 0000000..a2d7089
--- /dev/null
+++ b/tests/general/bug-198.out
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<root>a(1)<foo>b(2)<bar>c(3)</bar>d(4)</foo>e(5)</root>
diff --git a/tests/general/bug-198.xsl b/tests/general/bug-198.xsl
new file mode 100644
index 0000000..8d182a9
--- /dev/null
+++ b/tests/general/bug-198.xsl
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.0">
+
+    <xsl:template match="node()|@*">
+        <xsl:copy>
+            <xsl:apply-templates select="node()|@*" />
+        </xsl:copy>
+    </xsl:template>
+
+    <xsl:template match="text()">
+        <xsl:value-of select="."/>
+        <xsl:text>(</xsl:text>
+        <xsl:number count="text()" level="any" />
+        <xsl:text>)</xsl:text>
+    </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tests/general/bug-199.out b/tests/general/bug-199.out
new file mode 100644
index 0000000..beb660d
--- /dev/null
+++ b/tests/general/bug-199.out
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<root xmlns:a="a" ns="a(1)">
+    <foo xmlns:a="b" ns="b(2)">
+        <bar xmlns:a="c" ns="c(3)"/>
+    </foo>
+</root>
diff --git a/tests/general/bug-199.xsl b/tests/general/bug-199.xsl
new file mode 100644
index 0000000..9a0a984
--- /dev/null
+++ b/tests/general/bug-199.xsl
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.0">
+
+    <xsl:template match="node()|@*">
+        <xsl:copy>
+            <xsl:for-each select="namespace::a">
+                <xsl:attribute name="ns">
+                    <xsl:value-of select="."/>
+                    <xsl:text>(</xsl:text>
+                    <xsl:number count="*" level="any"/>
+                    <xsl:text>)</xsl:text>
+                </xsl:attribute>
+            </xsl:for-each>
+            <xsl:apply-templates select="node()|@*"/>
+        </xsl:copy>
+    </xsl:template>
+
+</xsl:stylesheet>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]