/** Trusting java.lang.* and the array variants of that means we have * to define a number of accept classes explicitly. Quite safe but * might become a bit verbose. */ @Test public void trustJavaLang() throws IOException, ClassNotFoundException { assertSerialization(willClose( new ValidatingObjectInputStream(inputStream) .accept(MoreComplexObject.class, ArrayList.class, Random.class) .accept("java.lang.*","[Ljava.lang.*") )); }
/** Check that the classname conforms to requirements. * @param name The class name * @throws InvalidClassException when a non-accepted class is encountered */ private void validateClassName(final String name) throws InvalidClassException { // Reject has precedence over accept for (final ClassNameMatcher m : rejectMatchers) { if (m.matches(name)) { invalidClassNameFound(name); } } boolean ok = false; for (final ClassNameMatcher m : acceptMatchers) { if (m.matches(name)) { ok = true; break; } } if (!ok) { invalidClassNameFound(name); } }
@Override protected Class<?> resolveClass(final ObjectStreamClass osc) throws IOException, ClassNotFoundException { validateClassName(osc.getName()); return super.resolveClass(osc); }
@Test(expected = InvalidClassException.class) public void rejectPrecedence() throws Exception { assertSerialization( willClose(new ValidatingObjectInputStream(testStream)) .accept(MockSerializedClass.class) .reject(MockSerializedClass.class, Integer.class) ); }
@Test(expected = InvalidClassException.class) public void rejectOnly() throws Exception { assertSerialization( willClose(new ValidatingObjectInputStream(testStream)) .reject(Integer.class) ); }
/** * Deserialize list * @param in Input stream * @param <T> Class * @throws IOException Error accessing to IO * @throws ClassNotFoundException Class not found */ public static <T> Map<String, T> readMap(ObjectInputStream in, Class<T> clazz) throws IOException, ClassNotFoundException { int size = in.readInt(); ValidatingObjectInputStream inputStream = new ValidatingObjectInputStream(in); inputStream.accept(clazz); Map<String, T> map = null; if (size >= 0) { map = new HashMap<>(); for (int i = 0; i < size; i++) { map.put((String) inputStream.readObject(), clazz.cast(inputStream.readObject())); } } return map; } }
ValidatingObjectInputStream objectInputStream = new ValidatingObjectInputStream( inputStream ); objectInputStream.accept( MailItem.class, ArrayList.class, byte [ ].class, FileAttachment.class, UrlAttachment.class, FileAttachment [ ].class, UrlAttachment [ ].class, URL.class ); mailItem = (MailItem) objectInputStream.readObject( ); objectInputStream.close( );
@Test(expected = InvalidClassException.class) public void noAccept() throws Exception { assertSerialization( willClose(new ValidatingObjectInputStream(testStream))); }
/** * Deserialize list * @param in Input stream * @param <T> Class * @throws IOException Error accessing to IO * @throws ClassNotFoundException Class not found */ public static <T> List<T> readList(ObjectInputStream in, Class<T> clazz) throws IOException, ClassNotFoundException { int size = in.readInt(); ValidatingObjectInputStream inputStream = new ValidatingObjectInputStream(in); inputStream.accept(clazz); List<T> list = null; if (size >= 0) { list = new ArrayList<>(); for (int i = 0; i < size; i++) { list.add(clazz.cast(inputStream.readObject())); } } return list; }
@Test(expected = InvalidClassException.class) public void rejectPattern() throws Exception { assertSerialization( willClose(new ValidatingObjectInputStream(testStream)) .accept(MockSerializedClass.class) .reject(Pattern.compile("org.*")) ); }
@Test public void exceptionIncludesClassName() throws Exception { try { assertSerialization( willClose(new ValidatingObjectInputStream(testStream))); fail("Expected an InvalidClassException"); } catch(final InvalidClassException ice) { final String name = MockSerializedClass.class.getName(); assertTrue("Expecting message to contain " + name, ice.getMessage().contains(name)); } }
try(ValidatingObjectInputStream vois = new ValidatingObjectInputStream(bais) vois.accept( AggregationState.class, AverageState.class, org.eclipse.rdf4j.query.AbstractBindingSet.class ); vois.accept("[B"); // Array of Bytes final Object o = vois.readObject(); if(o instanceof AggregationState) { state = (AggregationState)o;
/** Trusting java.* is probably reasonable and avoids having to be too * detailed in the accepts. */ @Test public void trustJavaIncludingArrays() throws IOException, ClassNotFoundException { assertSerialization(willClose( new ValidatingObjectInputStream(inputStream) .accept(MoreComplexObject.class) .accept("java.*","[Ljava.*") )); }
@Test(expected = InvalidClassException.class) public void reject() throws Exception { assertSerialization( willClose(new ValidatingObjectInputStream(testStream)) .accept(Long.class) .reject(MockSerializedClass.class, Integer.class) ); }
@Override protected Class<?> resolveClass(final ObjectStreamClass osc) throws IOException, ClassNotFoundException { validateClassName(osc.getName()); return super.resolveClass(osc); }
/** Check that the classname conforms to requirements. * @param name The class name * @throws InvalidClassException when a non-accepted class is encountered */ 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); } }
try(ValidatingObjectInputStream vois = new ValidatingObjectInputStream(bais) vois.accept(AggregationState.class, AverageState.class, java.util.HashMap.class, org.openrdf.model.impl.DecimalLiteralImpl.class, org.openrdf.model.impl.IntegerLiteralImpl.class); vois.accept("[B"); // Array of Bytes final Object o = vois.readObject(); if(o instanceof AggregationState) { state = (AggregationState)o;
@Test public void ourTestClassOnlyAccepted() throws Exception { assertSerialization( willClose(new ValidatingObjectInputStream(testStream)) .accept(MockSerializedClass.class) ); }
@Test(expected = InvalidClassException.class) public void rejectCustomMatcher() throws Exception { assertSerialization( willClose(new ValidatingObjectInputStream(testStream)) .accept(MockSerializedClass.class) .reject(ALWAYS_TRUE) ); }
@Override protected Class<?> resolveClass(ObjectStreamClass osc) throws IOException, ClassNotFoundException { validateClassName(osc.getName()); return super.resolveClass(osc); }