aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-09-12 10:05:17 +0100
committerMichael Williamson <mike@zwobble.org>2026-09-12 10:05:17 +0100
commit0ee7fbb98f8f119d6086bc08bfbe959643e9dd44 (patch)
tree04de386257347b67ff40bae5b8508ffd303ff48b
parent3f797af7e4a2e69f2f5aa5305f79960f7e7c5d13 (diff)
Handle missing complex field start characters
-rw-r--r--NEWS3
-rw-r--r--src/main/java/org/zwobble/mammoth/internal/docx/StatefulBodyXmlReader.java12
-rw-r--r--src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java32
3 files changed, 47 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index fa7fdb7..250c1e1 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,9 @@
Note that it is still strongly recommended to process untrusted documents in
a separate thread with a timeout to avoid potential similar issues.
+* Handle complex field separator and end characters without corresponding start
+ characters.
+
# 1.12.1
* Detect and ignore numbering levels that use numStyleLink to refer to
diff --git a/src/main/java/org/zwobble/mammoth/internal/docx/StatefulBodyXmlReader.java b/src/main/java/org/zwobble/mammoth/internal/docx/StatefulBodyXmlReader.java
index 2cc7e4b..06326d0 100644
--- a/src/main/java/org/zwobble/mammoth/internal/docx/StatefulBodyXmlReader.java
+++ b/src/main/java/org/zwobble/mammoth/internal/docx/StatefulBodyXmlReader.java
@@ -321,6 +321,12 @@ class StatefulBodyXmlReader {
complexFieldStack.add(ComplexField.begin(element));
currentInstrText.setLength(0);
} else if (type.equals("end")) {
+ if (complexFieldStack.isEmpty()) {
+ return emptyWithWarning(
+ "Ignoring complex field end character without corresponding start character"
+ );
+ }
+
ComplexField complexField = complexFieldStack.remove();
if (complexField instanceof BeginComplexField) {
complexField = parseCurrentInstrText(complexField);
@@ -329,6 +335,12 @@ class StatefulBodyXmlReader {
return success(new Checkbox(((CheckboxComplexField) complexField).checked));
}
} else if (type.equals("separate")) {
+ if (complexFieldStack.isEmpty()) {
+ return emptyWithWarning(
+ "Ignoring complex field separator character without corresponding start character"
+ );
+ }
+
ComplexField complexFieldSeparate = complexFieldStack.remove();
ComplexField complexField = parseCurrentInstrText(complexFieldSeparate);
complexFieldStack.add(complexField);
diff --git a/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java b/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java
index 135ad54..d3fc3b1 100644
--- a/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java
+++ b/src/test/java/org/zwobble/mammoth/tests/docx/BodyXmlTests.java
@@ -626,6 +626,38 @@ public class BodyXmlTests {
isEmptyRun()
)));
}
+
+ @Test
+ public void separatorCharacterWithoutCorrespondingStartCharacterIsIgnored() {
+ XmlElement element = paragraphXml(list(
+ SEPARATE_COMPLEX_FIELD
+ ));
+
+ InternalResult<DocumentElement> result = read(bodyReader(), element);
+
+ assertThat(result, isInternalResult(
+ isParagraph(hasChildren(
+ isEmptyRun()
+ )),
+ list("Ignoring complex field separator character without corresponding start character")
+ ));
+ }
+
+ @Test
+ public void endCharacterWithoutCorrespondingStartCharacterIsIgnored() {
+ XmlElement element = paragraphXml(list(
+ END_COMPLEX_FIELD
+ ));
+
+ InternalResult<DocumentElement> result = read(bodyReader(), element);
+
+ assertThat(result, isInternalResult(
+ isParagraph(hasChildren(
+ isEmptyRun()
+ )),
+ list("Ignoring complex field end character without corresponding start character")
+ ));
+ }
}
@Nested