diff --git a/pom-central.xml b/pom-central.xml
index 38684af8..ed568d42 100644
--- a/pom-central.xml
+++ b/pom-central.xml
@@ -165,6 +165,12 @@
5.14.4
test
+
+ org.junit.jupiter
+ junit-jupiter-params
+ 5.14.4
+ test
+
org.junit.platform
junit-platform-launcher
diff --git a/pom-pack.xml b/pom-pack.xml
index a5784506..cb8f1b33 100644
--- a/pom-pack.xml
+++ b/pom-pack.xml
@@ -253,6 +253,12 @@
5.14.4
test
+
+ org.junit.jupiter
+ junit-jupiter-params
+ 5.14.4
+ test
+
org.junit.platform
junit-platform-launcher
diff --git a/pom.xml b/pom.xml
index 426f72d7..56aee75d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -210,6 +210,12 @@
5.14.4
test
+
+ org.junit.jupiter
+ junit-jupiter-params
+ 5.14.4
+ test
+
org.junit.platform
junit-platform-launcher
diff --git a/src/main/java/com/github/underscore/Xml.java b/src/main/java/com/github/underscore/Xml.java
index 793da57c..ab9bbb01 100644
--- a/src/main/java/com/github/underscore/Xml.java
+++ b/src/main/java/com/github/underscore/Xml.java
@@ -1521,15 +1521,22 @@ static Map parseAttributes(final String source) {
StringBuilder key = new StringBuilder();
StringBuilder value = new StringBuilder();
boolean inQuotes = false;
+ char quoteChar = 0;
boolean expectingValue = false;
for (char c : source.toCharArray()) {
- if (c == '"') {
- inQuotes = !inQuotes;
- if (!inQuotes && expectingValue) {
- result.put(key.toString(), value.toString());
- key.setLength(0);
- value.setLength(0);
- expectingValue = false;
+ if ((c == '"' || c == '\'') && (!inQuotes || c == quoteChar)) {
+ if (!inQuotes) {
+ inQuotes = true;
+ quoteChar = c;
+ } else {
+ inQuotes = false;
+ quoteChar = 0;
+ if (expectingValue) {
+ result.put(key.toString(), value.toString());
+ key.setLength(0);
+ value.setLength(0);
+ expectingValue = false;
+ }
}
} else if (c == '=' && !inQuotes) {
expectingValue = true;
diff --git a/src/test/java/com/github/underscore/LodashTest.java b/src/test/java/com/github/underscore/LodashTest.java
index bf1fbe9b..35ddfaab 100644
--- a/src/test/java/com/github/underscore/LodashTest.java
+++ b/src/test/java/com/github/underscore/LodashTest.java
@@ -33,6 +33,8 @@
import static java.util.Collections.singletonList;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
import java.io.IOException;
import java.net.URISyntaxException;
@@ -1152,6 +1154,87 @@ void xmpToJson6() {
+ ""));
}
+ @Test
+ void xmpToJson7() {
+ assertEquals(
+ "{\n"
+ + " \"Comment\": {\n"
+ + " \"-stringValue\": \"a\",\n"
+ + " \"-self-closing\": \"true\"\n"
+ + " },\n"
+ + " \"#omit-xml-declaration\": \"yes\"\n"
+ + "}",
+ U.xmlToJson(""));
+ assertEquals(
+ "{\n"
+ + " \"Comment\": {\n"
+ + " },\n"
+ + " \"#omit-xml-declaration\": \"yes\"\n"
+ + "}",
+ U.xmlToJson(""));
+ assertEquals(
+ "{\n"
+ + " \"Comment\": {\n"
+ + " \"-stringValue\": \"a'\",\n"
+ + " \"-self-closing\": \"true\"\n"
+ + " },\n"
+ + " \"#omit-xml-declaration\": \"yes\"\n"
+ + "}",
+ U.xmlToJson(""));
+ assertThrows(
+ IllegalArgumentException.class, () -> U.xmlToJson(""));
+ assertThrows(
+ IllegalArgumentException.class, () -> U.xmlToJson(" parse(String s) {
+ Map m = new LinkedHashMap<>();
+ if (s != null && !s.isEmpty()) {
+ for (String pair : s.split(",", -1)) {
+ int i = pair.indexOf('=');
+ m.put(pair.substring(0, i), pair.substring(i + 1));
+ }
+ }
+ return m;
+ }
+
@Test
void xmlToJsonMinimum() {
assertEquals(