[libxslt] Fix str:padding to work with UTF-8 strings



commit 515283959aae470a6ee5033deb9f977a489e7578
Author: Nick Wellnhofer <wellnhofer aevum de>
Date:   Sun Aug 4 16:42:51 2013 +0200

    Fix str:padding to work with UTF-8 strings
    
    Thanks to Tobias Hoffmann for the report.
    
    Also add some tests.

 libexslt/strings.c                |   16 ++++++++------
 tests/exslt/strings/padding.1.out |   27 +++++++++++++++++++++++++
 tests/exslt/strings/padding.1.xml |   10 +++++++++
 tests/exslt/strings/padding.1.xsl |   40 +++++++++++++++++++++++++++++++++++++
 4 files changed, 86 insertions(+), 7 deletions(-)
---
diff --git a/libexslt/strings.c b/libexslt/strings.c
index c0c7a18..3c702ad 100644
--- a/libexslt/strings.c
+++ b/libexslt/strings.c
@@ -351,8 +351,8 @@ exsltStrDecodeUriFunction (xmlXPathParserContextPtr ctxt, int nargs) {
  */
 static void
 exsltStrPaddingFunction (xmlXPathParserContextPtr ctxt, int nargs) {
-    int number, str_len = 0;
-    xmlChar *str = NULL, *ret = NULL, *tmp;
+    int number, str_len = 0, str_size = 0;
+    xmlChar *str = NULL, *ret = NULL;
 
     if ((nargs < 1) || (nargs > 2)) {
        xmlXPathSetArityError(ctxt);
@@ -362,11 +362,13 @@ exsltStrPaddingFunction (xmlXPathParserContextPtr ctxt, int nargs) {
     if (nargs == 2) {
        str = xmlXPathPopString(ctxt);
        str_len = xmlUTF8Strlen(str);
+       str_size = xmlStrlen(str);
     }
     if (str_len == 0) {
        if (str != NULL) xmlFree(str);
        str = xmlStrdup((const xmlChar *) " ");
        str_len = 1;
+       str_size = 1;
     }
 
     number = (int) xmlXPathPopNumber(ctxt);
@@ -378,13 +380,13 @@ exsltStrPaddingFunction (xmlXPathParserContextPtr ctxt, int nargs) {
     }
 
     while (number >= str_len) {
-       ret = xmlStrncat(ret, str, str_len);
+       ret = xmlStrncat(ret, str, str_size);
        number -= str_len;
     }
-    tmp = xmlUTF8Strndup (str, number);
-    ret = xmlStrcat(ret, tmp);
-    if (tmp != NULL)
-       xmlFree (tmp);
+    if (number > 0) {
+       str_size = xmlUTF8Strsize(str, number);
+       ret = xmlStrncat(ret, str, str_size);
+    }
 
     xmlXPathReturnString(ctxt, ret);
 
diff --git a/tests/exslt/strings/padding.1.out b/tests/exslt/strings/padding.1.out
new file mode 100644
index 0000000..1833a65
--- /dev/null
+++ b/tests/exslt/strings/padding.1.out
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<test-results>
+  <test-result>
+    <padding>     </padding>
+    <length-check>OK</length-check>
+  </test-result>
+  <test-result>
+    <padding>--------</padding>
+    <length-check>OK</length-check>
+  </test-result>
+  <test-result>
+    <padding>abcabcabca</padding>
+    <length-check>OK</length-check>
+  </test-result>
+  <test-result>
+    <padding>–––––––</padding>
+    <length-check>OK</length-check>
+  </test-result>
+  <test-result>
+    <padding>– – – – – –</padding>
+    <length-check>OK</length-check>
+  </test-result>
+  <test-result>
+    <padding>ÄÖÜÄÖÜ</padding>
+    <length-check>OK</length-check>
+  </test-result>
+</test-results>
diff --git a/tests/exslt/strings/padding.1.xml b/tests/exslt/strings/padding.1.xml
new file mode 100644
index 0000000..16d0824
--- /dev/null
+++ b/tests/exslt/strings/padding.1.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<test-cases>
+    <test-case length="5"/>
+    <test-case length="8">-</test-case>
+    <test-case length="10">abc</test-case>
+    <test-case length="7">&#x2013;</test-case>
+    <test-case length="11">&#x2013;&#xa0;</test-case>
+    <test-case length="6">ÄÖÜ</test-case>
+</test-cases>
+
diff --git a/tests/exslt/strings/padding.1.xsl b/tests/exslt/strings/padding.1.xsl
new file mode 100644
index 0000000..c5d621d
--- /dev/null
+++ b/tests/exslt/strings/padding.1.xsl
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0"
+    xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
+    xmlns:str="http://exslt.org/strings";
+    exclude-result-prefixes="str">
+
+<xsl:output indent="yes"/>
+
+<xsl:template match="test-cases">
+    <test-results>
+        <xsl:apply-templates select="test-case"/>
+    </test-results>
+</xsl:template>
+
+<xsl:template match="test-case">
+    <test-result>
+        <xsl:variable name="padding">
+            <xsl:choose>
+                <xsl:when test="string(.)">
+                    <xsl:value-of select="str:padding(@length, .)"/>
+                </xsl:when>
+                <xsl:otherwise>
+                    <xsl:value-of select="str:padding(@length)"/>
+                </xsl:otherwise>
+            </xsl:choose>
+        </xsl:variable>
+        <padding>
+            <xsl:value-of select="$padding"/>
+        </padding>
+        <length-check>
+            <xsl:choose>
+                <xsl:when test="string-length($padding) = @length">OK</xsl:when>
+                <xsl:otherwise>FAIL</xsl:otherwise>
+            </xsl:choose>
+        </length-check>
+    </test-result>
+</xsl:template>
+
+</xsl:stylesheet>
+


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