mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
GP-3210 fix manual xml serialization of high unicode characters
This commit is contained in:
@@ -17,11 +17,12 @@ package ghidra.framework.options;
|
|||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
|
|
||||||
@@ -342,7 +343,7 @@ public class SaveStateTest extends AbstractGenericTest {
|
|||||||
ss.putString(greaterThanLessThanKey, stringWithGreaterThanAndLessThan);
|
ss.putString(greaterThanLessThanKey, stringWithGreaterThanAndLessThan);
|
||||||
|
|
||||||
String stringWithLargeHexDigit =
|
String stringWithLargeHexDigit =
|
||||||
"The following is a large hex digit: \u0128, \u0132, \307 and \253 " +
|
"The following is a large hex digit: \u0128, \u0132, \307 and \253 \uD835\uDCC8 " +
|
||||||
"with some trailing text ÿ";
|
"with some trailing text ÿ";
|
||||||
String hexDigitKey = "HEX_DIGIT_KEY";
|
String hexDigitKey = "HEX_DIGIT_KEY";
|
||||||
ss.putString(hexDigitKey, stringWithLargeHexDigit);
|
ss.putString(hexDigitKey, stringWithLargeHexDigit);
|
||||||
|
|||||||
@@ -59,7 +59,8 @@ public class PropertyFileTest extends AbstractGenericTest {
|
|||||||
pf.putInt("TestInt", 1234);
|
pf.putInt("TestInt", 1234);
|
||||||
pf.putLong("TestLong", 0x12345678);
|
pf.putLong("TestLong", 0x12345678);
|
||||||
|
|
||||||
StringBuffer sb = new StringBuffer("Line1\nLine2\n\"Ugly\" & Special <Values>; ");
|
StringBuffer sb = new StringBuffer(
|
||||||
|
"Line1\nLine2\n\"Ugly\" & Special <Values>; \u0128, \u0132, \307 and \253");
|
||||||
for (int i = 1; i < 35; i++) {
|
for (int i = 1; i < 35; i++) {
|
||||||
sb.append((char) i);
|
sb.append((char) i);
|
||||||
}
|
}
|
||||||
@@ -70,6 +71,10 @@ public class PropertyFileTest extends AbstractGenericTest {
|
|||||||
|
|
||||||
pf.putString("TestString", URLEncoder.encode(str, "UTF-8"));
|
pf.putString("TestString", URLEncoder.encode(str, "UTF-8"));
|
||||||
|
|
||||||
|
// also test plain unicode values, as well as a 32bit unicode value
|
||||||
|
String string2 = "non-control char values: < & ; > \u00bb \u0128, \u0132, \uD835\uDCC8";
|
||||||
|
pf.putString("TestString2", string2);
|
||||||
|
|
||||||
pf.writeState();
|
pf.writeState();
|
||||||
|
|
||||||
PropertyFile pf2 = new PropertyFile(parent, storageName, "/", NAME);
|
PropertyFile pf2 = new PropertyFile(parent, storageName, "/", NAME);
|
||||||
@@ -81,6 +86,7 @@ public class PropertyFileTest extends AbstractGenericTest {
|
|||||||
assertEquals(1234, pf2.getInt("TestInt", -1));
|
assertEquals(1234, pf2.getInt("TestInt", -1));
|
||||||
assertEquals(0x12345678, pf2.getLong("TestLong", -1));
|
assertEquals(0x12345678, pf2.getLong("TestLong", -1));
|
||||||
assertEquals(str, URLDecoder.decode(pf2.getString("TestString", null), "UTF-8"));
|
assertEquals(str, URLDecoder.decode(pf2.getString("TestString", null), "UTF-8"));
|
||||||
|
assertEquals(string2, pf2.getString("TestString2", null));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,12 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
package ghidra.util.xml;
|
package ghidra.util.xml;
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import javax.xml.XMLConstants;
|
import javax.xml.XMLConstants;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.parsers.SAXParserFactory;
|
import javax.xml.parsers.SAXParserFactory;
|
||||||
@@ -87,19 +88,21 @@ public class XmlUtilities {
|
|||||||
* @return the encoded XML string
|
* @return the encoded XML string
|
||||||
*/
|
*/
|
||||||
public static String escapeElementEntities(String xml) {
|
public static String escapeElementEntities(String xml) {
|
||||||
StringBuffer buffer = new StringBuffer();
|
StringBuilder buffer = new StringBuilder();
|
||||||
for (int i = 0; i < xml.length(); i++) {
|
for (int offset = 0; offset < xml.length();) {
|
||||||
char next = xml.charAt(i);
|
int codePoint = xml.codePointAt(offset);
|
||||||
if ((next < ' ') && (next != 0x09) && (next != 0x0A) && (next != 0x0D)) {
|
offset += Character.charCount(codePoint);
|
||||||
|
|
||||||
|
if ((codePoint < ' ') && (codePoint != 0x09) && (codePoint != 0x0A) && (codePoint != 0x0D)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (next >= 0x7F) {
|
if (codePoint >= 0x7F) {
|
||||||
buffer.append("&#x");
|
buffer.append("&#x");
|
||||||
buffer.append(Integer.toString(next, 16).toUpperCase());
|
buffer.append(Integer.toString(codePoint, 16).toUpperCase());
|
||||||
buffer.append(";");
|
buffer.append(";");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch (next) {
|
switch (codePoint) {
|
||||||
case '<':
|
case '<':
|
||||||
buffer.append(LESS_THAN);
|
buffer.append(LESS_THAN);
|
||||||
break;
|
break;
|
||||||
@@ -115,11 +118,8 @@ public class XmlUtilities {
|
|||||||
case '&':
|
case '&':
|
||||||
buffer.append(AMPERSAND);
|
buffer.append(AMPERSAND);
|
||||||
break;
|
break;
|
||||||
// Why was 7F deleted
|
|
||||||
// case 0x7F:
|
|
||||||
// break;
|
|
||||||
default:
|
default:
|
||||||
buffer.append(next);
|
buffer.appendCodePoint(codePoint);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,10 +137,10 @@ public class XmlUtilities {
|
|||||||
public static String unEscapeElementEntities(String escapedXMLString) {
|
public static String unEscapeElementEntities(String escapedXMLString) {
|
||||||
|
|
||||||
Matcher matcher = HEX_DIGIT_PATTERN.matcher(escapedXMLString);
|
Matcher matcher = HEX_DIGIT_PATTERN.matcher(escapedXMLString);
|
||||||
StringBuffer buffy = new StringBuffer();
|
StringBuilder buffy = new StringBuilder();
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
int intValue = Integer.parseInt(matcher.group(1), 16);
|
int codePoint = Integer.parseInt(matcher.group(1), 16);
|
||||||
matcher.appendReplacement(buffy, Character.toString((char) intValue));
|
matcher.appendReplacement(buffy, Character.toString(codePoint));
|
||||||
}
|
}
|
||||||
matcher.appendTail(buffy);
|
matcher.appendTail(buffy);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user