From 62d4d33f71b17829f63d408ebe0f4c5eb560307e Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 12 Sep 2026 09:52:19 +0100 Subject: Handle missing complex field start characters --- NEWS | 3 +++ lib/docx/body-reader.js | 12 ++++++++++++ test/docx/body-reader.tests.js | 26 ++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/NEWS b/NEWS index 77f348b..28bdbaa 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,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.2 * Avoid prototype pollution when reading the styles defined in a document. This diff --git a/lib/docx/body-reader.js b/lib/docx/body-reader.js index 2ec9d0d..2c2a741 100644 --- a/lib/docx/body-reader.js +++ b/lib/docx/body-reader.js @@ -169,6 +169,12 @@ function BodyReader(options) { complexFieldStack.push({type: "begin", fldChar: element}); currentInstrText = []; } else if (type === "end") { + if (complexFieldStack.length === 0) { + return emptyResultWithMessages([warning( + "ignoring complex field end character without corresponding start character" + )]); + } + var complexFieldEnd = complexFieldStack.pop(); if (complexFieldEnd.type === "begin") { complexFieldEnd = parseCurrentInstrText(complexFieldEnd); @@ -179,6 +185,12 @@ function BodyReader(options) { })); } } else if (type === "separate") { + if (complexFieldStack.length === 0) { + return emptyResultWithMessages([warning( + "ignoring complex field separator character without corresponding start character" + )]); + } + var complexFieldSeparate = complexFieldStack.pop(); var complexField = parseCurrentInstrText(complexFieldSeparate); complexFieldStack.push(complexField); diff --git a/test/docx/body-reader.tests.js b/test/docx/body-reader.tests.js index 9559809..d8b521c 100644 --- a/test/docx/body-reader.tests.js +++ b/test/docx/body-reader.tests.js @@ -581,6 +581,32 @@ test("complex fields", (function() { }), isEmptyRun )); + }, + + "separator character without corresponding start character is ignored": function() { + var paragraphXml = new XmlElement("w:p", {}, [ + separateXml + ]); + + var result = readXmlElement(paragraphXml); + + assertThat(result.value.children, contains( + isEmptyRun + )); + assert.deepEqual(result.messages, [warning("ignoring complex field separator character without corresponding start character")]); + }, + + "end character without corresponding start character is ignored": function() { + var paragraphXml = new XmlElement("w:p", {}, [ + endXml + ]); + + var result = readXmlElement(paragraphXml); + + assertThat(result.value.children, contains( + isEmptyRun + )); + assert.deepEqual(result.messages, [warning("ignoring complex field end character without corresponding start character")]); } }; })()); -- cgit v1.2.3