Log Message
Merge new InterfaceTypePermission from trunk into branch. Enable permissions for XStreamer.
Modified Paths
- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/XStream.java
- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/XStreamer.java
- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/security/ExplicitTypePermission.java
- branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/XStreamer.xsl
- branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/XStreamerTest.java
- branches/v-1.4.x/xstream/src/test/com/thoughtworks/xstream/converters/extended/JavaClassConverterTest.java
- branches/v-1.4.x/xstream-distribution/src/content/security.html
Added Paths
Property Changed
Diff
Property changes: branches/v-1.4.x
Modified: svn:mergeinfo
Modified: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/XStream.java (2241 => 2242)
--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/XStream.java 2014-01-30 20:48:06 UTC (rev 2241)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/XStream.java 2014-01-30 21:13:06 UTC (rev 2242)
@@ -145,6 +145,7 @@
import com.thoughtworks.xstream.security.NoPermission;
import com.thoughtworks.xstream.security.NoTypePermission;
import com.thoughtworks.xstream.security.RegExpTypePermission;
+import com.thoughtworks.xstream.security.TypeHierarchyPermission;
import com.thoughtworks.xstream.security.TypePermission;
import com.thoughtworks.xstream.security.WildcardTypePermission;
@@ -2024,6 +2025,26 @@
}
/**
+ * Add security permission for explicit types.
+ *
+ * @param types the types to allow
+ * @since upcoming
+ */
+ public void allowTypes(Class[] types) {
+ addPermission(new ExplicitTypePermission(types));
+ }
+
+ /**
+ * Add security permission for a type hierarchy.
+ *
+ * @param type the base type to allow
+ * @since upcoming
+ */
+ public void allowTypeHierarchy(Class type) {
+ addPermission(new TypeHierarchyPermission(type));
+ }
+
+ /**
* Add security permission for types matching one of the specified regular expressions.
*
* @param regexps the regular expressions to allow type names
@@ -2082,6 +2103,26 @@
}
/**
+ * Add security permission forbidding explicit types.
+ *
+ * @param types the types to forbid
+ * @since upcoming
+ */
+ public void denyTypes(Class[] types) {
+ denyPermission(new ExplicitTypePermission(types));
+ }
+
+ /**
+ * Add security permission forbidding a type hierarchy.
+ *
+ * @param type the base type to forbid
+ * @since upcoming
+ */
+ public void denyTypeHierarchy(Class type) {
+ denyPermission(new TypeHierarchyPermission(type));
+ }
+
+ /**
* Add security permission forbidding types matching one of the specified regular expressions.
*
* @param regexps the regular expressions to forbid type names
Modified: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/XStreamer.java (2241 => 2242)
--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/XStreamer.java 2014-01-30 20:48:06 UTC (rev 2241)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/XStreamer.java 2014-01-30 21:13:06 UTC (rev 2242)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 XStream Committers.
+ * Copyright (C) 2006, 2007, 2014 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -10,11 +10,6 @@
*/
package com.thoughtworks.xstream;
-import com.thoughtworks.xstream.converters.ConversionException;
-import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
-import com.thoughtworks.xstream.io.HierarchicalStreamReader;
-import com.thoughtworks.xstream.io.xml.XppDriver;
-
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -24,8 +19,15 @@
import java.io.StringWriter;
import java.io.Writer;
+import com.thoughtworks.xstream.converters.ConversionException;
+import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.xml.XppDriver;
+import com.thoughtworks.xstream.security.AnyTypePermission;
+import com.thoughtworks.xstream.security.TypePermission;
+
/**
- * Self-contained XStream generator. The class is a utility to write XML streams that contain
+ * Self-contained XStream generator. The class is a utility to write XML streams that contain
* additionally the XStream that was used to serialize the object graph. Such a stream can
* be unmarshalled using this embedded XStream instance, that kept any settings.
*
@@ -34,6 +36,10 @@
*/
public class XStreamer {
+ private final static TypePermission[] PERMISSIONS = {
+ AnyTypePermission.ANY
+ };
+
/**
* Serialize an object including the XStream to a pretty-printed XML String.
*
@@ -42,14 +48,14 @@
* @since 1.2
* @see #toXML(XStream, Object, Writer)
*/
- public String toXML(XStream xstream, Object obj) throws ObjectStreamException {
- Writer writer = new StringWriter();
+ public String toXML(final XStream xstream, final Object obj) throws ObjectStreamException {
+ final Writer writer = new StringWriter();
try {
toXML(xstream, obj, writer);
- } catch (ObjectStreamException e) {
+ } catch (final ObjectStreamException e) {
throw e;
- } catch (IOException e) {
- throw new ConversionException("Unexpeced IO error from a StringWriter", e);
+ } catch (final IOException e) {
+ throw new ConversionException("Unexpected IO error from a StringWriter", e);
}
return writer.toString();
}
@@ -69,10 +75,10 @@
* @throws com.thoughtworks.xstream.XStreamException if the object cannot be serialized
* @since 1.2
*/
- public void toXML(XStream xstream, Object obj, Writer out)
+ public void toXML(final XStream xstream, final Object obj, final Writer out)
throws IOException {
- XStream outer = new XStream();
- ObjectOutputStream oos = outer.createObjectOutputStream(out);
+ final XStream outer = new XStream();
+ final ObjectOutputStream oos = outer.createObjectOutputStream(out);
try {
oos.writeObject(xstream);
oos.flush();
@@ -84,75 +90,162 @@
/**
* Deserialize a self-contained XStream with object from a String. The method will use
- * internally an XppDriver to load the contained XStream instance.
+ * internally an XppDriver to load the contained XStream instance with default permissions.
*
+ * @param xml the XML data
* @throws ClassNotFoundException if a class in the XML stream cannot be found
* @throws ObjectStreamException if the XML contains non-deserializable elements
* @throws com.thoughtworks.xstream.XStreamException if the object cannot be deserialized
* @since 1.2
* @see #toXML(XStream, Object, Writer)
*/
- public Object fromXML(String xml) throws ClassNotFoundException, ObjectStreamException {
+ public Object fromXML(final String xml) throws ClassNotFoundException, ObjectStreamException {
try {
return fromXML(new StringReader(xml));
- } catch (ObjectStreamException e) {
+ } catch (final ObjectStreamException e) {
throw e;
- } catch (IOException e) {
- throw new ConversionException("Unexpeced IO error from a StringReader", e);
+ } catch (final IOException e) {
+ throw new ConversionException("Unexpected IO error from a StringReader", e);
}
}
/**
+ * Deserialize a self-contained XStream with object from a String. The method will use
+ * internally an XppDriver to load the contained XStream instance.
+ *
+ * @param xml the XML data
+ * @param permissions the permissions to use (ensure that they include the defaults)
+ * @throws ClassNotFoundException if a class in the XML stream cannot be found
+ * @throws ObjectStreamException if the XML contains non-deserializable elements
+ * @throws com.thoughtworks.xstream.XStreamException if the object cannot be deserialized
+ * @since upcoming
+ * @see #toXML(XStream, Object, Writer)
+ */
+ public Object fromXML(final String xml, final TypePermission[] permissions) throws ClassNotFoundException, ObjectStreamException {
+ try {
+ return fromXML(new StringReader(xml), permissions);
+ } catch (final ObjectStreamException e) {
+ throw e;
+ } catch (final IOException e) {
+ throw new ConversionException("Unexpected IO error from a StringReader", e);
+ }
+ }
+
+ /**
* Deserialize a self-contained XStream with object from a String.
*
+ * @param driver the implementation to use
+ * @param xml the XML data
* @throws ClassNotFoundException if a class in the XML stream cannot be found
* @throws ObjectStreamException if the XML contains non-deserializable elements
* @throws com.thoughtworks.xstream.XStreamException if the object cannot be deserialized
* @since 1.2
* @see #toXML(XStream, Object, Writer)
*/
- public Object fromXML(HierarchicalStreamDriver driver, String xml)
+ public Object fromXML(final HierarchicalStreamDriver driver, final String xml)
throws ClassNotFoundException, ObjectStreamException {
try {
return fromXML(driver, new StringReader(xml));
- } catch (ObjectStreamException e) {
+ } catch (final ObjectStreamException e) {
throw e;
- } catch (IOException e) {
- throw new ConversionException("Unexpeced IO error from a StringReader", e);
+ } catch (final IOException e) {
+ throw new ConversionException("Unexpected IO error from a StringReader", e);
}
}
/**
+ * Deserialize a self-contained XStream with object from a String.
+ *
+ * @param driver the implementation to use
+ * @param xml the XML data
+ * @param permissions the permissions to use (ensure that they include the defaults)
+ * @throws ClassNotFoundException if a class in the XML stream cannot be found
+ * @throws ObjectStreamException if the XML contains non-deserializable elements
+ * @throws com.thoughtworks.xstream.XStreamException if the object cannot be deserialized
+ * @since upcoming
+ * @see #toXML(XStream, Object, Writer)
+ */
+ public Object fromXML(final HierarchicalStreamDriver driver, final String xml, final TypePermission[] permissions)
+ throws ClassNotFoundException, ObjectStreamException {
+ try {
+ return fromXML(driver, new StringReader(xml), permissions);
+ } catch (final ObjectStreamException e) {
+ throw e;
+ } catch (final IOException e) {
+ throw new ConversionException("Unexpected IO error from a StringReader", e);
+ }
+ }
+
+ /**
* Deserialize a self-contained XStream with object from an XML Reader. The method will use
- * internally an XppDriver to load the contained XStream instance.
+ * internally an XppDriver to load the contained XStream instance with default permissions.
*
+ * @param xml the {@link Reader} providing the XML data
* @throws IOException if an error occurs reading from the Reader.
* @throws ClassNotFoundException if a class in the XML stream cannot be found
* @throws com.thoughtworks.xstream.XStreamException if the object cannot be deserialized
* @since 1.2
* @see #toXML(XStream, Object, Writer)
*/
- public Object fromXML(Reader xml)
+ public Object fromXML(final Reader xml)
throws IOException, ClassNotFoundException {
return fromXML(new XppDriver(), xml);
}
/**
- * Deserialize a self-contained XStream with object from an XML Reader.
+ * Deserialize a self-contained XStream with object from an XML Reader. The method will use
+ * internally an XppDriver to load the contained XStream instance.
*
+ * @param xml the {@link Reader} providing the XML data
+ * @param permissions the permissions to use (ensure that they include the defaults)
* @throws IOException if an error occurs reading from the Reader.
* @throws ClassNotFoundException if a class in the XML stream cannot be found
* @throws com.thoughtworks.xstream.XStreamException if the object cannot be deserialized
+ * @since upcoming
+ * @see #toXML(XStream, Object, Writer)
+ */
+ public Object fromXML(final Reader xml, final TypePermission[] permissions)
+ throws IOException, ClassNotFoundException {
+ return fromXML(new XppDriver(), xml, permissions);
+ }
+
+ /**
+ * Deserialize a self-contained XStream with object from an XML Reader.
+ *
+ * @param driver the implementation to use
+ * @param xml the {@link Reader} providing the XML data
+ * @throws IOException if an error occurs reading from the Reader.
+ * @throws ClassNotFoundException if a class in the XML stream cannot be found
+ * @throws com.thoughtworks.xstream.XStreamException if the object cannot be deserialized
* @since 1.2
*/
- public Object fromXML(HierarchicalStreamDriver driver, Reader xml)
+ public Object fromXML(final HierarchicalStreamDriver driver, final Reader xml)
throws IOException, ClassNotFoundException {
- XStream outer = new XStream(driver);
- HierarchicalStreamReader reader = driver.createReader(xml);
- ObjectInputStream configIn = outer.createObjectInputStream(reader);
+ return fromXML(driver, xml, PERMISSIONS);
+ }
+
+ /**
+ * Deserialize a self-contained XStream with object from an XML Reader.
+ *
+ * @param driver the implementation to use
+ * @param xml the {@link Reader} providing the XML data
+ * @param permissions the permissions to use (ensure that they include the defaults)
+ * @throws IOException if an error occurs reading from the Reader.
+ * @throws ClassNotFoundException if a class in the XML stream cannot be found
+ * @throws com.thoughtworks.xstream.XStreamException if the object cannot be deserialized
+ * @since upcoming
+ */
+ public Object fromXML(final HierarchicalStreamDriver driver, final Reader xml, final TypePermission[] permissions)
+ throws IOException, ClassNotFoundException {
+ final XStream outer = new XStream(driver);
+ for(int i = 0; i < permissions.length; ++i) {
+ outer.addPermission(permissions[i]);
+ }
+ final HierarchicalStreamReader reader = driver.createReader(xml);
+ final ObjectInputStream configIn = outer.createObjectInputStream(reader);
try {
- XStream configured = (XStream)configIn.readObject();
- ObjectInputStream in = configured.createObjectInputStream(reader);
+ final XStream configured = (XStream)configIn.readObject();
+ final ObjectInputStream in = configured.createObjectInputStream(reader);
try {
return in.readObject();
} finally {
@@ -163,4 +256,16 @@
}
}
+ /**
+ * Retrieve the default permissions to unmarshal an XStream instance.
+ * <p>
+ * The returned list will only cover permissions for XStream's own types. If your custom converters or mappers keep
+ * references to other types, you will have to add permission for those types on your own.
+ * </p>
+ *
+ * @since upcoming
+ */
+ public static TypePermission[] getDefaultPermissions() {
+ return PERMISSIONS.clone();
+ }
}
Modified: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/security/ExplicitTypePermission.java (2241 => 2242)
--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/security/ExplicitTypePermission.java 2014-01-30 20:48:06 UTC (rev 2241)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/security/ExplicitTypePermission.java 2014-01-30 21:13:06 UTC (rev 2242)
@@ -11,6 +11,7 @@
import java.util.HashSet;
import java.util.Set;
+
/**
* Explicit permission for a type with a name matching one in the provided list.
*
@@ -20,10 +21,26 @@
public class ExplicitTypePermission implements TypePermission {
final Set names;
-
+
/**
* @since upcoming
*/
+ public ExplicitTypePermission(final Class[] types) {
+ this(new Object() {
+ public String[] getNames() {
+ if (types == null)
+ return null;
+ String[] names = new String[types.length];
+ for (int i = 0; i < types.length; ++i)
+ names[i] = types[i].getName();
+ return names;
+ }
+ }.getNames());
+ }
+
+ /**
+ * @since upcoming
+ */
public ExplicitTypePermission(String[] names) {
this.names = names == null ? Collections.EMPTY_SET : new HashSet(Arrays.asList(names));
}
Copied: branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/security/InterfaceTypePermission.java (from rev 2236, trunk/xstream/src/java/com/thoughtworks/xstream/security/InterfaceTypePermission.java) (0 => 2242)
--- branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/security/InterfaceTypePermission.java (rev 0)
+++ branches/v-1.4.x/xstream/src/java/com/thoughtworks/xstream/security/InterfaceTypePermission.java 2014-01-30 21:13:06 UTC (rev 2242)
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2014 XStream Committers.
+ * All rights reserved.
+ *
+ * Created on 27. January 2014 by Joerg Schaible
+ */
+package com.thoughtworks.xstream.security;
+
+/**
+ * Permission for any interface type.
+ *
+ * @author Jörg Schaible
+ * @since upcoming
+ */
+public class InterfaceTypePermission implements TypePermission {
+ /**
+ * @since upcoming
+ */
+ public static final TypePermission INTERFACES = new InterfaceTypePermission();
+
+ public boolean allows(Class type) {
+ return type != null && type.isInterface();
+ }
+
+ public int hashCode() {
+ return 31;
+ }
+
+ public boolean equals(Object obj) {
+ return obj != null && obj.getClass() == InterfaceTypePermission.class;
+ }
+
+}
Modified: branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/XStreamer.xsl (2241 => 2242)
--- branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/XStreamer.xsl 2014-01-30 20:48:06 UTC (rev 2241)
+++ branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/XStreamer.xsl 2014-01-30 21:13:06 UTC (rev 2242)
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!--
-Copyright (C) 2006, 2007, 2008 XStream Committers.
+Copyright (C) 2006, 2007, 2008, 2014 XStream Committers.
All rights reserved.
The software in this package is published under the terms of the BSD
@@ -17,6 +17,13 @@
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
+<xsl:template match="names">
+ <xsl:copy>
+ <xsl:apply-templates select="string">
+ <xsl:sort/>
+ </xsl:apply-templates>
+ </xsl:copy>
+</xsl:template>
<xsl:template match="typeToImpl|typeToName|classToName|packageToName">
<xsl:copy>
<xsl:apply-templates select="entry">
Modified: branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/XStreamerTest.java (2241 => 2242)
--- branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/XStreamerTest.java 2014-01-30 20:48:06 UTC (rev 2241)
+++ branches/v-1.4.x/xstream/src/test/com/thoughtworks/acceptance/XStreamerTest.java 2014-01-30 21:13:06 UTC (rev 2242)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006 Joe Walnes.
- * Copyright (C) 2006, 2007 XStream Committers.
+ * Copyright (C) 2006, 2007, 2014 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -54,6 +54,7 @@
xstream.toXML(c);
fail("Thrown " + ConversionException.class.getName() + " expected");
} catch (final ConversionException e) {
+ assertTrue(e.getMessage().contains("XStream instance"));
}
}
Modified: branches/v-1.4.x/xstream/src/test/com/thoughtworks/xstream/converters/extended/JavaClassConverterTest.java (2241 => 2242)
--- branches/v-1.4.x/xstream/src/test/com/thoughtworks/xstream/converters/extended/JavaClassConverterTest.java 2014-01-30 20:48:06 UTC (rev 2241)
+++ branches/v-1.4.x/xstream/src/test/com/thoughtworks/xstream/converters/extended/JavaClassConverterTest.java 2014-01-30 21:13:06 UTC (rev 2242)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2005 Joe Walnes.
- * Copyright (C) 2006, 2007 XStream Committers.
+ * Copyright (C) 2006, 2007, 2014 XStream Committers.
* All rights reserved.
*
* The software in this package is published under the terms of the BSD
@@ -57,4 +57,23 @@
assertTrue("Should be an array", result.isArray());
assertEquals("com.thoughtworks.xstream.converters.extended.JavaClassConverterTest$B", result.getComponentType().getName());
}
+
+ public void testHandlesJavaClassArray() {
+ xstream.registerConverter(new JavaClassConverter(xstream.getMapper()){});
+
+ Class[] classes = new Class[] {
+ Object.class,
+ Comparable.class,
+ null,
+ Throwable.class
+ };
+
+ assertBothWays(classes, ""
+ + "<java-class-array>\n"
+ + " <java-class>object</java-class>\n"
+ + " <java-class>java.lang.Comparable</java-class>\n"
+ + " <null/>\n"
+ + " <java-class>java.lang.Throwable</java-class>\n"
+ + "</java-class-array>");
+ }
}
Modified: branches/v-1.4.x/xstream-distribution/src/content/security.html (2241 => 2242)
--- branches/v-1.4.x/xstream-distribution/src/content/security.html 2014-01-30 20:48:06 UTC (rev 2241)
+++ branches/v-1.4.x/xstream-distribution/src/content/security.html 2014-01-30 21:13:06 UTC (rev 2242)
@@ -113,15 +113,19 @@
<p>The <a href="" facade provides the following methods to
register such type permissions within the SecurityMapper:</p><div class="Source Java">
<pre>XStream.addPermission(TypePermission);
+XStream.allowTypes(Class[]);
XStream.allowTypes(String[]);
XStream.allowTypesByRegExp(String[]);
XStream.allowTypesByRegExp(Pattern[]);
XStream.allowTypesByWildcard(String[]);
+XStream.allowTypeHierary(Class);
XStream.denyPermission(TypePermission);
+XStream.denyTypes(Class[]);
XStream.denyTypes(String[]);
XStream.denyTypesByRegExp(String[]);
XStream.denyTypesByRegExp(Pattern[]);
-XStream.denyTypesByWildcard(String[]);</pre></div>
+XStream.denyTypesByWildcard(String[]);
+XStream.denyTypeHierary(Class);</pre></div>
<p>The sequence of registration is essential. The most recently registered permission will be evaluated first.</p>
@@ -153,12 +157,12 @@
</tr>
<tr>
<td><a href=""
- <td>Allow any array type.</td>
+ <td>Allow any array type. You may use the ARRAYS instance directly.</td>
<td> </td>
</tr>
<tr>
<td><a href=""
- <td>Allow any CGLIB proxy type.</td>
+ <td>Allow any CGLIB proxy type. You may use the PROXIES instance directly.</td>
<td> </td>
</tr>
<tr>
@@ -167,6 +171,11 @@
<td> </td>
</tr>
<tr>
+ <td><a href=""
+ <td>Allow any interface type. You may use the INTERFACES instance directly.</td>
+ <td> </td>
+ </tr>
+ <tr>
<td><a href=""
<td>Invert any other permission. Instances of this type are used by XStream in the deny methods.</td>
<td class="example"> </td>
@@ -179,17 +188,17 @@
</tr>
<tr>
<td><a href=""
- <td>Allow null as type.</td>
+ <td>Allow null as type. You may use the NULL instance directly.</td>
<td> </td>
</tr>
<tr>
<td><a href=""
- <td>Allow any primitive type and its boxed counterpart.</td>
+ <td>Allow any primitive type and its boxed counterpart (incl void). You may use the PROXIES instance directly.</td>
<td> </td>
</tr>
<tr>
<td><a href=""
- <td>Allow any Java proxy type.</td>
+ <td>Allow any Java proxy type. You may use the PROXIES instance directly.</td>
<td> </td>
</tr>
<tr>
To unsubscribe from this list please visit:
