+1 Very nice to see this happening :-)
Send from my mobile device > Am 19.11.2015 um 18:08 schrieb bdelacre...@apache.org: > > Author: bdelacretaz > Date: Thu Nov 19 17:08:23 2015 > New Revision: 1715217 > > URL: http://svn.apache.org/viewvc?rev=1715217&view=rev > Log: > IO-487 - ValidatingObjectInputStream, restricts which classes can be > deserialized > > Added: > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/ > > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/ClassNameMatcher.java > > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/FullClassNameMatcher.java > > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/RegexpClassNameMatcher.java > > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/ValidatingObjectInputStream.java > > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/WildcardClassNameMatcher.java > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/ > > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/FullClassNameMatcherTest.java > > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/OurTestClass.java > > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/RegexpClassNameMatcherTest.java > > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/ValidatingObjectInputStreamTest.java > > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/WildcardClassNameMatcherTest.java > > Added: > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/ClassNameMatcher.java > URL: > http://svn.apache.org/viewvc/commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/ClassNameMatcher.java?rev=1715217&view=auto > ============================================================================== > --- > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/ClassNameMatcher.java > (added) > +++ > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/ClassNameMatcher.java > Thu Nov 19 17:08:23 2015 > @@ -0,0 +1,29 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.commons.io.serialization; > + > +/** Match a Class name */ > +public interface ClassNameMatcher { > + > + /** True if the supplied class names matches. > + * @param className fully qualified class name > + * @return true if the class name matches this object's condition > + */ > + boolean matches(String className); > +} > \ No newline at end of file > > Added: > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/FullClassNameMatcher.java > URL: > http://svn.apache.org/viewvc/commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/FullClassNameMatcher.java?rev=1715217&view=auto > ============================================================================== > --- > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/FullClassNameMatcher.java > (added) > +++ > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/FullClassNameMatcher.java > Thu Nov 19 17:08:23 2015 > @@ -0,0 +1,44 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.commons.io.serialization; > + > +import java.util.Arrays; > +import java.util.Collections; > +import java.util.HashSet; > +import java.util.Set; > + > +/** {@link ClassNameMatcher} that matches on full class names */ > +final class FullClassNameMatcher implements ClassNameMatcher { > + > + private final Set<String> classesSet; > + > + /** > + * Constructs an object based on the specified class names. > + * > + * @param classes a list of class names > + */ > + public FullClassNameMatcher(String... classes) { > + classesSet = Collections.unmodifiableSet(new > HashSet<String>(Arrays.asList(classes))); > + } > + > + @Override > + public boolean matches(String className) { > + return classesSet.contains(className); > + } > +} > \ No newline at end of file > > Added: > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/RegexpClassNameMatcher.java > URL: > http://svn.apache.org/viewvc/commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/RegexpClassNameMatcher.java?rev=1715217&view=auto > ============================================================================== > --- > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/RegexpClassNameMatcher.java > (added) > +++ > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/RegexpClassNameMatcher.java > Thu Nov 19 17:08:23 2015 > @@ -0,0 +1,53 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.commons.io.serialization; > + > +import java.util.regex.Pattern; > + > +/** {@link ClassNameMatcher} that uses regular expressions */ > +final class RegexpClassNameMatcher implements ClassNameMatcher { > + > + private final Pattern pattern; // Class is thread-safe > + > + /** > + * Constructs an object based on the specified regular expression. > + * > + * @param regex a regular expression for evaluating acceptable class > names > + */ > + public RegexpClassNameMatcher(String regex) { > + this(Pattern.compile(regex)); > + } > + > + /** > + * Constructs an object based on the specified pattern. > + * > + * @param pattern a pattern for evaluating acceptable class names > + */ > + public RegexpClassNameMatcher(Pattern pattern) { > + if(pattern == null) { > + throw new IllegalArgumentException("Null pattern"); > + } > + this.pattern = pattern; > + } > + > + @Override > + public boolean matches(String className) { > + return pattern.matcher(className).matches(); > + } > +} > \ No newline at end of file > > Added: > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/ValidatingObjectInputStream.java > URL: > http://svn.apache.org/viewvc/commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/ValidatingObjectInputStream.java?rev=1715217&view=auto > ============================================================================== > --- > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/ValidatingObjectInputStream.java > (added) > +++ > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/ValidatingObjectInputStream.java > Thu Nov 19 17:08:23 2015 > @@ -0,0 +1,194 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.commons.io.serialization; > + > +import java.io.IOException; > +import java.io.InputStream; > +import java.io.InvalidClassException; > +import java.io.ObjectInputStream; > +import java.io.ObjectStreamClass; > +import java.util.ArrayList; > +import java.util.List; > +import java.util.regex.Pattern; > + > +/** > + * <p> > + * An <code>ObjectInputStream</code> that's restricted to deserialize > + * a limited set of classes. > + * </p> > + * > + * <p> > + * Various accept/reject methods allow for specifying which classes > + * can be deserialized. > + * </p> > + * > + * <p> > + * Design inspired by <a > + * href="http://www.ibm.com/developerworks/library/se-lookahead/">IBM > + * DeveloperWorks Article</a>. > + * </p> > + */ > +public class ValidatingObjectInputStream extends ObjectInputStream { > + private final List<ClassNameMatcher> acceptMatchers = new > ArrayList<ClassNameMatcher>(); > + private final List<ClassNameMatcher> rejectMatchers = new > ArrayList<ClassNameMatcher>(); > + > + /** > + * Constructs an object to deserialize the specified input stream. > + * At least one accept method needs to be called to specify which > + * classes can be deserialized, as by default no classes are > + * accepted. > + * > + * @param input an input stream > + * @param acceptor a class acceptor > + * @throws IOException if an I/O error occurs while reading stream header > + */ > + public ValidatingObjectInputStream(InputStream input) throws IOException > { > + super(input); > + } > + > + private void validateClassName(String name) throws InvalidClassException > { > + // Reject has precedence over accept > + for(ClassNameMatcher m : rejectMatchers) { > + if(m.matches(name)) { > + invalidClassNameFound(name); > + } > + } > + > + boolean ok = false; > + for(ClassNameMatcher m : acceptMatchers) { > + if(m.matches(name)) { > + ok = true; > + break; > + } > + } > + if(!ok) { > + invalidClassNameFound(name); > + } > + } > + > + /** Called to throw InvalidClassException (by default) if an invalid > + * class name is found in deserialization. Can be overridden, for > example > + * to log those class names. > + * By default the name of the invalid class is not included in the > + * exception thrown, as that might give too much information from a > + * security point of view. > + * > + * @param className name of the invalid class > + * @throws InvalidClassException > + */ > + protected void invalidClassNameFound(String className) throws > InvalidClassException{ > + throw new InvalidClassException("Class name not accepted"); > + } > + > + @Override > + protected Class<?> resolveClass(ObjectStreamClass osc) throws > IOException, ClassNotFoundException { > + validateClassName(osc.getName()); > + return super.resolveClass(osc); > + } > + > + /** Accept the specified classes for deserialization, unless they > + * are otherwise rejected. > + * @param classes Classes to accept > + * @return this object > + */ > + public ValidatingObjectInputStream accept(Class<?>... classes) { > + for(Class<?> c : classes) { > + acceptMatchers.add(new FullClassNameMatcher(c.getName())); > + } > + return this; > + } > + > + /** Reject the specified classes for deserialization, even if they > + * are otherwise accepted. > + * @param classes Classes to reject > + * @return this object > + */ > + public ValidatingObjectInputStream reject(Class<?>... classes) { > + for(Class<?> c : classes) { > + rejectMatchers.add(new FullClassNameMatcher(c.getName())); > + } > + return this; > + } > + > + /** Accept the wildcard specified classes for deserialization, > + * unless they are otherwise rejected. > + * @param patterns Wildcard filename patterns as defined by > + * {@link FilenameUtils.wildcardMatch} > + * @return this object > + */ > + public ValidatingObjectInputStream accept(String ... patterns) { > + for(String pattern : patterns) { > + acceptMatchers.add(new WildcardClassNameMatcher(pattern)); > + } > + return this; > + } > + > + /** Reject the wildcard specified classes for deserialization, > + * even if they are otherwise accepted. > + * @param patterns Wildcard filename patterns as defined by > + * {@link FilenameUtils.wildcardMatch} > + * @return this object > + */ > + public ValidatingObjectInputStream reject(String ... patterns) { > + for(String pattern : patterns) { > + rejectMatchers.add(new WildcardClassNameMatcher(pattern)); > + } > + return this; > + } > + > + /** Accept class names that match the supplied pattern for > + * deserialization, unless they are otherwise rejected. > + * @param pattern standard Java regexp > + * @return this object > + */ > + public ValidatingObjectInputStream accept(Pattern pattern) { > + acceptMatchers.add(new RegexpClassNameMatcher(pattern)); > + return this; > + } > + > + /** Reject class names that match the supplied pattern for > + * deserialization, even if they are otherwise accepted. > + * @param pattern standard Java regexp > + * @return this object > + */ > + public ValidatingObjectInputStream reject(Pattern pattern) { > + rejectMatchers.add(new RegexpClassNameMatcher(pattern)); > + return this; > + } > + > + /** Accept class names where the supplied ClassNameMatcher matches for > + * deserialization, unless they are otherwise rejected. > + * @param m the matcher to use > + * @return this object > + */ > + public ValidatingObjectInputStream accept(ClassNameMatcher m) { > + acceptMatchers.add(m); > + return this; > + } > + > + /** Reject class names where the supplied ClassNameMatcher matches for > + * deserialization, even if they are otherwise accepted. > + * @param m the matcher to use > + * @return this object > + */ > + public ValidatingObjectInputStream reject(ClassNameMatcher m) { > + rejectMatchers.add(m); > + return this; > + } > +} > \ No newline at end of file > > Added: > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/WildcardClassNameMatcher.java > URL: > http://svn.apache.org/viewvc/commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/WildcardClassNameMatcher.java?rev=1715217&view=auto > ============================================================================== > --- > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/WildcardClassNameMatcher.java > (added) > +++ > commons/proper/io/trunk/src/main/java/org/apache/commons/io/serialization/WildcardClassNameMatcher.java > Thu Nov 19 17:08:23 2015 > @@ -0,0 +1,41 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.commons.io.serialization; > + > +import org.apache.commons.io.FilenameUtils; > + > +/** {@link ClassNameMatcher} that uses simplified regular expressions > + * provided by {@link FilenameUtils#wildcardMatch} */ > +final class WildcardClassNameMatcher implements ClassNameMatcher { > + > + private final String pattern; > + > + /** > + * Constructs an object based on the specified simplified regular > expression. > + * @param regex a {@link FilenameUtils#wildcardMatch} pattern. > + */ > + public WildcardClassNameMatcher(String pattern) { > + this.pattern = pattern; > + } > + > + @Override > + public boolean matches(String className) { > + return FilenameUtils.wildcardMatch(className, pattern); > + } > +} > \ No newline at end of file > > Added: > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/FullClassNameMatcherTest.java > URL: > http://svn.apache.org/viewvc/commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/FullClassNameMatcherTest.java?rev=1715217&view=auto > ============================================================================== > --- > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/FullClassNameMatcherTest.java > (added) > +++ > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/FullClassNameMatcherTest.java > Thu Nov 19 17:08:23 2015 > @@ -0,0 +1,42 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.commons.io.serialization; > + > +import static org.junit.Assert.assertFalse; > +import static org.junit.Assert.assertTrue; > + > +import org.junit.Test; > + > +public class FullClassNameMatcherTest { > + > + private static final String [] NAMES_ARRAY = { Integer.class.getName(), > Long.class.getName() }; > + > + @Test > + public void noNames() throws Exception { > + final FullClassNameMatcher m = new FullClassNameMatcher(); > + assertFalse(m.matches(Integer.class.getName())); > + } > + > + @Test > + public void withNames() throws Exception { > + final FullClassNameMatcher m = new FullClassNameMatcher(NAMES_ARRAY); > + assertTrue(m.matches(Integer.class.getName())); > + assertFalse(m.matches(String.class.getName())); > + } > +} > \ No newline at end of file > > Added: > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/OurTestClass.java > URL: > http://svn.apache.org/viewvc/commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/OurTestClass.java?rev=1715217&view=auto > ============================================================================== > --- > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/OurTestClass.java > (added) > +++ > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/OurTestClass.java > Thu Nov 19 17:08:23 2015 > @@ -0,0 +1,44 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.commons.io.serialization; > + > +import java.io.Serializable; > + > +public class OurTestClass implements Serializable { > + private static final long serialVersionUID = 2139985988735372175L; > + > + private final String str; > + > + OurTestClass(String str) { > + this.str = str; > + } > + > + @Override > + public int hashCode() { > + return str.hashCode(); > + } > + > + @Override > + public boolean equals(Object obj) { > + if(!(obj instanceof OurTestClass)) { > + return false; > + } > + return str.equals(((OurTestClass)obj).str); > + } > +} > \ No newline at end of file > > Added: > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/RegexpClassNameMatcherTest.java > URL: > http://svn.apache.org/viewvc/commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/RegexpClassNameMatcherTest.java?rev=1715217&view=auto > ============================================================================== > --- > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/RegexpClassNameMatcherTest.java > (added) > +++ > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/RegexpClassNameMatcherTest.java > Thu Nov 19 17:08:23 2015 > @@ -0,0 +1,61 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.commons.io.serialization; > + > +import static org.junit.Assert.assertFalse; > +import static org.junit.Assert.assertTrue; > + > +import java.util.regex.Pattern; > + > +import org.junit.Test; > + > +public class RegexpClassNameMatcherTest { > + > + @Test > + public void testSimplePatternFromString() { > + ClassNameMatcher ca = new RegexpClassNameMatcher("foo.*"); > + assertTrue(ca.matches("foo.should.match")); > + assertFalse(ca.matches("bar.should.not.match")); > + } > + > + @Test > + public void testSimplePatternFromPattern() { > + ClassNameMatcher ca = new > RegexpClassNameMatcher(Pattern.compile("foo.*")); > + assertTrue(ca.matches("foo.should.match")); > + assertFalse(ca.matches("bar.should.not.match")); > + } > + > + @Test > + public void testOrPattern() { > + ClassNameMatcher ca = new RegexpClassNameMatcher("foo.*|bar.*"); > + assertTrue(ca.matches("foo.should.match")); > + assertTrue(ca.matches("bar.should.match")); > + assertFalse(ca.matches("zoo.should.not.match")); > + } > + > + @Test(expected=NullPointerException.class) > + public void testNullStringPattern() { > + new RegexpClassNameMatcher((String)null); > + } > + > + @Test(expected=IllegalArgumentException.class) > + public void testNullPatternPattern() { > + new RegexpClassNameMatcher((Pattern)null); > + } > +} > \ No newline at end of file > > Added: > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/ValidatingObjectInputStreamTest.java > URL: > http://svn.apache.org/viewvc/commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/ValidatingObjectInputStreamTest.java?rev=1715217&view=auto > ============================================================================== > --- > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/ValidatingObjectInputStreamTest.java > (added) > +++ > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/ValidatingObjectInputStreamTest.java > Thu Nov 19 17:08:23 2015 > @@ -0,0 +1,231 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.commons.io.serialization; > + > +import static org.junit.Assert.assertEquals; > + > +import java.io.ByteArrayInputStream; > +import java.io.ByteArrayOutputStream; > +import java.io.Closeable; > +import java.io.IOException; > +import java.io.InputStream; > +import java.io.InvalidClassException; > +import java.io.ObjectInputStream; > +import java.io.ObjectOutputStream; > +import java.util.ArrayList; > +import java.util.List; > +import java.util.UUID; > +import java.util.regex.Pattern; > + > +import org.junit.After; > +import org.junit.Before; > +import org.junit.Test; > + > +public class ValidatingObjectInputStreamTest { > + private List<Closeable> toClose; > + private OurTestClass testObject; > + private InputStream testStream; > + > + static private final ClassNameMatcher ALWAYS_TRUE = new > ClassNameMatcher() { > + @Override > + public boolean matches(String className) { > + return true; > + } > + }; > + > + private <T extends Closeable> T willClose(T t) { > + toClose.add(t); > + return t; > + } > + > + @Before > + public void setup() throws IOException { > + toClose = new ArrayList<Closeable>(); > + testObject = new OurTestClass(UUID.randomUUID().toString()); > + final ByteArrayOutputStream bos = willClose(new > ByteArrayOutputStream()); > + final ObjectOutputStream oos = willClose(new > ObjectOutputStream(bos)); > + oos.writeObject(testObject); > + testStream = willClose(new ByteArrayInputStream(bos.toByteArray())); > + } > + > + @After > + public void cleanup() { > + for (Closeable c : toClose) { > + try { > + c.close(); > + } catch (IOException ignored) { > + } > + } > + } > + > + private void assertSerialization(ObjectInputStream ois) throws > ClassNotFoundException, IOException { > + final OurTestClass result = (OurTestClass) (ois.readObject()); > + assertEquals(testObject, result); > + } > + > + @Test(expected = InvalidClassException.class) > + public void noAccept() throws Exception { > + assertSerialization( > + willClose(new ValidatingObjectInputStream(testStream))); > + } > + > + @Test > + public void acceptCustomMatcher() throws Exception { > + assertSerialization( > + willClose(new ValidatingObjectInputStream(testStream)) > + .accept(ALWAYS_TRUE) > + ); > + } > + > + @Test(expected = InvalidClassException.class) > + public void rejectCustomMatcher() throws Exception { > + assertSerialization( > + willClose(new ValidatingObjectInputStream(testStream)) > + .accept(OurTestClass.class) > + .reject(ALWAYS_TRUE) > + ); > + } > + > + @Test > + public void acceptPattern() throws Exception { > + assertSerialization( > + willClose(new ValidatingObjectInputStream(testStream)) > + .accept(Pattern.compile(".*OurTestClass.*")) > + ); > + } > + > + @Test(expected = InvalidClassException.class) > + public void rejectPattern() throws Exception { > + assertSerialization( > + willClose(new ValidatingObjectInputStream(testStream)) > + .accept(OurTestClass.class) > + .reject(Pattern.compile("org.*")) > + ); > + } > + > + @Test > + public void acceptWildcard() throws Exception { > + assertSerialization( > + willClose(new ValidatingObjectInputStream(testStream)) > + .accept("org.apache.commons.io.*") > + ); > + } > + > + @Test(expected = InvalidClassException.class) > + public void rejectWildcard() throws Exception { > + assertSerialization( > + willClose(new ValidatingObjectInputStream(testStream)) > + .accept(OurTestClass.class) > + .reject("org.*") > + ); > + } > + > + @Test(expected = InvalidClassException.class) > + public void ourTestClassNotAccepted() throws Exception { > + assertSerialization( > + willClose(new ValidatingObjectInputStream(testStream)) > + .accept(Integer.class) > + ); > + } > + > + @Test > + public void ourTestClassOnlyAccepted() throws Exception { > + assertSerialization( > + willClose(new ValidatingObjectInputStream(testStream)) > + .accept(OurTestClass.class) > + ); > + } > + > + @Test > + public void ourTestClassAcceptedFirst() throws Exception { > + assertSerialization( > + willClose(new ValidatingObjectInputStream(testStream)) > + .accept(OurTestClass.class, Integer.class) > + ); > + } > + > + @Test > + public void ourTestClassAcceptedSecond() throws Exception { > + assertSerialization( > + willClose(new ValidatingObjectInputStream(testStream)) > + .accept(Integer.class, OurTestClass.class) > + ); > + } > + > + @Test > + public void ourTestClassAcceptedFirstWildcard() throws Exception { > + assertSerialization( > + willClose(new ValidatingObjectInputStream(testStream)) > + .accept("*OurTestClass","*Integer") > + ); > + } > + > + @Test > + public void ourTestClassAcceptedSecondWildcard() throws Exception { > + assertSerialization( > + willClose(new ValidatingObjectInputStream(testStream)) > + .accept("*Integer","*OurTestClass") > + ); > + } > + > + @Test(expected = InvalidClassException.class) > + public void reject() throws Exception { > + assertSerialization( > + willClose(new ValidatingObjectInputStream(testStream)) > + .accept(Long.class) > + .reject(OurTestClass.class, Integer.class) > + ); > + } > + > + @Test(expected = InvalidClassException.class) > + public void rejectPrecedence() throws Exception { > + assertSerialization( > + willClose(new ValidatingObjectInputStream(testStream)) > + .accept(OurTestClass.class) > + .reject(OurTestClass.class, Integer.class) > + ); > + } > + > + @Test(expected = InvalidClassException.class) > + public void rejectOnly() throws Exception { > + assertSerialization( > + willClose(new ValidatingObjectInputStream(testStream)) > + .reject(Integer.class) > + ); > + } > + > + @Test(expected = RuntimeException.class) > + public void customInvalidMethod() throws Exception { > + class CustomVOIS extends ValidatingObjectInputStream { > + CustomVOIS(InputStream is) throws IOException { > + super(is); > + } > + > + @Override > + protected void invalidClassNameFound(String className) throws > InvalidClassException { > + throw new RuntimeException("Custom exception"); > + } > + }; > + > + assertSerialization( > + willClose(new CustomVOIS(testStream)) > + .reject(Integer.class) > + ); > + } > +} > \ No newline at end of file > > Added: > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/WildcardClassNameMatcherTest.java > URL: > http://svn.apache.org/viewvc/commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/WildcardClassNameMatcherTest.java?rev=1715217&view=auto > ============================================================================== > --- > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/WildcardClassNameMatcherTest.java > (added) > +++ > commons/proper/io/trunk/src/test/java/org/apache/commons/io/serialization/WildcardClassNameMatcherTest.java > Thu Nov 19 17:08:23 2015 > @@ -0,0 +1,50 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.commons.io.serialization; > + > +import static org.junit.Assert.assertFalse; > +import static org.junit.Assert.assertTrue; > + > +import org.junit.Test; > + > +public class WildcardClassNameMatcherTest { > + > + @Test > + public void noPattern() { > + ClassNameMatcher ca = new WildcardClassNameMatcher("org.foo"); > + assertTrue(ca.matches("org.foo")); > + assertFalse(ca.matches("org.foo.and.more")); > + assertFalse(ca.matches("org_foo")); > + } > + > + @Test > + public void star() { > + ClassNameMatcher ca = new WildcardClassNameMatcher("org*"); > + assertTrue(ca.matches("org.foo.should.match")); > + assertFalse(ca.matches("bar.should.not.match")); > + } > + > + @Test > + public void starAndQuestionMark() { > + ClassNameMatcher ca = new > WildcardClassNameMatcher("org?apache?something*"); > + assertTrue(ca.matches("org.apache_something.more")); > + assertFalse(ca.matches("org..apache_something.more")); > + } > + > +} > \ No newline at end of file > > --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org