• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1From 6d71ed443d0b4ab1a3e9e43c6c2f1c2c3dc127cd Mon Sep 17 00:00:00 2001
2From: l30034438 <l30034438@notesmail.huawei.com/>
3Date: Thu, 19 Jun 2025 11:11:08 +0800
4Subject: [PATCH] Fix relaxng is parsed to an infinite attrs->next loop
5
6Change-Id: I2b7b37c628b20bd234b84d8938d241dd722af087
7---
8 relaxng.c                      | 13 ++++++++++---
9 test/relaxng/useless_group.rng | 21 +++++++++++++++++++++
10 test/relaxng/useless_group.xml |  3 +++
11 3 files changed, 34 insertions(+), 3 deletions(-)
12 create mode 100644 test/relaxng/useless_group.rng
13 create mode 100644 test/relaxng/useless_group.xml
14
15diff --git a/relaxng.c b/relaxng.c
16index c223dbb9..5ba76699 100644
17--- a/relaxng.c
18+++ b/relaxng.c
19@@ -6018,6 +6018,7 @@ xmlRelaxNGSimplify(xmlRelaxNGParserCtxtPtr ctxt,
20                     if (attronly == 1) {
21                         /*
22                          * migrate tmp to attrs
23+                         * if this runs twice an infinite attrs->next loop can be created
24                          */
25                         pre->next = tmp->next;
26                         tmp->next = cur->attrs;
27@@ -6038,9 +6039,15 @@ xmlRelaxNGSimplify(xmlRelaxNGParserCtxtPtr ctxt,
28                     if ((parent == NULL) && (prev == NULL)) {
29                         cur->type = XML_RELAXNG_NOOP;
30                     } else if (prev == NULL) {
31-                        parent->content = cur->content;
32-                        cur->content->next = cur->next;
33-                        cur = cur->content;
34+                        /*
35+                         * this simplification may already have happened
36+                         * if this is done twice this leads to an infinite loop of attrs->next
37+                         */
38+                        if (parent->content != cur->content) {
39+                            parent->content = cur->content;
40+                            cur->content->next = cur->next;
41+                            cur = cur->content;
42+                        }
43                     } else {
44                         cur->content->next = cur->next;
45                         prev->next = cur->content;
46diff --git a/test/relaxng/useless_group.rng b/test/relaxng/useless_group.rng
47new file mode 100644
48index 00000000..f295a100
49--- /dev/null
50+++ b/test/relaxng/useless_group.rng
51@@ -0,0 +1,21 @@
52+<grammar datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
53+  ns="http://relaxng.org/ns/structure/1.0"
54+  xmlns="http://relaxng.org/ns/structure/1.0">
55+
56+  <start>
57+    <ref name="listOfLists"/>
58+  </start>
59+
60+  <define name="listOfLists">
61+    <element name="listOfLists">
62+    <group>
63+      <zeroOrMore>
64+         <ref name="listOfLists"/>
65+      </zeroOrMore>
66+    </group>
67+    <optional>
68+      <attribute name="fail"/>
69+    </optional>
70+    </element>
71+  </define>
72+</grammar>
73diff --git a/test/relaxng/useless_group.xml b/test/relaxng/useless_group.xml
74new file mode 100644
75index 00000000..7806bd48
76--- /dev/null
77+++ b/test/relaxng/useless_group.xml
78@@ -0,0 +1,3 @@
79+<listOfLists xmlns="http://relaxng.org/ns/structure/1.0" fail="">
80+<listOfLists/>
81+</listOfLists>
82--
832.34.1
84
85