8276207: Properties.loadFromXML/storeToXML works incorrectly for supplementary characters

Reviewed-by: joehw
This commit is contained in:
Anirvan Sarkar 2021-11-06 00:41:44 +00:00 committed by Joe Wang
parent ed7ecca401
commit c7095b20d9
3 changed files with 74 additions and 32 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -1993,20 +1993,18 @@ public abstract class Parser {
try {
int i = Integer.parseInt(
new String(mBuff, idx + 1, mBuffIdx - idx), 10);
if (i >= 0xffff) {
panic(FAULT);
// Restore the buffer offset
mBuffIdx = idx - 1;
for(char character : Character.toChars(i)) {
if (character == ' ' || mInp.next != null) {
bappend(character, flag);
} else {
bappend(character);
}
}
ch = (char) i;
} catch (NumberFormatException nfe) {
panic(FAULT);
}
// Restore the buffer offset
mBuffIdx = idx - 1;
if (ch == ' ' || mInp.next != null) {
bappend(ch, flag);
} else {
bappend(ch);
}
st = -1;
break;
@ -2034,20 +2032,18 @@ public abstract class Parser {
try {
int i = Integer.parseInt(
new String(mBuff, idx + 1, mBuffIdx - idx), 16);
if (i >= 0xffff) {
panic(FAULT);
// Restore the buffer offset
mBuffIdx = idx - 1;
for(char character : Character.toChars(i)) {
if (character == ' ' || mInp.next != null) {
bappend(character, flag);
} else {
bappend(character);
}
}
ch = (char) i;
} catch (NumberFormatException nfe) {
panic(FAULT);
}
// Restore the buffer offset
mBuffIdx = idx - 1;
if (ch == ' ' || mInp.next != null) {
bappend(ch, flag);
} else {
bappend(ch);
}
st = -1;
break;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -360,6 +360,15 @@ public class XMLStreamWriterImpl implements XMLStreamWriter {
_doIndent = doIndent;
}
/**
* Writes character reference in hex format.
*/
private void writeCharRef(int codePoint) throws XMLStreamException {
_writer.write(ENCODING_PREFIX);
_writer.write(Integer.toHexString(codePoint));
_writer.write(SEMICOLON);
}
/**
* Writes XML content to underlying writer. Escapes characters unless
* escaping character feature is turned off.
@ -383,10 +392,15 @@ public class XMLStreamWriterImpl implements XMLStreamWriter {
if (!_writer.canEncode(ch)) {
_writer.write(content, startWritePos, index - startWritePos);
// Escape this char as underlying encoder cannot handle it
_writer.write(ENCODING_PREFIX);
_writer.write(Integer.toHexString(ch));
_writer.write(SEMICOLON);
// Check if current and next characters forms a surrogate pair
// and escape it to avoid generation of invalid xml content
if ( index != end - 1 && Character.isSurrogatePair(ch, content[index+1])) {
writeCharRef(Character.toCodePoint(ch, content[index+1]));
index++;
} else {
writeCharRef(ch);
}
startWritePos = index + 1;
continue;
}
@ -455,10 +469,15 @@ public class XMLStreamWriterImpl implements XMLStreamWriter {
if (!_writer.canEncode(ch)) {
_writer.write(content, startWritePos, index - startWritePos);
// Escape this char as underlying encoder cannot handle it
_writer.write(ENCODING_PREFIX);
_writer.write(Integer.toHexString(ch));
_writer.write(SEMICOLON);
// Check if current and next characters forms a surrogate pair
// and escape it to avoid generation of invalid xml content
if ( index != end - 1 && Character.isSurrogatePair(ch, content.charAt(index+1))) {
writeCharRef(Character.toCodePoint(ch, content.charAt(index+1)));
index++;
} else {
writeCharRef(ch);
}
startWritePos = index + 1;
continue;
}