Skip to content
Closed
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
30 changes: 26 additions & 4 deletions src/main/java/com/github/underscore/Xml.java
Original file line number Diff line number Diff line change
Expand Up @@ -1045,9 +1045,9 @@ private static void escape(String s, StringBuilder sb) {
|| ch >= '\u007F' && ch <= '\u009F'
|| ch >= '\u2000' && ch <= '\u20FF') {
String ss = Integer.toHexString(ch);
sb.append("&#x");
sb.append("\\x");
sb.append("0".repeat(4 - ss.length()));
sb.append(ss.toUpperCase()).append(";");
sb.append(ss.toUpperCase());
} else {
sb.append(ch);
}
Expand Down Expand Up @@ -1101,7 +1101,28 @@ private static int translate(
}
}
}
return 0;
return translateBinary(input, index, builder);
}

static int translateBinary(
final CharSequence input, final int index, final StringBuilder builder) {
final int length = input.length();
if (index + 5 >= length) {
return 0;
}
if (input.charAt(index) != '\\' || input.charAt(index + 1) != 'x') {
return 0;
}
int value = 0;
for (int i = index + 2; i < index + 6; i++) {
final int digit = Character.digit(input.charAt(i), 16);
if (digit < 0) {
return 0;
}
value = (value << 4) | digit;
}
builder.append((char) value);
return 6;
}

public static String getMapKey(Object map) {
Expand Down Expand Up @@ -1283,7 +1304,8 @@ private static Object getValue(final String name, final Object value, final From
} else {
localValue = value;
}
return localValue instanceof String && name.startsWith("-")
return localValue instanceof String
&& (name.startsWith("-") || ((String) localValue).contains("\\x"))
? XmlValue.unescape((String) localValue)
: localValue;
}
Expand Down
8 changes: 8 additions & 0 deletions src/test/java/com/github/underscore/LodashTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1152,6 +1152,14 @@ void xmpToJson6() {
+ "</root>"));
}

@Test
void xmlToJson7() {
assertEquals(
"{\n \"debug\": \"\\u0001\"\n}",
U.xmlToJson(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<debug>\\x0001</debug>"));
}

@Test
void xmlToJsonMinimum() {
assertEquals(
Expand Down
112 changes: 106 additions & 6 deletions src/test/java/com/github/underscore/StringTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1197,14 +1197,14 @@ void escapeXml() {
assertEquals("&#xD;", Xml.XmlValue.escape("\r"));
assertEquals("\t", Xml.XmlValue.escape("\t"));
assertEquals("/", Xml.XmlValue.escape("/"));
assertEquals("&#x0000;", Xml.XmlValue.escape("\u0000"));
assertEquals("&#x001F;", Xml.XmlValue.escape("\u001F"));
assertEquals("\\x0000", Xml.XmlValue.escape("\u0000"));
assertEquals("\\x001F", Xml.XmlValue.escape("\u001F"));
assertEquals("\u0020", Xml.XmlValue.escape("\u0020"));
assertEquals("&#x007F;", Xml.XmlValue.escape("\u007F"));
assertEquals("&#x009F;", Xml.XmlValue.escape("\u009F"));
assertEquals("\\x007F", Xml.XmlValue.escape("\u007F"));
assertEquals("\\x009F", Xml.XmlValue.escape("\u009F"));
assertEquals("\u00A0", Xml.XmlValue.escape("\u00A0"));
assertEquals("&#x2000;", Xml.XmlValue.escape("\u2000"));
assertEquals("&#x20FF;", Xml.XmlValue.escape("\u20FF"));
assertEquals("\\x2000", Xml.XmlValue.escape("\u2000"));
assertEquals("\\x20FF", Xml.XmlValue.escape("\u20FF"));
assertEquals("\u2100", Xml.XmlValue.escape("\u2100"));
assertEquals("\uFFFF", Xml.XmlValue.escape("\uFFFF"));
}
Expand All @@ -1219,6 +1219,96 @@ void unescapeXml() {
assertEquals("<", Xml.XmlValue.unescape("&lt;"));
assertEquals(">", Xml.XmlValue.unescape("&gt;"));
assertEquals("&quot", Xml.XmlValue.unescape("&quot"));
assertEquals("\u20FF", Xml.XmlValue.unescape("\\x20FF"));
assertEquals("\u0000", Xml.XmlValue.unescape("\\x0000"));
assertEquals("\u001F", Xml.XmlValue.unescape("\\x001F"));
}

@Test
void translateBinary() {
StringBuilder builder = new StringBuilder();
int result = Xml.XmlValue.translateBinary("\\x0041", 0, builder);
assertEquals(6, result);
assertEquals("A", builder.toString());
}

@Test
void translateBinary2() {
StringBuilder builder = new StringBuilder();
int result = Xml.XmlValue.translateBinary("a\\x0041", 1, builder);
assertEquals(6, result);
assertEquals("A", builder.toString());
}

@Test
void translateBinary3() {
StringBuilder builder = new StringBuilder();
int result = Xml.XmlValue.translateBinary("abc", 0, builder);
assertEquals(0, result);
assertEquals("", builder.toString());
}

@Test
void translateBinary4() {
StringBuilder builder = new StringBuilder();
int result = Xml.XmlValue.translateBinary("\\u0041", 0, builder);
assertEquals(0, result);
assertEquals("", builder.toString());
}

@Test
void translateBinary5() {
StringBuilder builder = new StringBuilder();
int result = Xml.XmlValue.translateBinary("\\x00G1", 0, builder);
assertEquals(0, result);
assertEquals("", builder.toString());
}

@Test
void translateBinary6() {
StringBuilder builder = new StringBuilder();
int result = Xml.XmlValue.translateBinary("\\x041", 0, builder);
assertEquals(0, result);
assertEquals("", builder.toString());
}

@Test
void translateBinary7() {
StringBuilder builder = new StringBuilder();
int result = Xml.XmlValue.translateBinary("\\x0000", 0, builder);
assertEquals(6, result);
assertEquals(1, builder.length());
assertEquals(0, builder.charAt(0));
}

@SuppressWarnings("java:S5976")
@Test
void translateBinary8() {
StringBuilder builder = new StringBuilder();
int result = Xml.XmlValue.translateBinary("\\x1234", 0, builder);
assertEquals(6, result);
assertEquals(1, builder.length());
assertEquals('\u1234', builder.charAt(0));
}

@SuppressWarnings("java:S5976")
@Test
void translateBinary9() {
StringBuilder builder = new StringBuilder();
int result = Xml.XmlValue.translateBinary("\\xFFFF", 0, builder);
assertEquals(6, result);
assertEquals(1, builder.length());
assertEquals('\uFFFF', builder.charAt(0));
}

@SuppressWarnings("java:S5976")
@Test
void translateBinary10() {
StringBuilder builder = new StringBuilder();
int result = Xml.XmlValue.translateBinary("\\x00af", 0, builder);
assertEquals(6, result);
assertEquals(1, builder.length());
assertEquals('\u00AF', builder.charAt(0));
}

@Test
Expand Down Expand Up @@ -1510,6 +1600,16 @@ void testXmlDecodeCyrillic() {
U.toXml((List<Object>) U.fromJson("[\"Текст на русском\"]")));
}

@SuppressWarnings("unchecked")
@Test
void testXmlDecodeBinary() {
assertEquals(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root>\n <element array=\"true\">"
+ "\\x0001Текст на русском</element>\n"
+ "</root>",
U.toXml((List<Object>) U.fromJson("[\"\\u0001Текст на русском\"]")));
}

@Test
void toXmlFromList() {
final List<String> testList = new ArrayList<>();
Expand Down
Loading