Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/main/java/org/json/XML.java
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,14 @@ static boolean mustEscape(int cp) {
&& cp != 0xA
&& cp != 0xD
) || !(
// valid the range of acceptable characters that aren't control
(cp >= 0x20 && cp <= 0xD7FF)
// Valid character range per W3C XML 1.0 spec:
// #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
// Previously omitted #x9/#xA/#xD, causing unescape("&#10;") etc.
// to reject valid LF/TAB/CR as illegal (see #1059)
cp == 0x9
|| cp == 0xA
|| cp == 0xD
|| (cp >= 0x20 && cp <= 0xD7FF)
|| (cp >= 0xE000 && cp <= 0xFFFD)
|| (cp >= 0x10000 && cp <= 0x10FFFF)
)
Expand Down
37 changes: 37 additions & 0 deletions src/test/java/org/json/junit/XMLTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1537,6 +1537,43 @@ public void testValidUppercaseHexEntity() {
assertEquals("A", jsonObject.getString("a"));
}

/**
* Tests that valid XML numeric character references for whitespace
* control characters (TAB, LF, CR) are correctly unescaped. These
* codepoints are explicitly allowed by the XML 1.0 spec
* (https://www.w3.org/TR/REC-xml/#charsets) but were previously rejected
* as invalid. See issue #1059.
*/
@Test
public void testValidWhitespaceNumericEntityUnescape() {
// decimal references for the three allowed control characters
assertEquals("\t", XML.unescape("&#9;"));
assertEquals("\n", XML.unescape("&#10;"));
assertEquals("\r", XML.unescape("&#13;"));
// hex references for the same codepoints
assertEquals("\t", XML.unescape("&#x9;"));
assertEquals("\n", XML.unescape("&#xA;"));
assertEquals("\r", XML.unescape("&#xD;"));
}

/**
* Tests that {@code XML.toJSONObject} accepts numeric character references
* for the XML-allowed control characters (TAB, LF, CR) without throwing.
* Regression test for #1059, where {@code XML.toJSONObject("<a>&#10;</a>")}
* threw JSONException in versions after 20251224.
*/
@Test
public void testValidWhitespaceNumericEntityToJSONObject() {
// LF reference should round-trip through toJSONObject without throwing
JSONObject jsonObject = XML.toJSONObject("<a>&#10;</a>");
// the value is the LF character (possibly trimmed by the JSON path,
// but the call must not throw)
assertTrue(jsonObject.has("a"));
// TAB and CR references also accepted
XML.toJSONObject("<a>&#9;</a>");
XML.toJSONObject("<a>&#13;</a>");
}

}


Expand Down
Loading