gnu: libxslt: Make generated documentation reproducible.
* gnu/packages/patches/libxslt-generated-ids.patch: New file. * gnu/packages/patches/libxslt-remove-date-timestamps.patch: Likewise. * gnu/packages/xml.scm (libxslt)[source]: Use them. * gnu/local.mk (dist_patch_DATA): Add them.
This commit is contained in:
parent
c3052d6bcd
commit
c74c7c1317
|
@ -603,6 +603,8 @@ dist_patch_DATA = \
|
|||
gnu/packages/patches/libwmf-CVE-2015-4695.patch \
|
||||
gnu/packages/patches/libwmf-CVE-2015-4696.patch \
|
||||
gnu/packages/patches/libxslt-CVE-2015-7995.patch \
|
||||
gnu/packages/patches/libxslt-generated-ids.patch \
|
||||
gnu/packages/patches/libxslt-remove-date-timestamps.patch \
|
||||
gnu/packages/patches/lirc-localstatedir.patch \
|
||||
gnu/packages/patches/libpthread-glibc-preparation.patch \
|
||||
gnu/packages/patches/lm-sensors-hwmon-attrs.patch \
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
This makes generated IDs deterministic.
|
||||
|
||||
Written by Daniel Veillard.
|
||||
|
||||
This should be fixed in next release (2.29).
|
||||
See https://bugzilla.gnome.org/show_bug.cgi?id=751621.
|
||||
|
||||
diff --git a/libxslt/functions.c b/libxslt/functions.c
|
||||
index 6448bde..5b00a6d 100644
|
||||
--- a/libxslt/functions.c
|
||||
+++ b/libxslt/functions.c
|
||||
@@ -651,6 +651,63 @@ xsltFormatNumberFunction(xmlXPathParserContextPtr ctxt, int nargs)
|
||||
}
|
||||
|
||||
/**
|
||||
+ * xsltCleanupIds:
|
||||
+ * @ctxt: the transformation context
|
||||
+ * @root: the root of the resulting document
|
||||
+ *
|
||||
+ * This clean up ids which may have been saved in Element contents
|
||||
+ * by xsltGenerateIdFunction() to provide stable IDs on elements.
|
||||
+ *
|
||||
+ * Returns the number of items cleaned or -1 in case of error
|
||||
+ */
|
||||
+int
|
||||
+xsltCleanupIds(xsltTransformContextPtr ctxt, xmlNodePtr root) {
|
||||
+ xmlNodePtr cur;
|
||||
+ int count = 0;
|
||||
+
|
||||
+ if ((ctxt == NULL) || (root == NULL))
|
||||
+ return(-1);
|
||||
+ if (root->type != XML_ELEMENT_NODE)
|
||||
+ return(-1);
|
||||
+
|
||||
+ cur = root;
|
||||
+ while (cur != NULL) {
|
||||
+ if (cur->type == XML_ELEMENT_NODE) {
|
||||
+ if (cur->content != NULL) {
|
||||
+ cur->content = NULL;
|
||||
+ count++;
|
||||
+ }
|
||||
+ if (cur->children != NULL) {
|
||||
+ cur = cur->children;
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+ if (cur->next != NULL) {
|
||||
+ cur = cur->next;
|
||||
+ continue;
|
||||
+ }
|
||||
+ do {
|
||||
+ cur = cur->parent;
|
||||
+ if (cur == NULL)
|
||||
+ break;
|
||||
+ if (cur == (xmlNodePtr) root) {
|
||||
+ cur = NULL;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (cur->next != NULL) {
|
||||
+ cur = cur->next;
|
||||
+ break;
|
||||
+ }
|
||||
+ } while (cur != NULL);
|
||||
+ }
|
||||
+
|
||||
+fprintf(stderr, "Attributed %d IDs for element, cleaned up %d\n",
|
||||
+ ctxt->nextid, count);
|
||||
+
|
||||
+ return(count);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* xsltGenerateIdFunction:
|
||||
* @ctxt: the XPath Parser context
|
||||
* @nargs: the number of arguments
|
||||
@@ -701,7 +758,39 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
|
||||
if (obj)
|
||||
xmlXPathFreeObject(obj);
|
||||
|
||||
- val = (long)((char *)cur - (char *)&base_address);
|
||||
+ /*
|
||||
+ * Try to provide stable ID for generated document:
|
||||
+ * - usually ID are computed to be placed on elements via attributes
|
||||
+ * so using the element as the node for the ID
|
||||
+ * - the cur->content should be a correct placeholder for this, we use
|
||||
+ * it to hold element node numbers in xmlXPathOrderDocElems to
|
||||
+ * speed up XPath too
|
||||
+ * - xsltCleanupIds() clean them up before handing the XSLT output
|
||||
+ * to the API client.
|
||||
+ * - other nodes types use the node address method but that should
|
||||
+ * not end up in resulting document ID
|
||||
+ * - we can enable this by default without risk of performance issues
|
||||
+ * only the one pass xsltCleanupIds() is added
|
||||
+ */
|
||||
+ if (cur->type == XML_ELEMENT_NODE) {
|
||||
+ if (cur->content == NULL) {
|
||||
+ xsltTransformContextPtr tctxt;
|
||||
+
|
||||
+ tctxt = xsltXPathGetTransformContext(ctxt);
|
||||
+ if (tctxt == NULL) {
|
||||
+ val = (long)((char *)cur - (char *)&base_address);
|
||||
+ } else {
|
||||
+ tctxt->nextid++;
|
||||
+ val = tctxt->nextid;
|
||||
+ cur->content = (void *) (val);
|
||||
+ }
|
||||
+ } else {
|
||||
+ val = (long) cur->content;
|
||||
+ }
|
||||
+ } else {
|
||||
+ val = (long)((char *)cur - (char *)&base_address);
|
||||
+ }
|
||||
+
|
||||
if (val >= 0) {
|
||||
sprintf((char *)str, "idp%ld", val);
|
||||
} else {
|
||||
diff --git a/libxslt/functions.h b/libxslt/functions.h
|
||||
index e0e0bf9..4a1e163 100644
|
||||
--- a/libxslt/functions.h
|
||||
+++ b/libxslt/functions.h
|
||||
@@ -64,6 +64,13 @@ XSLTPUBFUN void XSLTCALL
|
||||
int nargs);
|
||||
|
||||
/*
|
||||
+ * Cleanup for ID generation
|
||||
+ */
|
||||
+XSLTPUBFUN int XSLTCALL
|
||||
+ xsltCleanupIds (xsltTransformContextPtr ctxt,
|
||||
+ xmlNodePtr root);
|
||||
+
|
||||
+/*
|
||||
* And the registration
|
||||
*/
|
||||
|
||||
diff --git a/libxslt/transform.c b/libxslt/transform.c
|
||||
index 24f9eb2..2bdf6bf 100644
|
||||
--- a/libxslt/transform.c
|
||||
+++ b/libxslt/transform.c
|
||||
@@ -700,6 +700,7 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) {
|
||||
cur->traceCode = (unsigned long*) &xsltDefaultTrace;
|
||||
cur->xinclude = xsltGetXIncludeDefault();
|
||||
cur->keyInitLevel = 0;
|
||||
+ cur->nextid = 0;
|
||||
|
||||
return(cur);
|
||||
|
||||
@@ -6092,6 +6093,13 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
|
||||
if (root != NULL) {
|
||||
const xmlChar *doctype = NULL;
|
||||
|
||||
+ /*
|
||||
+ * cleanup ids which may have been saved in Elements content ptrs
|
||||
+ */
|
||||
+ if (ctxt->nextid != 0) {
|
||||
+ xsltCleanupIds(ctxt, root);
|
||||
+ }
|
||||
+
|
||||
if ((root->ns != NULL) && (root->ns->prefix != NULL))
|
||||
doctype = xmlDictQLookup(ctxt->dict, root->ns->prefix, root->name);
|
||||
if (doctype == NULL)
|
||||
diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h
|
||||
index 95e8fe6..8eedae4 100644
|
||||
--- a/libxslt/xsltInternals.h
|
||||
+++ b/libxslt/xsltInternals.h
|
||||
@@ -1786,6 +1786,8 @@ struct _xsltTransformContext {
|
||||
int funcLevel; /* Needed to catch recursive functions issues */
|
||||
int maxTemplateDepth;
|
||||
int maxTemplateVars;
|
||||
+
|
||||
+ unsigned long nextid;/* for generating stable ids */
|
||||
};
|
||||
|
||||
/**
|
|
@ -0,0 +1,66 @@
|
|||
Use deterministic SOURCE_DATE_EPOCH for embedded timestamps in generated documentation.
|
||||
|
||||
Written by Eduard Sanou.
|
||||
|
||||
https://bugzilla.gnome.org/show_bug.cgi?id=758148
|
||||
|
||||
--- libxslt-1.1.28.orig/libexslt/date.c
|
||||
+++ libxslt-1.1.28/libexslt/date.c
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "exslt.h"
|
||||
|
||||
#include <string.h>
|
||||
+#include <errno.h>
|
||||
|
||||
#ifdef HAVE_MATH_H
|
||||
#include <math.h>
|
||||
@@ -747,21 +748,46 @@ static exsltDateValPtr
|
||||
exsltDateCurrent (void)
|
||||
{
|
||||
struct tm localTm, gmTm;
|
||||
+ struct tm *tb = NULL;
|
||||
time_t secs;
|
||||
int local_s, gm_s;
|
||||
exsltDateValPtr ret;
|
||||
+ char *source_date_epoch;
|
||||
|
||||
ret = exsltDateCreateDate(XS_DATETIME);
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
|
||||
- /* get current time */
|
||||
secs = time(NULL);
|
||||
+ /*
|
||||
+ * Allow the date and time to be set externally by an exported
|
||||
+ * environment variable to enable reproducible builds.
|
||||
+ */
|
||||
+ source_date_epoch = getenv("SOURCE_DATE_EPOCH");
|
||||
+ if (source_date_epoch) {
|
||||
+ errno = 0;
|
||||
+ secs = (time_t) strtol (source_date_epoch, NULL, 10);
|
||||
+ if (errno == 0) {
|
||||
+ tb = gmtime(&secs);
|
||||
+ if (tb == NULL) {
|
||||
+ /* SOURCE_DATE_EPOCH is not a valid date */
|
||||
+ return NULL;
|
||||
+ } else {
|
||||
+ localTm = *tb;
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* SOURCE_DATE_EPOCH is not a valid number */
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* get current time */
|
||||
#if HAVE_LOCALTIME_R
|
||||
- localtime_r(&secs, &localTm);
|
||||
+ localtime_r(&secs, &localTm);
|
||||
#else
|
||||
- localTm = *localtime(&secs);
|
||||
+ localTm = *localtime(&secs);
|
||||
#endif
|
||||
+ }
|
||||
+
|
||||
|
||||
/* get real year, not years since 1900 */
|
||||
ret->value.date.year = localTm.tm_year + 1900;
|
|
@ -7,6 +7,7 @@
|
|||
;;; Copyright © 2015, 2016 Mark H Weaver <mhw@netris.org>
|
||||
;;; Copyright © 2015 Efraim Flashner <efraim@flashner.co.il>
|
||||
;;; Copyright © 2015 Raimon Grau <raimonster@gmail.com>
|
||||
;;; Copyright © 2016 Mathieu Lirzin <mthl@gnu.org>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
;;;
|
||||
|
@ -131,7 +132,9 @@ project (but it is usable outside of the Gnome platform).")
|
|||
(sha256
|
||||
(base32
|
||||
"13029baw9kkyjgr7q3jccw2mz38amq7mmpr5p3bh775qawd1bisz"))
|
||||
(patches (search-patches "libxslt-CVE-2015-7995.patch"))))
|
||||
(patches (search-patches "libxslt-generated-ids.patch"
|
||||
"libxslt-remove-date-timestamps.patch"
|
||||
"libxslt-CVE-2015-7995.patch"))))
|
||||
(build-system gnu-build-system)
|
||||
(home-page "http://xmlsoft.org/XSLT/index.html")
|
||||
(synopsis "C library for applying XSLT stylesheets to XML documents")
|
||||
|
|
Loading…
Reference in New Issue