1
0
mirror of https://gitlab.gnome.org/GNOME/libxslt synced 2025-07-31 02:43:06 +03:00

variables: Fix non-deterministic generated IDs

Evaluate global variables in deterministic order. Otherwise, generated
IDs could be non-deterministic if generate-id() is called.

Fixes #123.
This commit is contained in:
Nick Wellnhofer
2024-09-19 21:49:46 +02:00
parent cb1e47d98b
commit c45ed81aeb

View File

@ -1259,13 +1259,6 @@ error:
return(result); return(result);
} }
static void
xsltEvalGlobalVariableWrapper(void *payload, void *data,
const xmlChar *name ATTRIBUTE_UNUSED) {
xsltEvalGlobalVariable((xsltStackElemPtr) payload,
(xsltTransformContextPtr) data);
}
/** /**
* xsltEvalGlobalVariables: * xsltEvalGlobalVariables:
* @ctxt: the XSLT transformation context * @ctxt: the XSLT transformation context
@ -1278,6 +1271,7 @@ xsltEvalGlobalVariableWrapper(void *payload, void *data,
int int
xsltEvalGlobalVariables(xsltTransformContextPtr ctxt) { xsltEvalGlobalVariables(xsltTransformContextPtr ctxt) {
xsltStackElemPtr elem; xsltStackElemPtr elem;
xsltStackElemPtr head = NULL;
xsltStylesheetPtr style; xsltStylesheetPtr style;
if ((ctxt == NULL) || (ctxt->document == NULL)) if ((ctxt == NULL) || (ctxt->document == NULL))
@ -1321,6 +1315,8 @@ xsltEvalGlobalVariables(xsltTransformContextPtr ctxt) {
xsltFreeStackElem(def); xsltFreeStackElem(def);
return(-1); return(-1);
} }
def->next = head;
head = def;
} else if ((elem->comp != NULL) && } else if ((elem->comp != NULL) &&
(elem->comp->type == XSLT_FUNC_VARIABLE)) { (elem->comp->type == XSLT_FUNC_VARIABLE)) {
/* /*
@ -1343,9 +1339,19 @@ xsltEvalGlobalVariables(xsltTransformContextPtr ctxt) {
} }
/* /*
* This part does the actual evaluation * This part does the actual evaluation. Note that scanning the hash
* table would result in a non-deterministic order, leading to
* non-deterministic generated IDs.
*/ */
xmlHashScan(ctxt->globalVars, xsltEvalGlobalVariableWrapper, ctxt); elem = head;
while (elem != NULL) {
xsltStackElemPtr next;
xsltEvalGlobalVariable(elem, ctxt);
next = elem->next;
elem->next = NULL;
elem = next;
}
return(0); return(0);
} }