Skip to content
This repository was archived by the owner on Jan 26, 2026. It is now read-only.

Commit 7ea7183

Browse files
committed
Merge commit '0b6d8130737125ba45981d54be7f15fe398ad2e0'
2 parents c8ae03e + 0b6d813 commit 7ea7183

5 files changed

Lines changed: 43 additions & 22 deletions

File tree

.gitlab-ci.yml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@
1212
gcc:
1313
extends: .test
1414
variables:
15-
CONFIG: "--without-tls"
15+
CFLAGS: "-O2"
16+
17+
gcc:c89:
18+
extends: .test
19+
variables:
20+
CONFIG: "--without-python"
1621
CFLAGS: "-O2 -std=c89 -D_XOPEN_SOURCE=600"
1722

1823
gcc:minimum:
@@ -36,12 +41,6 @@ gcc:legacy:
3641
BASE_CONFIG: "--with-legacy"
3742
CFLAGS: "-O2"
3843

39-
gcc:python3:
40-
extends: .test
41-
variables:
42-
CFLAGS: "-O2"
43-
PYTHON: "/usr/bin/python3"
44-
4544
gcc:static:
4645
extends: .test
4746
variables:

NEWS

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
NEWS file for libxml2
22

3+
v2.12.7: May 13 2024
4+
5+
### Security
6+
7+
- [CVE-2024-34459] Fix buffer overread with `xmllint --htmlout`
8+
9+
### Regressions
10+
11+
- xmllint: Fix --pedantic option
12+
- save: Handle invalid parent pointers in xhtmlNodeDumpOutput
13+
14+
315
v2.12.6: Mar 15 2024
416

517
### Regressions

configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ AC_PREREQ([2.63])
33

44
m4_define([MAJOR_VERSION], 2)
55
m4_define([MINOR_VERSION], 12)
6-
m4_define([MICRO_VERSION], 6)
6+
m4_define([MICRO_VERSION], 7)
77

88
AC_INIT([libxml2],[MAJOR_VERSION.MINOR_VERSION.MICRO_VERSION])
99
AC_CONFIG_SRCDIR([entities.c])

xmllint.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ xmlHTMLPrintFileContext(xmlParserInputPtr input) {
560560
len = strlen(buffer);
561561
snprintf(&buffer[len], sizeof(buffer) - len, "\n");
562562
cur = input->cur;
563-
while ((*cur == '\n') || (*cur == '\r'))
563+
while ((cur > base) && ((*cur == '\n') || (*cur == '\r')))
564564
cur--;
565565
n = 0;
566566
while ((cur != base) && (n++ < 80)) {
@@ -3350,7 +3350,7 @@ main(int argc, char **argv) {
33503350
else if ((!strcmp(argv[i], "-pedantic")) ||
33513351
(!strcmp(argv[i], "--pedantic"))) {
33523352
options |= XML_PARSE_PEDANTIC;
3353-
options &= XML_PARSE_NOWARNING;
3353+
options &= ~XML_PARSE_NOWARNING;
33543354
}
33553355
#ifdef LIBXML_DEBUG_ENABLED
33563356
else if ((!strcmp(argv[i], "-debugent")) ||

xmlsave.c

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,13 +1391,14 @@ xhtmlAttrListDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) {
13911391
static void
13921392
xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
13931393
int format = ctxt->format, addmeta;
1394-
xmlNodePtr tmp, root, unformattedNode = NULL;
1394+
xmlNodePtr tmp, root, unformattedNode = NULL, parent;
13951395
xmlChar *start, *end;
13961396
xmlOutputBufferPtr buf = ctxt->buf;
13971397

13981398
if (cur == NULL) return;
13991399

14001400
root = cur;
1401+
parent = cur->parent;
14011402
while (1) {
14021403
switch (cur->type) {
14031404
case XML_DOCUMENT_NODE:
@@ -1414,7 +1415,9 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
14141415
break;
14151416

14161417
case XML_DOCUMENT_FRAG_NODE:
1417-
if (cur->children) {
1418+
/* Always validate cur->parent when descending. */
1419+
if ((cur->parent == parent) && (cur->children != NULL)) {
1420+
parent = cur;
14181421
cur = cur->children;
14191422
continue;
14201423
}
@@ -1441,6 +1444,16 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
14411444
ctxt->indent_nr : ctxt->level),
14421445
ctxt->indent);
14431446

1447+
/*
1448+
* Some users like lxml are known to pass nodes with a corrupted
1449+
* tree structure. Fall back to a recursive call to handle this
1450+
* case.
1451+
*/
1452+
if ((cur->parent != parent) && (cur->children != NULL)) {
1453+
xhtmlNodeDumpOutput(ctxt, cur);
1454+
break;
1455+
}
1456+
14441457
xmlOutputBufferWrite(buf, 1, "<");
14451458
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
14461459
xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
@@ -1461,10 +1474,10 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
14611474
if (cur->properties != NULL)
14621475
xhtmlAttrListDumpOutput(ctxt, cur->properties);
14631476

1464-
if ((cur->parent != NULL) &&
1465-
(cur->parent->parent == (xmlNodePtr) cur->doc) &&
1477+
if ((parent != NULL) &&
1478+
(parent->parent == (xmlNodePtr) cur->doc) &&
14661479
xmlStrEqual(cur->name, BAD_CAST"head") &&
1467-
xmlStrEqual(cur->parent->name, BAD_CAST"html")) {
1480+
xmlStrEqual(parent->name, BAD_CAST"html")) {
14681481

14691482
tmp = cur->children;
14701483
while (tmp != NULL) {
@@ -1570,6 +1583,7 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
15701583

15711584
if (ctxt->format == 1) xmlOutputBufferWrite(buf, 1, "\n");
15721585
if (ctxt->level >= 0) ctxt->level++;
1586+
parent = cur;
15731587
cur = cur->children;
15741588
continue;
15751589
}
@@ -1664,13 +1678,9 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
16641678
break;
16651679
}
16661680

1667-
/*
1668-
* The parent should never be NULL here but we want to handle
1669-
* corrupted documents gracefully.
1670-
*/
1671-
if (cur->parent == NULL)
1672-
return;
1673-
cur = cur->parent;
1681+
cur = parent;
1682+
/* cur->parent was validated when descending. */
1683+
parent = cur->parent;
16741684

16751685
if (cur->type == XML_ELEMENT_NODE) {
16761686
if (ctxt->level > 0) ctxt->level--;

0 commit comments

Comments
 (0)