0012-Fix-xsltNumberFormatGetMultipleLevel.patch 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. From d182d8f6ba3071503d96ce17395c9d55871f0242 Mon Sep 17 00:00:00 2001
  2. From: Nick Wellnhofer <wellnhofer@aevum.de>
  3. Date: Tue, 22 Mar 2016 18:20:01 +0100
  4. Subject: [PATCH] Fix xsltNumberFormatGetMultipleLevel
  5. Namespace nodes are actually an xmlNs, not an xmlNode. They must be
  6. special-cased in xsltNumberFormatGetMultipleLevel to avoid an
  7. out-of-bounds heap access.
  8. Move the test whether a node matches the "count" pattern to a separate
  9. function to make the code more readable. As a side effect, we also
  10. compare expanded names when walking up the ancestor axis, fixing an
  11. insignificant bug.
  12. ---
  13. libxslt/numbers.c | 82 +++++++++++++++++++++++++++--------------------
  14. tests/docs/bug-186.xml | 4 +++
  15. tests/general/bug-186.out | 5 +++
  16. tests/general/bug-186.xsl | 7 ++++
  17. 4 files changed, 63 insertions(+), 35 deletions(-)
  18. create mode 100644 tests/docs/bug-186.xml
  19. create mode 100644 tests/general/bug-186.out
  20. create mode 100644 tests/general/bug-186.xsl
  21. --- a/libxslt/numbers.c
  22. +++ b/libxslt/numbers.c
  23. @@ -532,6 +532,43 @@ xsltNumberFormatInsertNumbers(xsltNumber
  24. }
  25. static int
  26. +xsltTestCompMatchCount(xsltTransformContextPtr context,
  27. + xmlNodePtr node,
  28. + xsltCompMatchPtr countPat,
  29. + xmlNodePtr cur)
  30. +{
  31. + if (countPat != NULL) {
  32. + return xsltTestCompMatchList(context, node, countPat);
  33. + }
  34. + else {
  35. + /*
  36. + * 7.7 Numbering
  37. + *
  38. + * If count attribute is not specified, then it defaults to the
  39. + * pattern that matches any node with the same node type as the
  40. + * current node and, if the current node has an expanded-name, with
  41. + * the same expanded-name as the current node.
  42. + */
  43. + if (node->type != cur->type)
  44. + return 0;
  45. + if (node->type == XML_NAMESPACE_DECL)
  46. + /*
  47. + * Namespace nodes have no preceding siblings and no parents
  48. + * that are namespace nodes. This means that node == cur.
  49. + */
  50. + return 1;
  51. + /* TODO: Skip node types without expanded names like text nodes. */
  52. + if (!xmlStrEqual(node->name, cur->name))
  53. + return 0;
  54. + if (node->ns == cur->ns)
  55. + return 1;
  56. + if ((node->ns == NULL) || (cur->ns == NULL))
  57. + return 0;
  58. + return (xmlStrEqual(node->ns->href, cur->ns->href));
  59. + }
  60. +}
  61. +
  62. +static int
  63. xsltNumberFormatGetAnyLevel(xsltTransformContextPtr context,
  64. xmlNodePtr node,
  65. xsltCompMatchPtr countPat,
  66. @@ -564,21 +601,8 @@ xsltNumberFormatGetAnyLevel(xsltTransfor
  67. while (cur != NULL) {
  68. /* process current node */
  69. - if (countPat == NULL) {
  70. - if ((node->type == cur->type) &&
  71. - /* FIXME: must use expanded-name instead of local name */
  72. - xmlStrEqual(node->name, cur->name)) {
  73. - if ((node->ns == cur->ns) ||
  74. - ((node->ns != NULL) &&
  75. - (cur->ns != NULL) &&
  76. - (xmlStrEqual(node->ns->href,
  77. - cur->ns->href) )))
  78. - cnt++;
  79. - }
  80. - } else {
  81. - if (xsltTestCompMatchList(context, cur, countPat))
  82. - cnt++;
  83. - }
  84. + if (xsltTestCompMatchCount(context, cur, countPat, node))
  85. + cnt++;
  86. if ((fromPat != NULL) &&
  87. xsltTestCompMatchList(context, cur, fromPat)) {
  88. break; /* while */
  89. @@ -637,30 +661,18 @@ xsltNumberFormatGetMultipleLevel(xsltTra
  90. xsltTestCompMatchList(context, ancestor, fromPat))
  91. break; /* for */
  92. - if ((countPat == NULL && node->type == ancestor->type &&
  93. - xmlStrEqual(node->name, ancestor->name)) ||
  94. - xsltTestCompMatchList(context, ancestor, countPat)) {
  95. + if (xsltTestCompMatchCount(context, ancestor, countPat, node)) {
  96. /* count(preceding-sibling::*) */
  97. - cnt = 0;
  98. - for (preceding = ancestor;
  99. + cnt = 1;
  100. + for (preceding =
  101. + xmlXPathNextPrecedingSibling(parser, ancestor);
  102. preceding != NULL;
  103. preceding =
  104. xmlXPathNextPrecedingSibling(parser, preceding)) {
  105. - if (countPat == NULL) {
  106. - if ((preceding->type == ancestor->type) &&
  107. - xmlStrEqual(preceding->name, ancestor->name)){
  108. - if ((preceding->ns == ancestor->ns) ||
  109. - ((preceding->ns != NULL) &&
  110. - (ancestor->ns != NULL) &&
  111. - (xmlStrEqual(preceding->ns->href,
  112. - ancestor->ns->href) )))
  113. - cnt++;
  114. - }
  115. - } else {
  116. - if (xsltTestCompMatchList(context, preceding,
  117. - countPat))
  118. - cnt++;
  119. - }
  120. +
  121. + if (xsltTestCompMatchCount(context, preceding, countPat,
  122. + node))
  123. + cnt++;
  124. }
  125. array[amount++] = (double)cnt;
  126. if (amount >= max)
  127. --- /dev/null
  128. +++ b/tests/docs/bug-186.xml
  129. @@ -0,0 +1,4 @@
  130. +<top xmlns:a="AAAA" xmlns:b="BBBB" xmlns:c="CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC">
  131. +<foo/>
  132. +<bar/>
  133. +</top>
  134. --- /dev/null
  135. +++ b/tests/general/bug-186.out
  136. @@ -0,0 +1,5 @@
  137. +<?xml version="1.0"?>
  138. +
  139. +1111
  140. +1111
  141. +
  142. --- /dev/null
  143. +++ b/tests/general/bug-186.xsl
  144. @@ -0,0 +1,7 @@
  145. +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  146. + <xsl:template match="*/*">
  147. + <xsl:for-each select="namespace::*">
  148. + <xsl:number/>
  149. + </xsl:for-each>
  150. + </xsl:template>
  151. +</xsl:stylesheet>