update libxslt to 1.1.34

This commit is contained in:
linwei9 2020-06-23 16:51:49 +08:00
parent f00acbc0ee
commit ef76febb14
22 changed files with 7 additions and 1659 deletions

View File

@ -1,65 +0,0 @@
From 06d193fabb096370a969ca9f017f60bca7057262 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Thu, 11 Apr 2019 14:06:51 +0200
Subject: [PATCH 04/26] Fix check of xsltTestCompMatch return value
xsltTestCompMatch returns -1 in case of errors which wasn't checked in
most places.
Found when investigating a libFuzzer timeout.
---
libxslt/pattern.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/libxslt/pattern.c b/libxslt/pattern.c
index 7d66019..5577877 100644
--- a/libxslt/pattern.c
+++ b/libxslt/pattern.c
@@ -2401,7 +2401,7 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
list = NULL;
while (list != NULL) {
if (xsltTestCompMatch(ctxt, list, node,
- ctxt->mode, ctxt->modeURI)) {
+ ctxt->mode, ctxt->modeURI) == 1) {
ret = list->template;
priority = list->priority;
break;
@@ -2470,7 +2470,7 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
while ((list != NULL) &&
((ret == NULL) || (list->priority > priority))) {
if (xsltTestCompMatch(ctxt, list, node,
- ctxt->mode, ctxt->modeURI)) {
+ ctxt->mode, ctxt->modeURI) == 1) {
ret = list->template;
priority = list->priority;
break;
@@ -2487,7 +2487,7 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
while ((list != NULL) &&
((ret == NULL) || (list->priority > priority))) {
if (xsltTestCompMatch(ctxt, list, node,
- ctxt->mode, ctxt->modeURI)) {
+ ctxt->mode, ctxt->modeURI) == 1) {
ret = list->template;
priority = list->priority;
break;
@@ -2500,7 +2500,7 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
while ((list != NULL) &&
((ret == NULL) || (list->priority > priority))) {
if (xsltTestCompMatch(ctxt, list, node,
- ctxt->mode, ctxt->modeURI)) {
+ ctxt->mode, ctxt->modeURI) == 1) {
ret = list->template;
priority = list->priority;
break;
@@ -2515,7 +2515,7 @@ keyed_match:
while ((list != NULL) &&
((ret == NULL) || (list->priority > priority))) {
if (xsltTestCompMatch(ctxt, list, node,
- ctxt->mode, ctxt->modeURI)) {
+ ctxt->mode, ctxt->modeURI) == 1) {
ret = list->template;
priority = list->priority;
break;
--
1.8.3.1

View File

@ -1,94 +0,0 @@
From 8bd32f7753ac253a54279a0b6a88d15a57076bb0 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 16 Jan 2018 18:59:02 +0100
Subject: [PATCH 09/33] Fix handling of RVTs returned from nested EXSLT
functions
Set the context variable to NULL when evaluating EXSLT functions.
Fixes potential use-after-free errors or memory leaks.
Fixes bug 792580. Thanks to Clemens Gutweiler for the report.
https://bugzilla.gnome.org/show_bug.cgi?id=792580
---
libexslt/functions.c | 4 ++++
tests/docs/bug-209.xml | 1 +
tests/general/bug-209.out | 2 ++
tests/general/bug-209.xsl | 21 +++++++++++++++++++++
4 files changed, 28 insertions(+)
create mode 100644 tests/docs/bug-209.xml
create mode 100644 tests/general/bug-209.out
create mode 100644 tests/general/bug-209.xsl
diff --git a/libexslt/functions.c b/libexslt/functions.c
index 74dea1a..2b83ca3 100644
--- a/libexslt/functions.c
+++ b/libexslt/functions.c
@@ -292,6 +292,7 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
exsltFuncFunctionData *func;
xmlNodePtr paramNode, oldInsert, fake;
int oldBase;
+ void *oldCtxtVar;
xsltStackElemPtr params = NULL, param;
xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt);
int i, notSet;
@@ -430,11 +431,14 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
fake = xmlNewDocNode(tctxt->output, NULL,
(const xmlChar *)"fake", NULL);
oldInsert = tctxt->insert;
+ oldCtxtVar = tctxt->contextVariable;
tctxt->insert = fake;
+ tctxt->contextVariable = NULL;
xsltApplyOneTemplate (tctxt, tctxt->node,
func->content, NULL, NULL);
xsltLocalVariablePop(tctxt, tctxt->varsBase, -2);
tctxt->insert = oldInsert;
+ tctxt->contextVariable = oldCtxtVar;
tctxt->varsBase = oldBase; /* restore original scope */
if (params != NULL)
xsltFreeStackElemList(params);
diff --git a/tests/docs/bug-209.xml b/tests/docs/bug-209.xml
new file mode 100644
index 0000000..69d62f2
--- /dev/null
+++ b/tests/docs/bug-209.xml
@@ -0,0 +1 @@
+<doc/>
diff --git a/tests/general/bug-209.out b/tests/general/bug-209.out
new file mode 100644
index 0000000..e829790
--- /dev/null
+++ b/tests/general/bug-209.out
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<result/>
diff --git a/tests/general/bug-209.xsl b/tests/general/bug-209.xsl
new file mode 100644
index 0000000..fe69ac6
--- /dev/null
+++ b/tests/general/bug-209.xsl
@@ -0,0 +1,21 @@
+<xsl:stylesheet
+ version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:func="http://exslt.org/functions"
+ extension-element-prefixes="func">
+
+ <xsl:template match="/">
+ <xsl:variable name="v" select="func:a()" />
+ <xsl:copy-of select="$v"/>
+ </xsl:template>
+
+ <func:function name="func:a">
+ <func:result select="func:b()" />
+ </func:function>
+
+ <func:function name="func:b">
+ <func:result>
+ <result/>
+ </func:result>
+ </func:function>
+</xsl:stylesheet>
--
1.8.3.1

View File

@ -1,312 +0,0 @@
From 7d81bd62d5788a9e2931c20a3d0a6be7e703c608 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 23 Jul 2018 22:52:12 +0200
Subject: [PATCH 12/33] Fix EXSLT functions returning RVTs from outer scopes
The RVTs referenced from function results must not be blindly registered
as local, as they might be part of variables from an outer scope. Remove
LOCAL/VARIABLE distinction for RVTs. Don't register as local RVT
unconditionally when reflagging as LOCAL. Instead, register function
result RVTs from inner variables as local RVTs when they're released in
xsltFreeStackElem. Keep local function result RVTs xsltReleaseLocalRVTs
instead of reregistering.
Closes: https://gitlab.gnome.org/GNOME/libxslt/issues/2
Thanks to Daniel Mendler and Martin Gieseking for the reports.
---
libexslt/functions.c | 11 ++++++++++-
libxslt/transform.c | 17 ++++++++++++++---
libxslt/variables.c | 27 +++++++++++----------------
libxslt/variables.h | 12 ++----------
tests/docs/bug-210.xml | 1 +
tests/docs/bug-211.xml | 1 +
tests/general/bug-210.out | 2 ++
tests/general/bug-210.xsl | 20 ++++++++++++++++++++
tests/general/bug-211.out | 2 ++
tests/general/bug-211.xsl | 26 ++++++++++++++++++++++++++
10 files changed, 89 insertions(+), 30 deletions(-)
create mode 100644 tests/docs/bug-210.xml
create mode 100644 tests/docs/bug-211.xml
create mode 100644 tests/general/bug-210.out
create mode 100644 tests/general/bug-210.xsl
create mode 100644 tests/general/bug-211.out
create mode 100644 tests/general/bug-211.xsl
diff --git a/libexslt/functions.c b/libexslt/functions.c
index 2b83ca3..b7b968f 100644
--- a/libexslt/functions.c
+++ b/libexslt/functions.c
@@ -426,7 +426,15 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
}
}
/*
- * actual processing
+ * Actual processing. Note that contextVariable is set to NULL which
+ * means that RVTs returned from functions always end up as local RVTs,
+ * not as variable fragments if the function is called in the select
+ * expression of an xsl:variable. This is a hack that only works because
+ * xsltReleaseLocalRVTs isn't called after processing xsl:variable.
+ *
+ * It would probably be better to remove the fragile contextVariable
+ * logic and make xsltEvalVariable move the required RVTs into the
+ * variable manually.
*/
fake = xmlNewDocNode(tctxt->output, NULL,
(const xmlChar *)"fake", NULL);
@@ -766,6 +774,7 @@ exsltFuncResultElem (xsltTransformContextPtr ctxt,
return;
}
/* Mark as function result. */
+ xsltRegisterLocalRVT(ctxt, container);
container->psvi = XSLT_RVT_FUNC_RESULT;
oldInsert = ctxt->insert;
diff --git a/libxslt/transform.c b/libxslt/transform.c
index 90d2731..d7af31f 100644
--- a/libxslt/transform.c
+++ b/libxslt/transform.c
@@ -2295,6 +2295,7 @@ static void
xsltReleaseLocalRVTs(xsltTransformContextPtr ctxt, xmlDocPtr base)
{
xmlDocPtr cur = ctxt->localRVT, tmp;
+ xmlDocPtr prev = NULL;
if (cur == base)
return;
@@ -2308,16 +2309,26 @@ xsltReleaseLocalRVTs(xsltTransformContextPtr ctxt, xmlDocPtr base)
xsltReleaseRVT(ctxt, tmp);
} else if (tmp->psvi == XSLT_RVT_GLOBAL) {
xsltRegisterPersistRVT(ctxt, tmp);
- } else if (tmp->psvi != XSLT_RVT_FUNC_RESULT) {
+ } else if (tmp->psvi == XSLT_RVT_FUNC_RESULT) {
+ if (prev == NULL)
+ ctxt->localRVT = tmp;
+ else
+ prev->next = (xmlNodePtr) tmp;
+ tmp->prev = (xmlNodePtr) prev;
+ prev = tmp;
+ } else {
xmlGenericError(xmlGenericErrorContext,
"xsltReleaseLocalRVTs: Unexpected RVT flag %p\n",
tmp->psvi);
}
} while (cur != base);
+ if (prev == NULL)
+ ctxt->localRVT = base;
+ else
+ prev->next = (xmlNodePtr) base;
if (base != NULL)
- base->prev = NULL;
- ctxt->localRVT = base;
+ base->prev = (xmlNodePtr) prev;
}
/**
diff --git a/libxslt/variables.c b/libxslt/variables.c
index fe6f299..8f88e57 100644
--- a/libxslt/variables.c
+++ b/libxslt/variables.c
@@ -123,7 +123,7 @@ xsltRegisterTmpRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
return(-1);
RVT->prev = NULL;
- RVT->psvi = XSLT_RVT_VARIABLE;
+ RVT->psvi = XSLT_RVT_LOCAL;
/*
* We'll restrict the lifetime of user-created fragments
@@ -163,6 +163,7 @@ xsltRegisterLocalRVT(xsltTransformContextPtr ctxt,
return(-1);
RVT->prev = NULL;
+ RVT->psvi = XSLT_RVT_LOCAL;
/*
* When evaluating "select" expressions of xsl:variable
@@ -173,7 +174,6 @@ xsltRegisterLocalRVT(xsltTransformContextPtr ctxt,
if ((ctxt->contextVariable != NULL) &&
(XSLT_TCTXT_VARIABLE(ctxt)->flags & XSLT_VAR_IN_SELECT))
{
- RVT->psvi = XSLT_RVT_VARIABLE;
RVT->next = (xmlNodePtr) XSLT_TCTXT_VARIABLE(ctxt)->fragment;
XSLT_TCTXT_VARIABLE(ctxt)->fragment = RVT;
return(0);
@@ -183,7 +183,6 @@ xsltRegisterLocalRVT(xsltTransformContextPtr ctxt,
* If not reference by a returning instruction (like EXSLT's function),
* then this fragment will be freed, when the instruction exits.
*/
- RVT->psvi = XSLT_RVT_LOCAL;
RVT->next = (xmlNodePtr) ctxt->localRVT;
if (ctxt->localRVT != NULL)
ctxt->localRVT->prev = (xmlNodePtr) RVT;
@@ -314,14 +313,8 @@ xsltFlagRVTs(xsltTransformContextPtr ctxt, xmlXPathObjectPtr obj, void *val) {
#endif
if (val == XSLT_RVT_LOCAL) {
- if (doc->psvi != XSLT_RVT_FUNC_RESULT) {
- xmlGenericError(xmlGenericErrorContext,
- "xsltFlagRVTs: Invalid transition %p => LOCAL\n",
- doc->psvi);
- return(-1);
- }
-
- xsltRegisterLocalRVT(ctxt, doc);
+ if (doc->psvi == XSLT_RVT_FUNC_RESULT)
+ doc->psvi = XSLT_RVT_LOCAL;
} else if (val == XSLT_RVT_GLOBAL) {
if (doc->psvi != XSLT_RVT_LOCAL) {
xmlGenericError(xmlGenericErrorContext,
@@ -585,10 +578,12 @@ xsltFreeStackElem(xsltStackElemPtr elem) {
cur = elem->fragment;
elem->fragment = (xmlDocPtr) cur->next;
- if (cur->psvi == XSLT_RVT_VARIABLE) {
- xsltReleaseRVT((xsltTransformContextPtr) elem->context,
- cur);
- } else if (cur->psvi != XSLT_RVT_FUNC_RESULT) {
+ if (cur->psvi == XSLT_RVT_LOCAL) {
+ xsltReleaseRVT(elem->context, cur);
+ } else if (cur->psvi == XSLT_RVT_FUNC_RESULT) {
+ xsltRegisterLocalRVT(elem->context, cur);
+ cur->psvi = XSLT_RVT_FUNC_RESULT;
+ } else {
xmlGenericError(xmlGenericErrorContext,
"xsltFreeStackElem: Unexpected RVT flag %p\n",
cur->psvi);
@@ -992,7 +987,7 @@ xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr variable,
* the Result Tree Fragment.
*/
variable->fragment = container;
- container->psvi = XSLT_RVT_VARIABLE;
+ container->psvi = XSLT_RVT_LOCAL;
oldOutput = ctxt->output;
oldInsert = ctxt->insert;
diff --git a/libxslt/variables.h b/libxslt/variables.h
index 24acf8d..039288f 100644
--- a/libxslt/variables.h
+++ b/libxslt/variables.h
@@ -46,28 +46,20 @@ extern "C" {
#define XSLT_RVT_LOCAL ((void *)1)
/**
- * XSLT_RVT_VARIABLE:
- *
- * RVT is part of a local variable and destroyed after the variable goes out
- * of scope.
- */
-#define XSLT_RVT_VARIABLE ((void *)2)
-
-/**
* XSLT_RVT_FUNC_RESULT:
*
* RVT is part of results returned with func:result. The RVT won't be
* destroyed after exiting a template and will be reset to XSLT_RVT_LOCAL or
* XSLT_RVT_VARIABLE in the template that receives the return value.
*/
-#define XSLT_RVT_FUNC_RESULT ((void *)3)
+#define XSLT_RVT_FUNC_RESULT ((void *)2)
/**
* XSLT_RVT_GLOBAL:
*
* RVT is part of a global variable.
*/
-#define XSLT_RVT_GLOBAL ((void *)4)
+#define XSLT_RVT_GLOBAL ((void *)3)
/*
* Interfaces for the variable module.
diff --git a/tests/docs/bug-210.xml b/tests/docs/bug-210.xml
new file mode 100644
index 0000000..69d62f2
--- /dev/null
+++ b/tests/docs/bug-210.xml
@@ -0,0 +1 @@
+<doc/>
diff --git a/tests/docs/bug-211.xml b/tests/docs/bug-211.xml
new file mode 100644
index 0000000..69d62f2
--- /dev/null
+++ b/tests/docs/bug-211.xml
@@ -0,0 +1 @@
+<doc/>
diff --git a/tests/general/bug-210.out b/tests/general/bug-210.out
new file mode 100644
index 0000000..445906d
--- /dev/null
+++ b/tests/general/bug-210.out
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<var>value</var>
diff --git a/tests/general/bug-210.xsl b/tests/general/bug-210.xsl
new file mode 100644
index 0000000..1915171
--- /dev/null
+++ b/tests/general/bug-210.xsl
@@ -0,0 +1,20 @@
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:exsl="http://exslt.org/common"
+ xmlns:func="http://exslt.org/functions"
+ xmlns:my="my-namespace"
+ extension-element-prefixes="exsl func">
+
+<xsl:template match="/">
+ <xsl:variable name="var">
+ <var>value</var>
+ </xsl:variable>
+ <xsl:copy-of select="my:func($var)"/>
+</xsl:template>
+
+<func:function name="my:func">
+ <xsl:param name="var"/>
+ <func:result select="$var"/>
+</func:function>
+
+</xsl:stylesheet>
diff --git a/tests/general/bug-211.out b/tests/general/bug-211.out
new file mode 100644
index 0000000..7b3cf11
--- /dev/null
+++ b/tests/general/bug-211.out
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+__
diff --git a/tests/general/bug-211.xsl b/tests/general/bug-211.xsl
new file mode 100644
index 0000000..557f5fb
--- /dev/null
+++ b/tests/general/bug-211.xsl
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:str="http://exslt.org/strings"
+ xmlns:fn="http://exslt.org/functions"
+ xmlns:adoc="http://asciidoc.org/"
+ extension-element-prefixes="fn">
+
+ <fn:function name="adoc:sanitize">
+ <xsl:param name="id"/>
+ <xsl:variable name="tmp" select="str:replace($id, '__', '_')"/>
+ <xsl:choose>
+ <xsl:when test="contains($tmp, '__')">
+ <fn:result select="adoc:sanitize($tmp)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <fn:result select="$id"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </fn:function>
+
+ <xsl:template match="*">
+ <xsl:value-of select="adoc:sanitize('________')"/>
+ </xsl:template>
+
+</xsl:stylesheet>
--
1.8.3.1

View File

@ -1,32 +0,0 @@
From c75b811de0afeea6acf19c99a755b8e1c0585aa9 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Thu, 25 Apr 2019 11:16:58 +0200
Subject: [PATCH 12/26] Fix integer overflow in _exsltDateDayInWeek
Found by OSS-Fuzz.
---
libexslt/date.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/libexslt/date.c b/libexslt/date.c
index 32c9db7..d075adc 100644
--- a/libexslt/date.c
+++ b/libexslt/date.c
@@ -1474,11 +1474,12 @@ _exsltDateDayInWeek(long yday, long yr)
long ret;
if (yr <= 0) {
- ret = ((yr-2 + ((yr/4)-(yr/100)+(yr/400)) + yday) % 7);
+ /* Compute modulus twice to avoid integer overflow */
+ ret = ((yr%7-2 + ((yr/4)-(yr/100)+(yr/400)) + yday) % 7);
if (ret < 0)
ret += 7;
} else
- ret = (((yr-1) + (((yr-1)/4)-((yr-1)/100)+((yr-1)/400)) + yday) % 7);
+ ret = (((yr%7-1) + (((yr-1)/4)-((yr-1)/100)+((yr-1)/400)) + yday) % 7);
return ret;
}
--
1.8.3.1

View File

@ -1,29 +0,0 @@
From c5eb6cf3aba0af048596106ed839b4ae17ecbcb1 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sat, 27 Apr 2019 11:19:48 +0200
Subject: [PATCH 14/26] Fix uninitialized read of xsl:number token
Found by OSS-Fuzz.
---
libxslt/numbers.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/libxslt/numbers.c b/libxslt/numbers.c
index 89e1f66..75c31eb 100644
--- a/libxslt/numbers.c
+++ b/libxslt/numbers.c
@@ -382,7 +382,10 @@ xsltNumberFormatTokenize(const xmlChar *format,
tokens->tokens[tokens->nTokens].token = val - 1;
ix += len;
val = xmlStringCurrentChar(NULL, format+ix, &len);
- }
+ } else {
+ tokens->tokens[tokens->nTokens].token = (xmlChar)'0';
+ tokens->tokens[tokens->nTokens].width = 1;
+ }
} else if ( (val == (xmlChar)'A') ||
(val == (xmlChar)'a') ||
(val == (xmlChar)'I') ||
--
1.8.3.1

View File

@ -1,39 +0,0 @@
From dfa1bdceaef73a404d1c6efe58c3618493b36afb Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sat, 22 Sep 2018 15:47:10 +0200
Subject: [PATCH 14/33] Variables need 'extern' in static lib on Cygwin
---
libexslt/exsltexports.h | 2 +-
libxslt/xsltexports.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libexslt/exsltexports.h b/libexslt/exsltexports.h
index 21c49a4..eee8222 100644
--- a/libexslt/exsltexports.h
+++ b/libexslt/exsltexports.h
@@ -124,7 +124,7 @@
#if !defined(LIBEXSLT_STATIC)
#define EXSLTPUBVAR __declspec(dllimport) extern
#else
- #define EXSLTPUBVAR
+ #define EXSLTPUBVAR extern
#endif
#endif
#define EXSLTCALL __cdecl
diff --git a/libxslt/xsltexports.h b/libxslt/xsltexports.h
index 37b43bf..99b6ac3 100644
--- a/libxslt/xsltexports.h
+++ b/libxslt/xsltexports.h
@@ -126,7 +126,7 @@
#if !defined(LIBXSLT_STATIC)
#define XSLTPUBVAR __declspec(dllimport) extern
#else
- #define XSLTPUBVAR
+ #define XSLTPUBVAR extern
#endif
#endif
#define XSLTCALL __cdecl
--
1.8.3.1

View File

@ -1,220 +0,0 @@
From de6d869a8ef5ca327231fb73489f4c9024d8757a Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sat, 27 Apr 2019 14:33:29 +0200
Subject: [PATCH 15/26] Fix numbering in non-Latin scripts
The `token` type wasn't wide enough to hold a Unicode code point.
---
libxslt/numbers.c | 24 +++++++++--------
tests/docs/bug-219.xml | 22 +++++++++++++++
tests/general/bug-219.out | 68 +++++++++++++++++++++++++++++++++++++++++++++++
tests/general/bug-219.xsl | 17 ++++++++++++
4 files changed, 120 insertions(+), 11 deletions(-)
create mode 100644 tests/docs/bug-219.xml
create mode 100644 tests/general/bug-219.out
create mode 100644 tests/general/bug-219.xsl
diff --git a/libxslt/numbers.c b/libxslt/numbers.c
index 75c31eb..0a2a51c 100644
--- a/libxslt/numbers.c
+++ b/libxslt/numbers.c
@@ -36,7 +36,7 @@
#define SYMBOL_QUOTE ((xmlChar)'\'')
-#define DEFAULT_TOKEN (xmlChar)'0'
+#define DEFAULT_TOKEN '0'
#define DEFAULT_SEPARATOR "."
#define MAX_TOKENS 1024
@@ -45,7 +45,7 @@ typedef struct _xsltFormatToken xsltFormatToken;
typedef xsltFormatToken *xsltFormatTokenPtr;
struct _xsltFormatToken {
xmlChar *separator;
- xmlChar token;
+ int token;
int width;
};
@@ -107,20 +107,22 @@ xsltUTF8Charcmp(xmlChar *utf1, xmlChar *utf2) {
(xsltUTF8Charcmp((letter), (self)->patternSeparator) == 0))
#define IS_DIGIT_ZERO(x) xsltIsDigitZero(x)
-#define IS_DIGIT_ONE(x) xsltIsDigitZero((xmlChar)(x)-1)
+#define IS_DIGIT_ONE(x) xsltIsDigitZero((x)-1)
static int
xsltIsDigitZero(unsigned int ch)
{
/*
* Reference: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
+ *
+ * There a many more digit ranges in newer Unicode versions. These
+ * are only the zeros that match Digit in XML 1.0 (IS_DIGIT macro).
*/
switch (ch) {
case 0x0030: case 0x0660: case 0x06F0: case 0x0966:
case 0x09E6: case 0x0A66: case 0x0AE6: case 0x0B66:
case 0x0C66: case 0x0CE6: case 0x0D66: case 0x0E50:
- case 0x0E60: case 0x0F20: case 0x1040: case 0x17E0:
- case 0x1810: case 0xFF10:
+ case 0x0ED0: case 0x0F20:
return TRUE;
default:
return FALSE;
@@ -383,13 +385,13 @@ xsltNumberFormatTokenize(const xmlChar *format,
ix += len;
val = xmlStringCurrentChar(NULL, format+ix, &len);
} else {
- tokens->tokens[tokens->nTokens].token = (xmlChar)'0';
+ tokens->tokens[tokens->nTokens].token = '0';
tokens->tokens[tokens->nTokens].width = 1;
}
- } else if ( (val == (xmlChar)'A') ||
- (val == (xmlChar)'a') ||
- (val == (xmlChar)'I') ||
- (val == (xmlChar)'i') ) {
+ } else if ( (val == 'A') ||
+ (val == 'a') ||
+ (val == 'I') ||
+ (val == 'i') ) {
tokens->tokens[tokens->nTokens].token = val;
ix += len;
val = xmlStringCurrentChar(NULL, format+ix, &len);
@@ -400,7 +402,7 @@ xsltNumberFormatTokenize(const xmlChar *format,
* not support a numbering sequence that starts with that
* token, it must use a format token of 1."
*/
- tokens->tokens[tokens->nTokens].token = (xmlChar)'0';
+ tokens->tokens[tokens->nTokens].token = '0';
tokens->tokens[tokens->nTokens].width = 1;
}
/*
diff --git a/tests/docs/bug-219.xml b/tests/docs/bug-219.xml
new file mode 100644
index 0000000..6549781
--- /dev/null
+++ b/tests/docs/bug-219.xml
@@ -0,0 +1,22 @@
+<test>
+ <formats>
+ <format>&#x0660;&#x0661;</format>
+ <format>&#x06F0;&#x06F1;</format>
+ <format>&#x0966;&#x0967;</format>
+ <format>&#x09E6;&#x09E7;</format>
+ <format>&#x0A66;&#x0A67;</format>
+ <format>&#x0AE6;&#x0AE7;</format>
+ <format>&#x0B66;&#x0B67;</format>
+ <format>&#x0C66;&#x0C67;</format>
+ <format>&#x0CE6;&#x0CE7;</format>
+ <format>&#x0D66;&#x0D67;</format>
+ <format>&#x0E50;&#x0E51;</format>
+ <format>&#x0ED0;&#x0ED1;</format>
+ <format>&#x0F20;&#x0F21;</format>
+ </formats>
+ <values>
+ <value>0</value>
+ <value>9</value>
+ <value>1234567890</value>
+ </values>
+</test>
diff --git a/tests/general/bug-219.out b/tests/general/bug-219.out
new file mode 100644
index 0000000..908043c
--- /dev/null
+++ b/tests/general/bug-219.out
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<results>
+ <format f="&#x660;&#x661;">
+ <value v="0">٠٠</value>
+ <value v="9">٠٩</value>
+ <value v="1234567890">١٢٣٤٥٦٧٨٩٠</value>
+ </format>
+ <format f="&#x6F0;&#x6F1;">
+ <value v="0">۰۰</value>
+ <value v="9">۰۹</value>
+ <value v="1234567890">۱۲۳۴۵۶۷۸۹۰</value>
+ </format>
+ <format f="&#x966;&#x967;">
+ <value v="0"></value>
+ <value v="9">०९</value>
+ <value v="1234567890">१२३४५६७८९०</value>
+ </format>
+ <format f="&#x9E6;&#x9E7;">
+ <value v="0"></value>
+ <value v="9">০৯</value>
+ <value v="1234567890">১২৩৪৫৬৭৮৯০</value>
+ </format>
+ <format f="&#xA66;&#xA67;">
+ <value v="0"></value>
+ <value v="9">੦੯</value>
+ <value v="1234567890">੧੨੩੪੫੬੭੮੯੦</value>
+ </format>
+ <format f="&#xAE6;&#xAE7;">
+ <value v="0"></value>
+ <value v="9">૦૯</value>
+ <value v="1234567890">૧૨૩૪૫૬૭૮૯૦</value>
+ </format>
+ <format f="&#xB66;&#xB67;">
+ <value v="0"></value>
+ <value v="9">୦୯</value>
+ <value v="1234567890">୧୨୩୪୫୬୭୮୯୦</value>
+ </format>
+ <format f="&#xC66;&#xC67;">
+ <value v="0"></value>
+ <value v="9">౦౯</value>
+ <value v="1234567890">౧౨౩౪౫౬౭౮౯౦</value>
+ </format>
+ <format f="&#xCE6;&#xCE7;">
+ <value v="0"></value>
+ <value v="9">೦೯</value>
+ <value v="1234567890">೧೨೩೪೫೬೭೮೯೦</value>
+ </format>
+ <format f="&#xD66;&#xD67;">
+ <value v="0"></value>
+ <value v="9">൦൯</value>
+ <value v="1234567890">൧൨൩൪൫൬൭൮൯൦</value>
+ </format>
+ <format f="&#xE50;&#xE51;">
+ <value v="0"></value>
+ <value v="9">๐๙</value>
+ <value v="1234567890">๑๒๓๔๕๖๗๘๙๐</value>
+ </format>
+ <format f="&#xED0;&#xED1;">
+ <value v="0"></value>
+ <value v="9">໐໙</value>
+ <value v="1234567890">໑໒໓໔໕໖໗໘໙໐</value>
+ </format>
+ <format f="&#xF20;&#xF21;">
+ <value v="0">༠༠</value>
+ <value v="9">༠༩</value>
+ <value v="1234567890">༡༢༣༤༥༦༧༨༩༠</value>
+ </format>
+</results>
diff --git a/tests/general/bug-219.xsl b/tests/general/bug-219.xsl
new file mode 100644
index 0000000..e291994
--- /dev/null
+++ b/tests/general/bug-219.xsl
@@ -0,0 +1,17 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:output indent="yes"/>
+ <xsl:template match="test">
+ <results>
+ <xsl:for-each select="formats/format">
+ <format f="{.}">
+ <xsl:variable name="f" select="."/>
+ <xsl:for-each select="/test/values/value">
+ <value v="{.}">
+ <xsl:number value="." format="{$f}"/>
+ </value>
+ </xsl:for-each>
+ </format>
+ </xsl:for-each>
+ </results>
+ </xsl:template>
+</xsl:stylesheet>
--
1.8.3.1

View File

@ -1,43 +0,0 @@
From 11707a80c2af681832689e6a6d1b66674d6c2ccb Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 23 Jan 2018 18:23:37 +0100
Subject: [PATCH 18/33] Fix misleading indentation in security.c
---
libxslt/security.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/libxslt/security.c b/libxslt/security.c
index 9c848cc..550dc4e 100644
--- a/libxslt/security.c
+++ b/libxslt/security.c
@@ -385,16 +385,18 @@ xsltCheckWrite(xsltSecurityPrefsPtr sec,
(xmlStrEqual(BAD_CAST uri->scheme, BAD_CAST "file"))) {
#if defined(_WIN32) && !defined(__CYGWIN__)
- if ((uri->path)&&(uri->path[0]=='/')&&
- (uri->path[1]!='\0')&&(uri->path[2]==':'))
- ret = xsltCheckWritePath(sec, ctxt, uri->path+1);
- else
+ if ((uri->path)&&(uri->path[0]=='/')&&
+ (uri->path[1]!='\0')&&(uri->path[2]==':'))
+ ret = xsltCheckWritePath(sec, ctxt, uri->path+1);
+ else
#endif
+ {
+ /*
+ * Check if we are allowed to write this file
+ */
+ ret = xsltCheckWritePath(sec, ctxt, uri->path);
+ }
- /*
- * Check if we are allowed to write this file
- */
- ret = xsltCheckWritePath(sec, ctxt, uri->path);
if (ret <= 0) {
xmlFreeURI(uri);
return(ret);
--
1.8.3.1

View File

@ -1,55 +0,0 @@
From 8a5dcc6e9da769bb49ce6a750cc0ef094d621b43 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Fri, 10 May 2019 14:23:24 +0200
Subject: [PATCH 19/26] Avoid quadratic behavior in xsltSaveResultTo
xmlNodeDumpOutput tries to detect XHTML documents and calls
xmlGetIntSubset which iterates the children of the result document
fragment again, leading to quadratic behavior.
Unfortunately, there's no way to tell xmlNodeDumpOutput which
serialization mode to use and skip auto-detection. The xmlsave API has
such an option, but it lacks a function to create an xmlSaveCtxt from
an existing xmlOutputBuffer.
Temporarily set result->children to NULL. This works because the
internal subset is always available from result->intSubset.
Found by OSS-Fuzz.
---
libxslt/xsltutils.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/libxslt/xsltutils.c b/libxslt/xsltutils.c
index 61f5c25..5e95787 100644
--- a/libxslt/xsltutils.c
+++ b/libxslt/xsltutils.c
@@ -1578,7 +1578,15 @@ xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result,
xmlOutputBufferWriteString(buf, "?>\n");
}
if (result->children != NULL) {
- xmlNodePtr child = result->children;
+ xmlNodePtr children = result->children;
+ xmlNodePtr child = children;
+
+ /*
+ * Hack to avoid quadratic behavior when scanning
+ * result->children in xmlGetIntSubset called by
+ * xmlNodeDumpOutput.
+ */
+ result->children = NULL;
while (child != NULL) {
xmlNodeDumpOutput(buf, result, child, 0, (indent == 1),
@@ -1591,6 +1599,8 @@ xsltSaveResultTo(xmlOutputBufferPtr buf, xmlDocPtr result,
}
if (indent)
xmlOutputBufferWriteString(buf, "\n");
+
+ result->children = children;
}
xmlOutputBufferFlush(buf);
}
--
1.8.3.1

View File

@ -1,75 +0,0 @@
From 7434b5569fe9bc858900e66580d17e3b80cb80fc Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 12 May 2019 15:15:19 +0200
Subject: [PATCH 23/26] Fix insertion of xsl:fallback content
Fixes bug #730171: https://bugzilla.gnome.org/show_bug.cgi?id=730171
---
libxslt/transform.c | 2 ++
tests/docs/bug-220.xml | 1 +
tests/general/bug-220.out | 2 ++
tests/general/bug-220.xsl | 15 +++++++++++++++
4 files changed, 20 insertions(+)
create mode 100644 tests/docs/bug-220.xml
create mode 100644 tests/general/bug-220.out
create mode 100644 tests/general/bug-220.xsl
diff --git a/libxslt/transform.c b/libxslt/transform.c
index cf6ce67..b8dc363 100644
--- a/libxslt/transform.c
+++ b/libxslt/transform.c
@@ -2884,6 +2884,7 @@ xsltApplySequenceConstructor(xsltTransformContextPtr ctxt,
/*
* Search if there are fallbacks
*/
+ ctxt->insert = insert;
child = cur->children;
while (child != NULL) {
if ((IS_XSLT_ELEM(child)) &&
@@ -2895,6 +2896,7 @@ xsltApplySequenceConstructor(xsltTransformContextPtr ctxt,
}
child = child->next;
}
+ ctxt->insert = oldInsert;
if (!found) {
xsltTransformError(ctxt, NULL, cur,
diff --git a/tests/docs/bug-220.xml b/tests/docs/bug-220.xml
new file mode 100644
index 0000000..69d62f2
--- /dev/null
+++ b/tests/docs/bug-220.xml
@@ -0,0 +1 @@
+<doc/>
diff --git a/tests/general/bug-220.out b/tests/general/bug-220.out
new file mode 100644
index 0000000..abb48c3
--- /dev/null
+++ b/tests/general/bug-220.out
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<r><fallback/></r>
diff --git a/tests/general/bug-220.xsl b/tests/general/bug-220.xsl
new file mode 100644
index 0000000..cc4e3e0
--- /dev/null
+++ b/tests/general/bug-220.xsl
@@ -0,0 +1,15 @@
+<xsl:stylesheet
+ version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:ext="ext"
+ extension-element-prefixes="ext">
+<xsl:template match="/">
+ <r>
+ <ext:e>
+ <xsl:fallback><fallback/></xsl:fallback>
+ <ext:f/>
+ </ext:e>
+ </r>
+</xsl:template>
+</xsl:stylesheet>
+
--
1.8.3.1

View File

@ -1,24 +0,0 @@
From 00b327b6ca85a64ce9bf521a04a6d1ca84f21f82 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 12 Feb 2019 02:45:50 +0100
Subject: [PATCH 25/33] Fix memory leak in EXSLT functions error path
---
libexslt/functions.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/libexslt/functions.c b/libexslt/functions.c
index 6005671..075e236 100644
--- a/libexslt/functions.c
+++ b/libexslt/functions.c
@@ -476,6 +476,7 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
"executing a function\n",
ctxt->context->functionURI, ctxt->context->function);
xmlFreeNode(fake);
+ xmlXPathFreeObject(ret);
goto error;
}
xmlFreeNode(fake);
--
1.8.3.1

View File

@ -1,40 +0,0 @@
From 0921b596cc897ebc1fd57988b475aa7b430812f0 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Thu, 16 May 2019 21:19:55 +0200
Subject: [PATCH 25/26] Fix unsigned integer overflow in date.c
---
libexslt/date.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/libexslt/date.c b/libexslt/date.c
index d075adc..60defff 100644
--- a/libexslt/date.c
+++ b/libexslt/date.c
@@ -141,9 +141,9 @@ struct _exsltDateDurVal {
#define IS_LEAP(y) \
(((y & 3) == 0) && ((y % 25 != 0) || ((y & 15) == 0)))
-static const unsigned long daysInMonth[12] =
+static const long daysInMonth[12] =
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-static const unsigned long daysInMonthLeap[12] =
+static const long daysInMonthLeap[12] =
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
#define MAX_DAYINMONTH(yr,mon) \
@@ -177,9 +177,9 @@ static const unsigned long daysInMonthLeap[12] =
#define DAYS_PER_EPOCH (400 * 365 + 100 - 4 + 1)
#define YEARS_PER_EPOCH 400
-static const unsigned long dayInYearByMonth[12] =
+static const long dayInYearByMonth[12] =
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
-static const unsigned long dayInLeapYearByMonth[12] =
+static const long dayInLeapYearByMonth[12] =
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
#define DAY_IN_YEAR(day, month, year) \
--
1.8.3.1

View File

@ -1,101 +0,0 @@
From 99eb3e4358c93984de7597f6fdc8bb64973046c5 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 11 Feb 2019 23:29:53 +0100
Subject: [PATCH 26/33] Initialize ctxt->output before evaluating global vars
Otherwise, an xsl:element in an EXSLT function could lead to a null
pointer dereference. Also initialize some other variables earlier.
Fixes #10.
---
libxslt/transform.c | 13 +++++++------
tests/docs/bug-215.xml | 1 +
tests/general/bug-215.err | 8 ++++++++
tests/general/bug-215.out | 0
tests/general/bug-215.xsl | 6 ++++++
5 files changed, 22 insertions(+), 6 deletions(-)
create mode 100644 tests/docs/bug-215.xml
create mode 100644 tests/general/bug-215.err
create mode 100644 tests/general/bug-215.out
create mode 100644 tests/general/bug-215.xsl
diff --git a/libxslt/transform.c b/libxslt/transform.c
index ed5afac..1379391 100644
--- a/libxslt/transform.c
+++ b/libxslt/transform.c
@@ -6011,6 +6011,13 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
res->encoding = xmlStrdup(encoding);
variables = style->variables;
+ ctxt->node = (xmlNodePtr) doc;
+ ctxt->output = res;
+
+ ctxt->xpathCtxt->contextSize = 1;
+ ctxt->xpathCtxt->proximityPosition = 1;
+ ctxt->xpathCtxt->node = NULL; /* TODO: Set the context node here? */
+
/*
* Start the evaluation, evaluate the params, the stylesheets globals
* and start by processing the top node.
@@ -6020,7 +6027,6 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
/*
* Evaluate global params and user-provided params.
*/
- ctxt->node = (xmlNodePtr) doc;
if (ctxt->globalVars == NULL)
ctxt->globalVars = xmlHashCreate(20);
if (params != NULL) {
@@ -6035,14 +6041,9 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
/* Clean up any unused RVTs. */
xsltReleaseLocalRVTs(ctxt, NULL);
- ctxt->node = (xmlNodePtr) doc;
- ctxt->output = res;
ctxt->insert = (xmlNodePtr) res;
ctxt->varsBase = ctxt->varsNr - 1;
- ctxt->xpathCtxt->contextSize = 1;
- ctxt->xpathCtxt->proximityPosition = 1;
- ctxt->xpathCtxt->node = NULL; /* TODO: Set the context node here? */
/*
* Start processing the source tree -----------------------------------
*/
diff --git a/tests/docs/bug-215.xml b/tests/docs/bug-215.xml
new file mode 100644
index 0000000..ead3414
--- /dev/null
+++ b/tests/docs/bug-215.xml
@@ -0,0 +1 @@
+<empty/>
diff --git a/tests/general/bug-215.err b/tests/general/bug-215.err
new file mode 100644
index 0000000..a4fbd23
--- /dev/null
+++ b/tests/general/bug-215.err
@@ -0,0 +1,8 @@
+ ELEMENT fake
+element fake: error : Node has no parent
+ ELEMENT elem
+{DEF}f: cannot write to result tree while executing a function
+xmlXPathCompiledEval: No result on the stack.
+runtime error: file ./bug-215.xsl line 5 element variable
+Evaluating global variable var/param being computed failed
+no result for ./../docs/bug-215.xml
diff --git a/tests/general/bug-215.out b/tests/general/bug-215.out
new file mode 100644
index 0000000..e69de29
diff --git a/tests/general/bug-215.xsl b/tests/general/bug-215.xsl
new file mode 100644
index 0000000..0dabaaa
--- /dev/null
+++ b/tests/general/bug-215.xsl
@@ -0,0 +1,6 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:func="http://exslt.org/functions" xmlns:abc="DEF" version="1.0" extension-element-prefixes="func">
+ <func:function name="abc:f">
+ <xsl:element name="elem"/>
+ </func:function>
+ <xsl:variable name="v" select="abc:f()"/>
+</xsl:stylesheet>
--
1.8.3.1

View File

@ -1,90 +0,0 @@
From 45d1d8597ed1b330ff059dcde81a8d09c477a049 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Tue, 12 Feb 2019 01:52:31 +0100
Subject: [PATCH 27/33] Backup context node in exsltFuncFunctionFunction
exsltFuncFunctionFunction handles XPath extension functions and is called
from the XPath engine. Since evaluation of function templates can change
the XPath context node, it must be backed up to avoid corruption.
Without proper backup, evaluating certain content in function templates
could also result in use-after-free errors.
It seems that libxml2 commit 029d0e96 helped to expose the error.
Fixes #11.
---
libexslt/functions.c | 6 +++++-
tests/docs/bug-216.xml | 1 +
tests/general/bug-216.out | 2 ++
tests/general/bug-216.xsl | 11 +++++++++++
4 files changed, 19 insertions(+), 1 deletion(-)
create mode 100644 tests/docs/bug-216.xml
create mode 100644 tests/general/bug-216.out
create mode 100644 tests/general/bug-216.xsl
diff --git a/libexslt/functions.c b/libexslt/functions.c
index 075e236..41d3749 100644
--- a/libexslt/functions.c
+++ b/libexslt/functions.c
@@ -291,7 +291,7 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
xmlXPathObjectPtr oldResult, ret;
exsltFuncData *data;
exsltFuncFunctionData *func;
- xmlNodePtr paramNode, oldInsert, fake;
+ xmlNodePtr paramNode, oldInsert, oldXPNode, fake;
int oldBase;
void *oldCtxtVar;
xsltStackElemPtr params = NULL, param;
@@ -360,6 +360,9 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
}
tctxt->depth++;
+ /* Evaluating templates can change the XPath context node. */
+ oldXPNode = tctxt->xpathCtxt->node;
+
/*
* We have a problem with the evaluation of function parameters.
* The original library code did not evaluate XPath expressions until
@@ -446,5 +449,6 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
if (params != NULL)
xsltFreeStackElemList(params);
+ tctxt->xpathCtxt->node = oldXPNode;
if (data->error != 0)
goto error;
diff --git a/tests/docs/bug-216.xml b/tests/docs/bug-216.xml
new file mode 100644
index 0000000..d128aec
--- /dev/null
+++ b/tests/docs/bug-216.xml
@@ -0,0 +1 @@
+<top xmlns:ns1="abc"/>
diff --git a/tests/general/bug-216.out b/tests/general/bug-216.out
new file mode 100644
index 0000000..40f6b10
--- /dev/null
+++ b/tests/general/bug-216.out
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+10
diff --git a/tests/general/bug-216.xsl b/tests/general/bug-216.xsl
new file mode 100644
index 0000000..50cc4b1
--- /dev/null
+++ b/tests/general/bug-216.xsl
@@ -0,0 +1,11 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:func="http://exslt.org/functions" version="1.0" extension-element-prefixes="func">
+ <func:function name="func:f">
+ <xsl:for-each select="namespace::*">
+ <xsl:sort/>
+ </xsl:for-each>
+ <func:result>10</func:result>
+ </func:function>
+ <xsl:template match="*">
+ <xsl:value-of select="func:f()+count(abc)"/>
+ </xsl:template>
+</xsl:stylesheet>
--
1.8.3.1

View File

@ -1,132 +0,0 @@
From 08b62c25871b38d5d573515ca8a065b4b8f64f6b Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Wed, 20 Feb 2019 13:24:37 +0100
Subject: [PATCH 31/33] Always set context node before calling XPath iterators
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The xmlXPathNext* iterators rely on the XPath context node being set to
the start node of the iteration. Some parts of the code base like the
xsl:key functions also leave the context node in an unspecified state.
Make sure that the context node is reset before invoking the XPath
iterators. Also backup and restore the context node in
xsltNumberFormatGetMultipleLevel for good measure.
This bug could also lead to type confusion and invalid reads in
connection with namespace nodes.
Fixes #13. Also see the Chromium bug report:
https://bugs.chromium.org/p/chromium/issues/detail?id=930663
Thanks to Nicolas Grégoire for the report.
---
libxslt/numbers.c | 31 ++++++++++++++++++++-----------
tests/docs/bug-218.xml | 1 +
tests/general/bug-218.out | 2 ++
tests/general/bug-218.xsl | 8 ++++++++
4 files changed, 31 insertions(+), 11 deletions(-)
create mode 100644 tests/docs/bug-218.xml
create mode 100644 tests/general/bug-218.out
create mode 100644 tests/general/bug-218.xsl
diff --git a/libxslt/numbers.c b/libxslt/numbers.c
index 0d34740..89e1f66 100644
--- a/libxslt/numbers.c
+++ b/libxslt/numbers.c
@@ -646,42 +646,51 @@ xsltNumberFormatGetMultipleLevel(xsltTransformContextPtr context,
{
int amount = 0;
int cnt;
+ xmlNodePtr oldCtxtNode;
xmlNodePtr ancestor;
xmlNodePtr preceding;
xmlXPathParserContextPtr parser;
- context->xpathCtxt->node = node;
+ oldCtxtNode = context->xpathCtxt->node;
parser = xmlXPathNewParserContext(NULL, context->xpathCtxt);
if (parser) {
/* ancestor-or-self::*[count] */
- for (ancestor = node;
- (ancestor != NULL) && (ancestor->type != XML_DOCUMENT_NODE);
- ancestor = xmlXPathNextAncestor(parser, ancestor)) {
-
+ ancestor = node;
+ while ((ancestor != NULL) && (ancestor->type != XML_DOCUMENT_NODE)) {
if ((fromPat != NULL) &&
xsltTestCompMatchList(context, ancestor, fromPat))
break; /* for */
+ /*
+ * The xmlXPathNext* iterators require that the context node is
+ * set to the start node. Calls to xsltTestCompMatch* may also
+ * leave the context node in an undefined state, so make sure
+ * that the context node is reset before each iterator invocation.
+ */
+
if (xsltTestCompMatchCount(context, ancestor, countPat, node)) {
/* count(preceding-sibling::*) */
cnt = 1;
- for (preceding =
- xmlXPathNextPrecedingSibling(parser, ancestor);
- preceding != NULL;
- preceding =
- xmlXPathNextPrecedingSibling(parser, preceding)) {
-
+ context->xpathCtxt->node = ancestor;
+ preceding = xmlXPathNextPrecedingSibling(parser, ancestor);
+ while (preceding != NULL) {
if (xsltTestCompMatchCount(context, preceding, countPat,
node))
cnt++;
+ context->xpathCtxt->node = ancestor;
+ preceding =
+ xmlXPathNextPrecedingSibling(parser, preceding);
}
array[amount++] = (double)cnt;
if (amount >= max)
break; /* for */
}
+ context->xpathCtxt->node = node;
+ ancestor = xmlXPathNextAncestor(parser, ancestor);
}
xmlXPathFreeParserContext(parser);
}
+ context->xpathCtxt->node = oldCtxtNode;
return amount;
}
diff --git a/tests/docs/bug-218.xml b/tests/docs/bug-218.xml
new file mode 100644
index 0000000..3806547
--- /dev/null
+++ b/tests/docs/bug-218.xml
@@ -0,0 +1 @@
+<top xmlns:ns1="foo"/>
diff --git a/tests/general/bug-218.out b/tests/general/bug-218.out
new file mode 100644
index 0000000..832a29e
--- /dev/null
+++ b/tests/general/bug-218.out
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+1
diff --git a/tests/general/bug-218.xsl b/tests/general/bug-218.xsl
new file mode 100644
index 0000000..fdbb7b1
--- /dev/null
+++ b/tests/general/bug-218.xsl
@@ -0,0 +1,8 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:key name="aaa" match="/bbb" use="./ccc"/>
+ <xsl:template match="*">
+ <xsl:for-each select="namespace::*[position()=2]">
+ <xsl:number from="key('e','f')"/>
+ </xsl:for-each>
+ </xsl:template>
+</xsl:stylesheet>
--
1.8.3.1

View File

@ -1,65 +0,0 @@
From 6df1b708bd02f05c6d85ddddc1ca7f5450ebc5ea Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Fri, 8 Mar 2019 12:59:09 +0100
Subject: [PATCH 32/33] Fix float casts in exsltDateDuration
Add range check before converting double to long to avoid undefined
behavior.
Found with libFuzzer and UBSan.
---
libexslt/date.c | 7 +++++--
tests/exslt/date/duration.2.out | 2 ++
tests/exslt/date/duration.2.xml | 1 +
3 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/libexslt/date.c b/libexslt/date.c
index 6a3eb58..32c9db7 100644
--- a/libexslt/date.c
+++ b/libexslt/date.c
@@ -3106,14 +3106,17 @@ exsltDateDuration (const xmlChar *number)
else
secs = xmlXPathCastStringToNumber(number);
- if ((xmlXPathIsNaN(secs)) || (xmlXPathIsInf(secs)))
+ if (xmlXPathIsNaN(secs))
+ return NULL;
+
+ days = floor(secs / SECS_PER_DAY);
+ if ((days <= LONG_MIN) || (days >= LONG_MAX))
return NULL;
dur = exsltDateCreateDuration();
if (dur == NULL)
return NULL;
- days = floor(secs / SECS_PER_DAY);
dur->day = (long)days;
dur->sec = secs - days * SECS_PER_DAY;
diff --git a/tests/exslt/date/duration.2.out b/tests/exslt/date/duration.2.out
index 688b176..87505d5 100644
--- a/tests/exslt/date/duration.2.out
+++ b/tests/exslt/date/duration.2.out
@@ -12,4 +12,6 @@ result :
duration : P10Y10Y
result :
duration : P10.0Y
+result :
+duration : 9999999999999999999999999
result :
\ No newline at end of file
diff --git a/tests/exslt/date/duration.2.xml b/tests/exslt/date/duration.2.xml
index 5bc250e..d81f21d 100644
--- a/tests/exslt/date/duration.2.xml
+++ b/tests/exslt/date/duration.2.xml
@@ -8,5 +8,6 @@
<date seconds="P10Y10H"/>
<date seconds="P10Y10Y"/>
<date seconds="P10.0Y"/>
+ <date seconds="9999999999999999999999999"/>
</page>
--
1.8.3.1

View File

@ -1,119 +0,0 @@
From e03553605b45c88f0b4b2980adfbbb8f6fca2fd6 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sun, 24 Mar 2019 09:51:39 +0100
Subject: [PATCH] Fix security framework bypass
xsltCheckRead and xsltCheckWrite return -1 in case of error but callers
don't check for this condition and allow access. With a specially
crafted URL, xsltCheckRead could be tricked into returning an error
because of a supposedly invalid URL that would still be loaded
succesfully later on.
Fixes #12.
Thanks to Felix Wilhelm for the report.
---
libxslt/documents.c | 18 ++++++++++--------
libxslt/imports.c | 9 +++++----
libxslt/transform.c | 9 +++++----
libxslt/xslt.c | 9 +++++----
4 files changed, 25 insertions(+), 20 deletions(-)
diff --git a/libxslt/documents.c b/libxslt/documents.c
index 3f3a7312..4aad11bb 100644
--- a/libxslt/documents.c
+++ b/libxslt/documents.c
@@ -296,10 +296,11 @@ xsltLoadDocument(xsltTransformContextPtr ctxt, const xmlChar *URI) {
int res;
res = xsltCheckRead(ctxt->sec, ctxt, URI);
- if (res == 0) {
- xsltTransformError(ctxt, NULL, NULL,
- "xsltLoadDocument: read rights for %s denied\n",
- URI);
+ if (res <= 0) {
+ if (res == 0)
+ xsltTransformError(ctxt, NULL, NULL,
+ "xsltLoadDocument: read rights for %s denied\n",
+ URI);
return(NULL);
}
}
@@ -372,10 +373,11 @@ xsltLoadStyleDocument(xsltStylesheetPtr style, const xmlChar *URI) {
int res;
res = xsltCheckRead(sec, NULL, URI);
- if (res == 0) {
- xsltTransformError(NULL, NULL, NULL,
- "xsltLoadStyleDocument: read rights for %s denied\n",
- URI);
+ if (res <= 0) {
+ if (res == 0)
+ xsltTransformError(NULL, NULL, NULL,
+ "xsltLoadStyleDocument: read rights for %s denied\n",
+ URI);
return(NULL);
}
}
diff --git a/libxslt/imports.c b/libxslt/imports.c
index 874870cc..3783b247 100644
--- a/libxslt/imports.c
+++ b/libxslt/imports.c
@@ -130,10 +130,11 @@ xsltParseStylesheetImport(xsltStylesheetPtr style, xmlNodePtr cur) {
int secres;
secres = xsltCheckRead(sec, NULL, URI);
- if (secres == 0) {
- xsltTransformError(NULL, NULL, NULL,
- "xsl:import: read rights for %s denied\n",
- URI);
+ if (secres <= 0) {
+ if (secres == 0)
+ xsltTransformError(NULL, NULL, NULL,
+ "xsl:import: read rights for %s denied\n",
+ URI);
goto error;
}
}
diff --git a/libxslt/transform.c b/libxslt/transform.c
index 13793914..0636dbd0 100644
--- a/libxslt/transform.c
+++ b/libxslt/transform.c
@@ -3493,10 +3493,11 @@ xsltDocumentElem(xsltTransformContextPtr ctxt, xmlNodePtr node,
*/
if (ctxt->sec != NULL) {
ret = xsltCheckWrite(ctxt->sec, ctxt, filename);
- if (ret == 0) {
- xsltTransformError(ctxt, NULL, inst,
- "xsltDocumentElem: write rights for %s denied\n",
- filename);
+ if (ret <= 0) {
+ if (ret == 0)
+ xsltTransformError(ctxt, NULL, inst,
+ "xsltDocumentElem: write rights for %s denied\n",
+ filename);
xmlFree(URL);
xmlFree(filename);
return;
diff --git a/libxslt/xslt.c b/libxslt/xslt.c
index 780a5ad7..a234eb79 100644
--- a/libxslt/xslt.c
+++ b/libxslt/xslt.c
@@ -6763,10 +6763,11 @@ xsltParseStylesheetFile(const xmlChar* filename) {
int res;
res = xsltCheckRead(sec, NULL, filename);
- if (res == 0) {
- xsltTransformError(NULL, NULL, NULL,
- "xsltParseStylesheetFile: read rights for %s denied\n",
- filename);
+ if (res <= 0) {
+ if (res == 0)
+ xsltTransformError(NULL, NULL, NULL,
+ "xsltParseStylesheetFile: read rights for %s denied\n",
+ filename);
return(NULL);
}
}
--
2.18.1

View File

@ -1,70 +0,0 @@
From 6ce8de69330783977dd14f6569419489875fb71b Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Mon, 3 Jun 2019 13:14:45 +0200
Subject: [PATCH] Fix uninitialized read with UTF-8 grouping chars
The character type in xsltFormatNumberConversion was too narrow and
an invalid character/length combination could be passed to
xsltNumberFormatDecimal, resulting in an uninitialized read.
Found by OSS-Fuzz.
---
libxslt/numbers.c | 5 +++--
tests/docs/bug-222.xml | 1 +
tests/general/bug-222.out | 2 ++
tests/general/bug-222.xsl | 6 ++++++
4 files changed, 12 insertions(+), 2 deletions(-)
create mode 100644 tests/docs/bug-222.xml
create mode 100644 tests/general/bug-222.out
create mode 100644 tests/general/bug-222.xsl
diff --git a/libxslt/numbers.c b/libxslt/numbers.c
index f1ed884..20b99d5 100644
--- a/libxslt/numbers.c
+++ b/libxslt/numbers.c
@@ -1298,13 +1298,14 @@ OUTPUT_NUMBER:
number = floor((scale * number + 0.5)) / scale;
if ((self->grouping != NULL) &&
(self->grouping[0] != 0)) {
+ int gchar;
len = xmlStrlen(self->grouping);
- pchar = xsltGetUTF8Char(self->grouping, &len);
+ gchar = xsltGetUTF8Char(self->grouping, &len);
xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0],
format_info.integer_digits,
format_info.group,
- pchar, len);
+ gchar, len);
} else
xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0],
format_info.integer_digits,
diff --git a/tests/docs/bug-222.xml b/tests/docs/bug-222.xml
new file mode 100644
index 0000000..69d62f2
--- /dev/null
+++ b/tests/docs/bug-222.xml
@@ -0,0 +1 @@
+<doc/>
diff --git a/tests/general/bug-222.out b/tests/general/bug-222.out
new file mode 100644
index 0000000..e313969
--- /dev/null
+++ b/tests/general/bug-222.out
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+1⠢0
diff --git a/tests/general/bug-222.xsl b/tests/general/bug-222.xsl
new file mode 100644
index 0000000..e32dc47
--- /dev/null
+++ b/tests/general/bug-222.xsl
@@ -0,0 +1,6 @@
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+ <xsl:decimal-format name="f" grouping-separator="⠢"/>
+ <xsl:template match="/">
+ <xsl:value-of select="format-number(10,'#⠢0','f')"/>
+ </xsl:template>
+</xsl:stylesheet>
--
1.7.12.4

View File

@ -1,29 +0,0 @@
From 2232473733b7313d67de8836ea3b29eec6e8e285 Mon Sep 17 00:00:00 2001
From: Nick Wellnhofer <wellnhofer@aevum.de>
Date: Sat, 17 Aug 2019 16:51:53 +0200
Subject: [PATCH] Fix dangling pointer in xsltCopyText
xsltCopyText didn't reset ctxt->lasttext in some cases which could
lead to various memory errors in relation with CDATA sections in input
documents.
Found by OSS-Fuzz.
---
libxslt/transform.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libxslt/transform.c b/libxslt/transform.c
index 95ebd073..d7ab0b66 100644
--- a/libxslt/transform.c
+++ b/libxslt/transform.c
@@ -1094,6 +1094,8 @@ xsltCopyText(xsltTransformContextPtr ctxt, xmlNodePtr target,
if ((copy->content = xmlStrdup(cur->content)) == NULL)
return NULL;
}
+
+ ctxt->lasttext = NULL;
} else {
/*
* normal processing. keep counters to extend the text node
--
2.22.0

Binary file not shown.

BIN
libxslt-1.1.34.tar.gz Executable file

Binary file not shown.

View File

@ -1,33 +1,12 @@
Name: libxslt
Version: 1.1.32
Release: 7
Version: 1.1.34
Release: 1
Summary: XSLT Transformation Library
License: MIT
URL: http://xmlsoft.org/libxslt/
Source0: https://github.com/GNOME/%{name}/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
# PATCH-FIX-UPSTREAM bug-fix https://github.com/GNOME/libxslt/
Patch6000:0009-Fix-handling-of-RVTs-returned-from-nested-EXSLT-func.patch
Patch6001:0012-Fix-EXSLT-functions-returning-RVTs-from-outer-scopes.patch
Patch6002:0014-Variables-need-extern-in-static-lib-on-Cygwin.patch
Patch6003:0018-Fix-misleading-indentation-in-security.c.patch
Patch6004:0025-Fix-memory-leak-in-EXSLT-functions-error-path.patch
Patch6005:0026-Initialize-ctxt-output-before-evaluating-global-vars.patch
Patch6006:0027-Backup-context-node-in-exsltFuncFunctionFunction.patch
Patch6007:0031-Always-set-context-node-before-calling-XPath-iterato.patch
Patch6008:0032-Fix-float-casts-in-exsltDateDuration.patch
# PATCH-CVE-UPSTREAM
Patch6009:CVE-2015-9019.patch
Patch6010:CVE-2019-11068.patch
# PATCH-FIX-UPSTREAM bug-fix https://github.com/GNOME/libxslt/
Patch6011:0004-Fix-check-of-xsltTestCompMatch-return-value.patch
Patch6012:0012-Fix-integer-overflow-in-_exsltDateDayInWeek.patch
Patch6013:0014-Fix-uninitialized-read-of-xsl-number-token.patch
Patch6014:0015-Fix-numbering-in-non-Latin-scripts.patch
Patch6015:0019-Avoid-quadratic-behavior-in-xsltSaveResultTo.patch
Patch6016:0023-Fix-insertion-of-xsl-fallback-content.patch
Patch6017:0025-Fix-unsigned-integer-overflow-in-date.c.patch
Patch6018:CVE-2019-18197.patch
Patch6019:CVE-2019-13118.patch
Patch0000:CVE-2015-9019.patch
BuildRequires: gcc make libtool autoconf automake libgcrypt-devel pkgconfig(libxml-2.0) >= 2.6.27
@ -110,13 +89,16 @@ make check
%files -n python2-libxslt
%{_libdir}/python2.7/site-packages/libxslt.py*
%{_libdir}/python2.7/site-packages/libxsltmod.so
%{_docdir}/libxslt-python-1.1.32/*
%{_docdir}/libxslt-python-1.1.34/*
%doc python/libxsltclass.txt
%doc python/tests/*.py
%doc python/tests/*.xml
%doc python/tests/*.xsl
%changelog
* Mon Jun 22 2020 linwei<linwei54@huawei.com> - 1.1.34-1
- update to 1.1.34
* Sat Jan 11 2020 zhangguangzhi<zhanguangzhi3@huawei.com> - 1.1.32-7
- del patch to be consistent with open source