@@ -1537,6 +1537,43 @@ public void testValidUppercaseHexEntity() {
15371537 assertEquals ("A" , jsonObject .getString ("a" ));
15381538 }
15391539
1540+ /**
1541+ * Tests that valid XML numeric character references for whitespace
1542+ * control characters (TAB, LF, CR) are correctly unescaped. These
1543+ * codepoints are explicitly allowed by the XML 1.0 spec
1544+ * (https://www.w3.org/TR/REC-xml/#charsets) but were previously rejected
1545+ * as invalid. See issue #1059.
1546+ */
1547+ @ Test
1548+ public void testValidWhitespaceNumericEntityUnescape () {
1549+ // decimal references for the three allowed control characters
1550+ assertEquals ("\t " , XML .unescape ("	" ));
1551+ assertEquals ("\n " , XML .unescape (" " ));
1552+ assertEquals ("\r " , XML .unescape (" " ));
1553+ // hex references for the same codepoints
1554+ assertEquals ("\t " , XML .unescape ("	" ));
1555+ assertEquals ("\n " , XML .unescape ("
" ));
1556+ assertEquals ("\r " , XML .unescape ("
" ));
1557+ }
1558+
1559+ /**
1560+ * Tests that {@code XML.toJSONObject} accepts numeric character references
1561+ * for the XML-allowed control characters (TAB, LF, CR) without throwing.
1562+ * Regression test for #1059, where {@code XML.toJSONObject("<a> </a>")}
1563+ * threw JSONException in versions after 20251224.
1564+ */
1565+ @ Test
1566+ public void testValidWhitespaceNumericEntityToJSONObject () {
1567+ // LF reference should round-trip through toJSONObject without throwing
1568+ JSONObject jsonObject = XML .toJSONObject ("<a> </a>" );
1569+ // the value is the LF character (possibly trimmed by the JSON path,
1570+ // but the call must not throw)
1571+ assertTrue (jsonObject .has ("a" ));
1572+ // TAB and CR references also accepted
1573+ XML .toJSONObject ("<a>	</a>" );
1574+ XML .toJSONObject ("<a> </a>" );
1575+ }
1576+
15401577}
15411578
15421579
0 commit comments