commit 049c67f19e87ea6a7ab50493502ae198e63ad37f Author: overweight <5324761+overweight@user.noreply.gitee.com> Date: Mon Sep 30 10:59:48 2019 -0400 Package init diff --git a/0004-Fix-check-of-xsltTestCompMatch-return-value.patch b/0004-Fix-check-of-xsltTestCompMatch-return-value.patch new file mode 100644 index 0000000..c5bf50b --- /dev/null +++ b/0004-Fix-check-of-xsltTestCompMatch-return-value.patch @@ -0,0 +1,65 @@ +From 06d193fabb096370a969ca9f017f60bca7057262 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 + diff --git a/0009-Fix-handling-of-RVTs-returned-from-nested-EXSLT-func.patch b/0009-Fix-handling-of-RVTs-returned-from-nested-EXSLT-func.patch new file mode 100644 index 0000000..e9673dd --- /dev/null +++ b/0009-Fix-handling-of-RVTs-returned-from-nested-EXSLT-func.patch @@ -0,0 +1,94 @@ +From 8bd32f7753ac253a54279a0b6a88d15a57076bb0 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 @@ ++ +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 @@ ++ ++ +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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +1.8.3.1 + diff --git a/0012-Fix-EXSLT-functions-returning-RVTs-from-outer-scopes.patch b/0012-Fix-EXSLT-functions-returning-RVTs-from-outer-scopes.patch new file mode 100644 index 0000000..b0a9da1 --- /dev/null +++ b/0012-Fix-EXSLT-functions-returning-RVTs-from-outer-scopes.patch @@ -0,0 +1,312 @@ +From 7d81bd62d5788a9e2931c20a3d0a6be7e703c608 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 @@ ++ +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 @@ ++ +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 @@ ++ ++value +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 @@ ++ ++ ++ ++ ++ value ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +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 @@ ++ ++__ +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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +1.8.3.1 + diff --git a/0012-Fix-integer-overflow-in-_exsltDateDayInWeek.patch b/0012-Fix-integer-overflow-in-_exsltDateDayInWeek.patch new file mode 100644 index 0000000..56f059a --- /dev/null +++ b/0012-Fix-integer-overflow-in-_exsltDateDayInWeek.patch @@ -0,0 +1,32 @@ +From c75b811de0afeea6acf19c99a755b8e1c0585aa9 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 + diff --git a/0014-Fix-uninitialized-read-of-xsl-number-token.patch b/0014-Fix-uninitialized-read-of-xsl-number-token.patch new file mode 100644 index 0000000..601553f --- /dev/null +++ b/0014-Fix-uninitialized-read-of-xsl-number-token.patch @@ -0,0 +1,29 @@ +From c5eb6cf3aba0af048596106ed839b4ae17ecbcb1 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 + diff --git a/0014-Variables-need-extern-in-static-lib-on-Cygwin.patch b/0014-Variables-need-extern-in-static-lib-on-Cygwin.patch new file mode 100644 index 0000000..fa2b097 --- /dev/null +++ b/0014-Variables-need-extern-in-static-lib-on-Cygwin.patch @@ -0,0 +1,39 @@ +From dfa1bdceaef73a404d1c6efe58c3618493b36afb Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 + diff --git a/0015-Fix-numbering-in-non-Latin-scripts.patch b/0015-Fix-numbering-in-non-Latin-scripts.patch new file mode 100644 index 0000000..0253bab --- /dev/null +++ b/0015-Fix-numbering-in-non-Latin-scripts.patch @@ -0,0 +1,220 @@ +From de6d869a8ef5ca327231fb73489f4c9024d8757a Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 @@ ++ ++ ++ ٠١ ++ ۰۱ ++ ०१ ++ ০১ ++ ੦੧ ++ ૦૧ ++ ୦୧ ++ ౦౧ ++ ೦೧ ++ ൦൧ ++ ๐๑ ++ ໐໑ ++ ༠༡ ++ ++ ++ 0 ++ 9 ++ 1234567890 ++ ++ +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 @@ ++ ++ ++ ++ ٠٠ ++ ٠٩ ++ ١٢٣٤٥٦٧٨٩٠ ++ ++ ++ ۰۰ ++ ۰۹ ++ ۱۲۳۴۵۶۷۸۹۰ ++ ++ ++ ०० ++ ०९ ++ १२३४५६७८९० ++ ++ ++ ০০ ++ ০৯ ++ ১২৩৪৫৬৭৮৯০ ++ ++ ++ ੦੦ ++ ੦੯ ++ ੧੨੩੪੫੬੭੮੯੦ ++ ++ ++ ૦૦ ++ ૦૯ ++ ૧૨૩૪૫૬૭૮૯૦ ++ ++ ++ ୦୦ ++ ୦୯ ++ ୧୨୩୪୫୬୭୮୯୦ ++ ++ ++ ౦౦ ++ ౦౯ ++ ౧౨౩౪౫౬౭౮౯౦ ++ ++ ++ ೦೦ ++ ೦೯ ++ ೧೨೩೪೫೬೭೮೯೦ ++ ++ ++ ൦൦ ++ ൦൯ ++ ൧൨൩൪൫൬൭൮൯൦ ++ ++ ++ ๐๐ ++ ๐๙ ++ ๑๒๓๔๕๖๗๘๙๐ ++ ++ ++ ໐໐ ++ ໐໙ ++ ໑໒໓໔໕໖໗໘໙໐ ++ ++ ++ ༠༠ ++ ༠༩ ++ ༡༢༣༤༥༦༧༨༩༠ ++ ++ +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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +1.8.3.1 + diff --git a/0018-Fix-misleading-indentation-in-security.c.patch b/0018-Fix-misleading-indentation-in-security.c.patch new file mode 100644 index 0000000..733df18 --- /dev/null +++ b/0018-Fix-misleading-indentation-in-security.c.patch @@ -0,0 +1,43 @@ +From 11707a80c2af681832689e6a6d1b66674d6c2ccb Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 + diff --git a/0019-Avoid-quadratic-behavior-in-xsltSaveResultTo.patch b/0019-Avoid-quadratic-behavior-in-xsltSaveResultTo.patch new file mode 100644 index 0000000..905fc36 --- /dev/null +++ b/0019-Avoid-quadratic-behavior-in-xsltSaveResultTo.patch @@ -0,0 +1,55 @@ +From 8a5dcc6e9da769bb49ce6a750cc0ef094d621b43 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 + diff --git a/0023-Fix-insertion-of-xsl-fallback-content.patch b/0023-Fix-insertion-of-xsl-fallback-content.patch new file mode 100644 index 0000000..8d776b3 --- /dev/null +++ b/0023-Fix-insertion-of-xsl-fallback-content.patch @@ -0,0 +1,75 @@ +From 7434b5569fe9bc858900e66580d17e3b80cb80fc Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 @@ ++ +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 @@ ++ ++ +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 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +1.8.3.1 + diff --git a/0025-Fix-memory-leak-in-EXSLT-functions-error-path.patch b/0025-Fix-memory-leak-in-EXSLT-functions-error-path.patch new file mode 100644 index 0000000..24cbd06 --- /dev/null +++ b/0025-Fix-memory-leak-in-EXSLT-functions-error-path.patch @@ -0,0 +1,24 @@ +From 00b327b6ca85a64ce9bf521a04a6d1ca84f21f82 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 + diff --git a/0025-Fix-unsigned-integer-overflow-in-date.c.patch b/0025-Fix-unsigned-integer-overflow-in-date.c.patch new file mode 100644 index 0000000..899e3ad --- /dev/null +++ b/0025-Fix-unsigned-integer-overflow-in-date.c.patch @@ -0,0 +1,40 @@ +From 0921b596cc897ebc1fd57988b475aa7b430812f0 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 + diff --git a/0026-Initialize-ctxt-output-before-evaluating-global-vars.patch b/0026-Initialize-ctxt-output-before-evaluating-global-vars.patch new file mode 100644 index 0000000..556e1e3 --- /dev/null +++ b/0026-Initialize-ctxt-output-before-evaluating-global-vars.patch @@ -0,0 +1,101 @@ +From 99eb3e4358c93984de7597f6fdc8bb64973046c5 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 @@ ++ +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 @@ ++ ++ ++ ++ ++ ++ +-- +1.8.3.1 + diff --git a/0027-Backup-context-node-in-exsltFuncFunctionFunction.patch b/0027-Backup-context-node-in-exsltFuncFunctionFunction.patch new file mode 100644 index 0000000..2dd64e1 --- /dev/null +++ b/0027-Backup-context-node-in-exsltFuncFunctionFunction.patch @@ -0,0 +1,90 @@ +From 45d1d8597ed1b330ff059dcde81a8d09c477a049 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 @@ ++ +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 @@ ++ ++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 @@ ++ ++ ++ ++ ++ ++ 10 ++ ++ ++ ++ ++ +-- +1.8.3.1 + diff --git a/0031-Always-set-context-node-before-calling-XPath-iterato.patch b/0031-Always-set-context-node-before-calling-XPath-iterato.patch new file mode 100644 index 0000000..73e2865 --- /dev/null +++ b/0031-Always-set-context-node-before-calling-XPath-iterato.patch @@ -0,0 +1,132 @@ +From 08b62c25871b38d5d573515ca8a065b4b8f64f6b Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 @@ ++ +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 @@ ++ ++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 @@ ++ ++ ++ ++ ++ ++ ++ ++ +-- +1.8.3.1 + diff --git a/0032-Fix-float-casts-in-exsltDateDuration.patch b/0032-Fix-float-casts-in-exsltDateDuration.patch new file mode 100644 index 0000000..3e95e04 --- /dev/null +++ b/0032-Fix-float-casts-in-exsltDateDuration.patch @@ -0,0 +1,65 @@ +From 6df1b708bd02f05c6d85ddddc1ca7f5450ebc5ea Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 @@ + + + ++ + + +-- +1.8.3.1 + diff --git a/CVE-2015-9019.patch b/CVE-2015-9019.patch new file mode 100644 index 0000000..ca75f23 --- /dev/null +++ b/CVE-2015-9019.patch @@ -0,0 +1,37 @@ +--- a/libexslt/math.c 2017-10-30 15:49:55.000000000 +0800 ++++ b/libexslt/math.c 2019-04-18 15:00:54.524000000 +0800 +@@ -23,6 +23,13 @@ + #ifdef HAVE_STDLIB_H + #include + #endif ++#ifdef HAVE_UNISTD_H ++#include ++#endif ++#include ++#ifdef HAVE_TIME_H ++#include ++#endif + + #include "exslt.h" + +@@ -474,6 +481,20 @@ static double + exsltMathRandom (void) { + double ret; + int num; ++ long seed; ++ static int randinit = 0; ++ ++ if (!randinit) { ++ int fd = open("/dev/urandom",O_RDONLY); ++ ++ seed = time(NULL); /* just in case /dev/urandom is not there */ ++ if (fd == -1) { ++ read (fd, &seed, sizeof(seed)); ++ close (fd); ++ } ++ srand(seed); ++ randinit = 1; ++ } + + num = rand(); + ret = (double)num / (double)RAND_MAX; diff --git a/CVE-2019-11068.patch b/CVE-2019-11068.patch new file mode 100644 index 0000000..0fe5f5d --- /dev/null +++ b/CVE-2019-11068.patch @@ -0,0 +1,119 @@ +From e03553605b45c88f0b4b2980adfbbb8f6fca2fd6 Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +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 diff --git a/libxslt-1.1.26-utf8-docs.patch b/libxslt-1.1.26-utf8-docs.patch new file mode 100644 index 0000000..537718f --- /dev/null +++ b/libxslt-1.1.26-utf8-docs.patch @@ -0,0 +1,103 @@ +--- libxslt-1.1.26/ChangeLog.utf8 2009-07-24 10:16:49.000000000 +0200 ++++ libxslt-1.1.26/ChangeLog 2011-03-20 03:28:28.142684293 +0100 +@@ -284,7 +284,7 @@ + + Thu Aug 23 11:47:20 CEST 2007 Daniel Veillard + +- * libexslt/date.c: apply patch from Bjrn Wiberg fixing build on AIX ++ * libexslt/date.c: apply patch from Björn Wiberg fixing build on AIX + and closing bug #332173 + + Fri Aug 3 15:49:26 CEST 2007 Daniel Veillard +@@ -2112,7 +2112,7 @@ + Tue Feb 17 11:29:15 CET 2004 Daniel Veillard + + * libxslt/templates.c: applied patch from #134588 provided by +- Mariano Surez-Alvarez, attribute text node without doc. ++ Mariano Suárez-Alvarez, attribute text node without doc. + + Mon Feb 16 15:55:57 CET 2004 Daniel Veillard + +@@ -3121,7 +3121,7 @@ + * python/generator.py: fixed a problem in the generator where + the way functions are remapped as methods on classes was + not symetric and dependant on python internal hash order, +- as reported by Stphane Bidoul ++ as reported by Stéphane Bidoul + * libexslt/strings.c: attempt at fixing an object type pbm + * libxslt/triodef.h: update for OpenVMS from libxml2 + +@@ -3497,7 +3497,7 @@ + + Thu Jan 2 23:23:30 CET 2003 Daniel Veillard + +- * libexslt/strings.c: applied patch from Jrg Walter to provide ++ * libexslt/strings.c: applied patch from Jörg Walter to provide + URI escaping and unescaping functions. + + Thu Dec 26 15:43:31 CET 2002 Daniel Veillard +@@ -3507,7 +3507,7 @@ + + Mon Dec 23 15:43:59 CET 2002 Daniel Veillard + +- * python/libxslt.c: patch from Stphane Bidoul for Python 2.1 ++ * python/libxslt.c: patch from Stéphane Bidoul for Python 2.1 + + Sun Dec 22 22:54:04 CET 2002 Daniel Veillard + +@@ -3648,7 +3648,7 @@ + + Sun Nov 24 13:58:48 CET 2002 Daniel Veillard + +- * python/libxsl.py: updated with new version from Stphane Bidoul ++ * python/libxsl.py: updated with new version from Stéphane Bidoul + + Sat Nov 23 22:49:08 CET 2002 Igor Zlatkovic + +@@ -5036,7 +5036,7 @@ + + Mon Nov 26 11:21:27 CET 2001 Daniel Veillard + +- * libxslt/pattern.c: fixing bug #64044 reported by Gero Meiner, ++ * libxslt/pattern.c: fixing bug #64044 reported by Gero Meißner, + template matches compilation was failing to skip blanks bewteen + consecutive predicates + +@@ -5119,7 +5119,7 @@ + + Tue Oct 30 19:32:08 CET 2001 Daniel Veillard + +- * configure.in: applied patches from David Hrdeman closing ++ * configure.in: applied patches from David Härdeman closing + bug #62891 + + Tue Oct 30 15:25:19 CET 2001 Daniel Veillard +--- libxslt-1.1.26/NEWS.utf8 2009-09-24 16:38:20.000000000 +0200 ++++ libxslt-1.1.26/NEWS 2011-03-20 03:27:37.440684281 +0100 +@@ -312,7 +312,7 @@ + + + 1.1.4: Feb 23 2004: +- - bugfixes: attributes without doc (Mariano Surez-Alvarez), problem with ++ - bugfixes: attributes without doc (Mariano Suárez-Alvarez), problem with + Yelp, extension problem + - display extension modules (Steve Little) + - Windows compilation patch (Mark Vadoc), Mingw (Mikhail Grushinskiy) +@@ -472,7 +472,7 @@ + + + 1.0.24: Jan 14 2003: +- - bug fixes: imported global varables, python bindings (Stphane Bidoul), ++ - bug fixes: imported global varables, python bindings (Stéphane Bidoul), + EXSLT memory leak (Charles Bozeman), namespace generation on + xsl:attribute, space handling with imports (Daniel Stodden), + extension-element-prefixes (Josh Parsons), comments within xsl:text (Matt +@@ -485,7 +485,7 @@ + - fix the API generation scripts + - API to provide the sorting routines (Richard Jinks) + - added XML description of the EXSLT API +- - added ESXLT URI (un)escaping (Jrg Walter) ++ - added ESXLT URI (un)escaping (Jörg Walter) + - Some memory leaks have been found and fixed + - document() now support fragment identifiers in URIs + diff --git a/libxslt-1.1.32.tar.gz b/libxslt-1.1.32.tar.gz new file mode 100644 index 0000000..c8e57b1 Binary files /dev/null and b/libxslt-1.1.32.tar.gz differ diff --git a/libxslt.spec b/libxslt.spec new file mode 100644 index 0000000..b3cdeca --- /dev/null +++ b/libxslt.spec @@ -0,0 +1,124 @@ +Name: libxslt +Version: 1.1.32 +Release: 4 +Summary: XSLT Transformation Library +License: MIT +URL: http://xmlsoft.org/libxslt/ +Source0: ftp://xmlsoft.org/XSLT/libxslt-%{version}.tar.gz +# Fedora specific patches +Patch0: multilib.patch +Patch1: libxslt-1.1.26-utf8-docs.patch +# 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 + +BuildRequires: gcc make libtool autoconf automake libgcrypt-devel pkgconfig(libxml-2.0) >= 2.6.27 + +%description +Libxslt is the XSLT C library developed for the GNOME project + +%package devel +Summary: Development files for %{name} +Requires: %{name} = %{version}-%{release} +Requires: libgcrypt-devel libgpg-error-devel + +%description devel +%{name} allows you to transform XML files into other XML files +(or HTML, text, and more) using the standard XSLT stylesheet +transformation mechanism. + +%package_help + +%package -n python2-libxslt +%{?python_provide:%python_provide python2-libxslt} +Summary: Development files for %{name} +BuildRequires: python2-devel python2-libxml2 +Requires: %{name} = %{version}-%{release} +Requires: python2-libxml2 +Provides: %{name}-python = %{version}-%{release} + +%description -n python2-libxslt +The python2-libxslt package contains the python2 bindings for %{name} + +%prep +%autosetup -n %{name}-%{version} -p1 + +%build +chmod 644 python/tests/* +autoreconf -vfi +export PYTHON=/usr/bin/python2 +%configure --disable-static --disable-silent-rules --with-python +%make_build + +%install +%make_install +%delete_la +pushd $RPM_BUILD_ROOT/%{_includedir}/%{name}; touch -m --reference=xslt.h ../../bin/xslt-config;popd + +%check +make check + +%post +/sbin/ldconfig +%postun +/sbin/ldconfig + +%files +%defattr(-,root,root) +%doc ChangeLog NEWS README FEATURES AUTHORS +%license Copyright +%{_bindir}/xsltproc +%{_libdir}/libxslt.so.* +%{_libdir}/libexslt.so.* +%{_libdir}/libxslt-plugins/ +%{_mandir}/man1/xsltproc.1* + +%files devel +%{_libdir}/libxslt.so +%{_libdir}/libexslt.so +%{_libdir}/xsltConf.sh +%{_datadir}/aclocal/libxslt.m4 +%{_includedir}/libxslt/ +%{_includedir}/libexslt/ +%{_libdir}/pkgconfig/libxslt.pc +%{_libdir}/pkgconfig/libexslt.pc +%{_bindir}/xslt-config + + + +%files help +%doc %{_docdir}/%{name}-%{version} +%doc %{_mandir}/man3/* +%exclude %{_docdir}/%{name}/{ChangeLog,NEWS,README,FEATURES,AUTHORS} +%exclude %{_docdir}/../licenses/Copyright + +%files -n python2-libxslt +%{_libdir}/python2.7/site-packages/libxslt.py* +%{_libdir}/python2.7/site-packages/libxsltmod.so +%{_docdir}/libxslt-python-1.1.32/* +%doc python/libxsltclass.txt +%doc python/tests/*.py +%doc python/tests/*.xml +%doc python/tests/*.xsl + +%changelog +* Tue Sep 03 2019 openEuler Buildteam - 1.1.32-4 +- Package init diff --git a/multilib.patch b/multilib.patch new file mode 100644 index 0000000..94715d2 --- /dev/null +++ b/multilib.patch @@ -0,0 +1,24 @@ +*** XSLT/xslt-config.in.orig 2006-06-06 17:32:23.000000000 +0200 +--- XSLT/xslt-config.in 2006-06-06 17:32:48.000000000 +0200 +*************** +*** 4,10 **** + exec_prefix=@exec_prefix@ + exec_prefix_set=no + includedir=@includedir@ +! libdir=@libdir@ + + usage() + { +--- 4,15 ---- + exec_prefix=@exec_prefix@ + exec_prefix_set=no + includedir=@includedir@ +! if [ "`ldd /bin/sh | grep lib64`" = "" ] +! then +! libdir=${exec_prefix}/lib +! else +! libdir=${exec_prefix}/lib64 +! fi + + usage() + {