You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by zh...@apache.org on 2010/10/15 09:25:10 UTC
svn commit: r1022846 - in
/harmony/enhanced/java/trunk/classlib/modules/beans/src:
main/java/java/beans/XMLDecoder.java main/java/java/beans/XMLEncoder.java
test/java/org/apache/harmony/beans/tests/java/beans/XMLEncoderTest.java
Author: zhoukevin
Date: Fri Oct 15 07:25:09 2010
New Revision: 1022846
URL: http://svn.apache.org/viewvc?rev=1022846&view=rev
Log:
java.beans.XMLEncoder/Decoder fails to process invalid chars. Add 2 test cases to reproduce the problems
Modified:
harmony/enhanced/java/trunk/classlib/modules/beans/src/main/java/java/beans/XMLDecoder.java
harmony/enhanced/java/trunk/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java
harmony/enhanced/java/trunk/classlib/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/XMLEncoderTest.java
Modified: harmony/enhanced/java/trunk/classlib/modules/beans/src/main/java/java/beans/XMLDecoder.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/classlib/modules/beans/src/main/java/java/beans/XMLDecoder.java?rev=1022846&r1=1022845&r2=1022846&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/classlib/modules/beans/src/main/java/java/beans/XMLDecoder.java (original)
+++ harmony/enhanced/java/trunk/classlib/modules/beans/src/main/java/java/beans/XMLDecoder.java Fri Oct 15 07:25:09 2010
@@ -111,6 +111,7 @@ public class XMLDecoder {
elem.isExpression = true;
elem.id = attributes.getValue("id");
elem.idref = attributes.getValue("idref");
+ elem.attributes = attributes;
if (elem.idref == null) {
obtainTarget(elem, attributes);
obtainMethod(elem, attributes);
@@ -201,6 +202,7 @@ public class XMLDecoder {
Elem elem = new Elem();
elem.isExpression = true;
elem.id = attributes.getValue("id"); //$NON-NLS-1$
+ elem.attributes = attributes;
try {
// find component class
Class<?> compClass = classForName(attributes.getValue("class")); //$NON-NLS-1$
@@ -230,6 +232,7 @@ public class XMLDecoder {
private void startVoidElem(Attributes attributes) {
Elem elem = new Elem();
elem.id = attributes.getValue("id");
+ elem.attributes = attributes;
obtainTarget(elem, attributes);
obtainMethod(elem, attributes);
readObjs.push(elem);
@@ -242,6 +245,7 @@ public class XMLDecoder {
elem.isExpression = true;
elem.id = attributes.getValue("id");
elem.idref = attributes.getValue("idref");
+ elem.attributes = attributes;
elem.target = tagName;
readObjs.push(elem);
}
@@ -258,6 +262,21 @@ public class XMLDecoder {
}
// find the elem to close
Elem toClose = latestUnclosedElem();
+ if ("string".equals(toClose.target)) {
+ StringBuilder sb = new StringBuilder();
+ for (int index = readObjs.size() - 1; index >= 0; index--) {
+ Elem elem = (Elem) readObjs.get(index);
+ if (toClose == elem) {
+ break;
+ }
+ if ("char".equals(elem.target)) {
+ sb.insert(0, elem.methodName);
+ }
+ }
+ toClose.methodName = toClose.methodName != null ? toClose.methodName
+ + sb.toString()
+ : sb.toString();
+ }
// make sure it is executed
execute(toClose);
// set to closed
@@ -465,6 +484,15 @@ public class XMLDecoder {
} else if ("byte".equals(tag)) {
return Byte.valueOf(value);
} else if ("char".equals(tag)) {
+ if (value == null && elem.attributes != null) {
+ String codeAttr = elem.attributes.getValue("code");
+ if (codeAttr != null) {
+ Character character = new Character((char) Integer
+ .valueOf(codeAttr.substring(1), 16).intValue());
+ elem.methodName = character.toString();
+ return character;
+ }
+ }
return Character.valueOf(value.charAt(0));
} else if ("double".equals(tag)) {
return Double.valueOf(value);
@@ -522,6 +550,8 @@ public class XMLDecoder {
boolean fromOwner;
+ Attributes attributes;
+
Object result;
}
Modified: harmony/enhanced/java/trunk/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java?rev=1022846&r1=1022845&r2=1022846&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java (original)
+++ harmony/enhanced/java/trunk/classlib/modules/beans/src/main/java/java/beans/XMLEncoder.java Fri Oct 15 07:25:09 2010
@@ -219,7 +219,13 @@ public class XMLEncoder extends Encoder
} else if (obj instanceof Byte) {
out.println("<byte>" + obj + "</byte> ");
} else if (obj instanceof Character) {
- out.println("<char>" + obj + "</char> ");
+ char objChar = ((Character) obj).charValue();
+ if (invalidCharacter(objChar)) {
+ out.println("<char code=\"#" + Integer.toString(objChar, 16)
+ + "\"/>");
+ } else {
+ out.println("<char>" + objChar + "</char> ");
+ }
} else if (obj instanceof Double) {
out.println("<double>" + obj + "</double> ");
} else if (obj instanceof Float) {
@@ -236,6 +242,11 @@ public class XMLEncoder extends Encoder
}
}
+ private boolean invalidCharacter(char c) {
+ return ((0x0000 <= c && c < 0x0009) || (0x000a < c && c < 0x000d)
+ || (0x000d < c && c < 0x0020) || (0xd7ff < c && c < 0xe000) || c == 0xfffe);
+ }
+
@SuppressWarnings("nls")
private void flushExpression(Object obj, Record rec, int indent,
boolean asStatement) {
@@ -612,7 +623,12 @@ public class XMLEncoder extends Encoder
} else if (c == '"') {
out.print(""");
} else {
- out.print(c);
+ if (invalidCharacter(c)) {
+ out.print("<char code=\"#" + Integer.toString(c, 16)
+ + "\"/>");
+ } else {
+ out.print(c);
+ }
}
}
}
Modified: harmony/enhanced/java/trunk/classlib/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/XMLEncoderTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/java/trunk/classlib/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/XMLEncoderTest.java?rev=1022846&r1=1022845&r2=1022846&view=diff
==============================================================================
--- harmony/enhanced/java/trunk/classlib/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/XMLEncoderTest.java (original)
+++ harmony/enhanced/java/trunk/classlib/modules/beans/src/test/java/org/apache/harmony/beans/tests/java/beans/XMLEncoderTest.java Fri Oct 15 07:25:09 2010
@@ -25,6 +25,7 @@ import java.beans.ExceptionListener;
import java.beans.Expression;
import java.beans.PersistenceDelegate;
import java.beans.Statement;
+import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
@@ -1022,4 +1023,106 @@ public class XMLEncoderTest extends Test
this.name = name;
}
}
+
+ public static class MockCharProperty {
+ private char property;
+
+ public char getProperty() {
+ return property;
+ }
+
+ public void setProperty(char property) {
+ this.property = property;
+ }
+
+ public boolean equals(Object obj) {
+ if (obj instanceof MockCharProperty) {
+ return ((MockCharProperty) obj).property == (this.property);
+ }
+ return false;
+ }
+ }
+
+ public void testMockCharProperty() {
+ MockCharProperty expectedObj = new MockCharProperty();
+ MockCharProperty actualObj;
+ ByteArrayOutputStream baos;
+ ByteArrayInputStream bais;
+ XMLEncoder xmlEncoder;
+ XMLDecoder xmlDecoder;
+ char ch;
+ for (int index = 1; index < 65536; index++) {
+ ch = (char) index;
+ if (invalidCharacter(ch)) {
+ expectedObj.setProperty(ch);
+ baos = new ByteArrayOutputStream();
+ xmlEncoder = new XMLEncoder(baos);
+ xmlEncoder.writeObject(expectedObj);
+ xmlEncoder.close();
+ assertTrue(baos.toString().contains("<char code=\"#"));
+
+ bais = new ByteArrayInputStream(baos.toByteArray());
+ xmlDecoder = new XMLDecoder(bais);
+ actualObj = (MockCharProperty) xmlDecoder.readObject();
+ xmlDecoder.close();
+ assertEquals(expectedObj, actualObj);
+ }
+ }
+ }
+
+ public static class MockStringProperty {
+ private String property;
+
+ public String getProperty() {
+ return property;
+ }
+
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+ public boolean equals(Object obj) {
+ if (obj instanceof MockStringProperty) {
+ return ((MockStringProperty) obj).property
+ .equals(this.property);
+ }
+ return false;
+ }
+ }
+
+ public void testMockStringProperty() {
+ MockStringProperty expectedObj = new MockStringProperty();
+ MockStringProperty actualObj;
+ ByteArrayOutputStream baos;
+ ByteArrayInputStream bais;
+ XMLEncoder xmlEncoder;
+ XMLDecoder xmlDecoder;
+ char ch;
+ for (int index = 0; index < 65536; index++) {
+ ch = (char) index;
+ if (invalidCharacter(ch)) {
+ expectedObj.setProperty(stringWithChar(ch));
+ baos = new ByteArrayOutputStream();
+ xmlEncoder = new XMLEncoder(baos);
+ xmlEncoder.writeObject(expectedObj);
+ xmlEncoder.close();
+ assertTrue(baos.toString().contains("<char code=\"#"));
+
+ bais = new ByteArrayInputStream(baos.toByteArray());
+ xmlDecoder = new XMLDecoder(bais);
+ actualObj = (MockStringProperty) xmlDecoder.readObject();
+ xmlDecoder.close();
+ assertEquals(expectedObj, actualObj);
+ }
+ }
+ }
+
+ private String stringWithChar(char character) {
+ return "a string with a " + character + " character";
+ }
+
+ private boolean invalidCharacter(char c) {
+ return ((0x0000 <= c && c < 0x0009) || (0x000a < c && c < 0x000d)
+ || (0x000d < c && c < 0x0020) || (0xd7ff < c && c < 0xe000) || c == 0xfffe);
+ }
}
\ No newline at end of file