8026417: Enhance XML canonicalization

Copy before use mutable byte arrays. Also reviewed by Alexander Fomin <alexander.fomin@oracle.com>

Reviewed-by: mullan, hawtin, ahgross
This commit is contained in:
Xue-Lei Andrew Fan 2013-10-23 21:24:34 -07:00
parent 15d051e851
commit 623fe13d2c

View File

@ -64,6 +64,8 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
protected static final AttrCompare COMPARE = new AttrCompare(); protected static final AttrCompare COMPARE = new AttrCompare();
// Make sure you clone the following mutable arrays before passing to
// potentially untrusted objects such as OutputStreams.
private static final byte[] END_PI = {'?','>'}; private static final byte[] END_PI = {'?','>'};
private static final byte[] BEGIN_PI = {'<','?'}; private static final byte[] BEGIN_PI = {'<','?'};
private static final byte[] END_COMM = {'-','-','>'}; private static final byte[] END_COMM = {'-','-','>'};
@ -76,7 +78,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
private static final byte[] LT = {'&','l','t',';'}; private static final byte[] LT = {'&','l','t',';'};
private static final byte[] END_TAG = {'<','/'}; private static final byte[] END_TAG = {'<','/'};
private static final byte[] AMP = {'&','a','m','p',';'}; private static final byte[] AMP = {'&','a','m','p',';'};
private static final byte[] equalsStr = {'=','\"'}; private static final byte[] EQUALS_STR = {'=','\"'};
protected static final int NODE_BEFORE_DOCUMENT_ELEMENT = -1; protected static final int NODE_BEFORE_DOCUMENT_ELEMENT = -1;
protected static final int NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT = 0; protected static final int NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT = 0;
@ -303,7 +305,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
writer.write('>'); writer.write('>');
sibling = currentNode.getFirstChild(); sibling = currentNode.getFirstChild();
if (sibling == null) { if (sibling == null) {
writer.write(END_TAG); writer.write(END_TAG.clone());
UtfHelpper.writeStringToUtf8(name, writer); UtfHelpper.writeStringToUtf8(name, writer);
writer.write('>'); writer.write('>');
//We finished with this level, pop to the previous definitions. //We finished with this level, pop to the previous definitions.
@ -321,7 +323,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
break; break;
} }
while (sibling == null && parentNode != null) { while (sibling == null && parentNode != null) {
writer.write(END_TAG); writer.write(END_TAG.clone());
UtfHelpper.writeByte(((Element)parentNode).getTagName(), writer, cache); UtfHelpper.writeByte(((Element)parentNode).getTagName(), writer, cache);
writer.write('>'); writer.write('>');
//We finished with this level, pop to the previous definitions. //We finished with this level, pop to the previous definitions.
@ -481,7 +483,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
if (sibling == null) { if (sibling == null) {
if (currentNodeIsVisible) { if (currentNodeIsVisible) {
writer.write(END_TAG); writer.write(END_TAG.clone());
UtfHelpper.writeByte(name, writer, cache); UtfHelpper.writeByte(name, writer, cache);
writer.write('>'); writer.write('>');
//We finished with this level, pop to the previous definitions. //We finished with this level, pop to the previous definitions.
@ -503,7 +505,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
} }
while (sibling == null && parentNode != null) { while (sibling == null && parentNode != null) {
if (isVisible(parentNode)) { if (isVisible(parentNode)) {
writer.write(END_TAG); writer.write(END_TAG.clone());
UtfHelpper.writeByte(((Element)parentNode).getTagName(), writer, cache); UtfHelpper.writeByte(((Element)parentNode).getTagName(), writer, cache);
writer.write('>'); writer.write('>');
//We finished with this level, pop to the previous definitions. //We finished with this level, pop to the previous definitions.
@ -690,7 +692,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
) throws IOException { ) throws IOException {
writer.write(' '); writer.write(' ');
UtfHelpper.writeByte(name, writer, cache); UtfHelpper.writeByte(name, writer, cache);
writer.write(equalsStr); writer.write(EQUALS_STR.clone());
byte[] toWrite; byte[] toWrite;
final int length = value.length(); final int length = value.length();
int i = 0; int i = 0;
@ -700,27 +702,27 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
switch (c) { switch (c) {
case '&' : case '&' :
toWrite = AMP; toWrite = AMP.clone();
break; break;
case '<' : case '<' :
toWrite = LT; toWrite = LT.clone();
break; break;
case '"' : case '"' :
toWrite = QUOT; toWrite = QUOT.clone();
break; break;
case 0x09 : // '\t' case 0x09 : // '\t'
toWrite = X9; toWrite = X9.clone();
break; break;
case 0x0A : // '\n' case 0x0A : // '\n'
toWrite = XA; toWrite = XA.clone();
break; break;
case 0x0D : // '\r' case 0x0D : // '\r'
toWrite = XD; toWrite = XD.clone();
break; break;
default : default :
@ -750,7 +752,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
if (position == NODE_AFTER_DOCUMENT_ELEMENT) { if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
writer.write('\n'); writer.write('\n');
} }
writer.write(BEGIN_PI); writer.write(BEGIN_PI.clone());
final String target = currentPI.getTarget(); final String target = currentPI.getTarget();
int length = target.length(); int length = target.length();
@ -758,7 +760,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
char c = target.charAt(i); char c = target.charAt(i);
if (c == 0x0D) { if (c == 0x0D) {
writer.write(XD); writer.write(XD.clone());
} else { } else {
if (c < 0x80) { if (c < 0x80) {
writer.write(c); writer.write(c);
@ -778,14 +780,14 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
char c = data.charAt(i); char c = data.charAt(i);
if (c == 0x0D) { if (c == 0x0D) {
writer.write(XD); writer.write(XD.clone());
} else { } else {
UtfHelpper.writeCharToUtf8(c, writer); UtfHelpper.writeCharToUtf8(c, writer);
} }
} }
} }
writer.write(END_PI); writer.write(END_PI.clone());
if (position == NODE_BEFORE_DOCUMENT_ELEMENT) { if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
writer.write('\n'); writer.write('\n');
} }
@ -804,7 +806,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
if (position == NODE_AFTER_DOCUMENT_ELEMENT) { if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
writer.write('\n'); writer.write('\n');
} }
writer.write(BEGIN_COMM); writer.write(BEGIN_COMM.clone());
final String data = currentComment.getData(); final String data = currentComment.getData();
final int length = data.length(); final int length = data.length();
@ -812,7 +814,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
char c = data.charAt(i); char c = data.charAt(i);
if (c == 0x0D) { if (c == 0x0D) {
writer.write(XD); writer.write(XD.clone());
} else { } else {
if (c < 0x80) { if (c < 0x80) {
writer.write(c); writer.write(c);
@ -822,7 +824,7 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
} }
} }
writer.write(END_COMM); writer.write(END_COMM.clone());
if (position == NODE_BEFORE_DOCUMENT_ELEMENT) { if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
writer.write('\n'); writer.write('\n');
} }
@ -846,19 +848,19 @@ public abstract class CanonicalizerBase extends CanonicalizerSpi {
switch (c) { switch (c) {
case '&' : case '&' :
toWrite = AMP; toWrite = AMP.clone();
break; break;
case '<' : case '<' :
toWrite = LT; toWrite = LT.clone();
break; break;
case '>' : case '>' :
toWrite = GT; toWrite = GT.clone();
break; break;
case 0xD : case 0xD :
toWrite = XD; toWrite = XD.clone();
break; break;
default : default :