Catch ClassCastException when the encountered type doesn't match the

expected type, and re-throw as FormatException.
This commit is contained in:
akwizgran
2011-07-20 15:07:17 +01:00
parent 30d7a0f916
commit 45b4bef348
4 changed files with 47 additions and 10 deletions

View File

@@ -66,6 +66,6 @@ public interface Reader {
boolean hasUserDefinedTag() throws IOException; boolean hasUserDefinedTag() throws IOException;
int readUserDefinedTag() throws IOException; int readUserDefinedTag() throws IOException;
void readUserDefinedTag(int tag) throws IOException; void readUserDefinedTag(int tag) throws IOException;
<T> T readUserDefinedObject(int tag) throws IOException, <T> T readUserDefinedObject(int tag, Class<T> t) throws IOException,
GeneralSecurityException; GeneralSecurityException;
} }

View File

@@ -31,7 +31,7 @@ class BundleReaderImpl implements BundleReader {
if(state != State.START) throw new IllegalStateException(); if(state != State.START) throw new IllegalStateException();
reader.addObjectReader(Tags.HEADER, headerReader); reader.addObjectReader(Tags.HEADER, headerReader);
reader.readUserDefinedTag(Tags.HEADER); reader.readUserDefinedTag(Tags.HEADER);
Header h = reader.readUserDefinedObject(Tags.HEADER); Header h = reader.readUserDefinedObject(Tags.HEADER, Header.class);
reader.removeObjectReader(Tags.HEADER); reader.removeObjectReader(Tags.HEADER);
state = State.FIRST_BATCH; state = State.FIRST_BATCH;
return h; return h;
@@ -53,7 +53,7 @@ class BundleReaderImpl implements BundleReader {
return null; return null;
} }
reader.readUserDefinedTag(Tags.BATCH); reader.readUserDefinedTag(Tags.BATCH);
return reader.readUserDefinedObject(Tags.BATCH); return reader.readUserDefinedObject(Tags.BATCH, Batch.class);
} }
public void finish() throws IOException { public void finish() throws IOException {

View File

@@ -386,11 +386,10 @@ class ReaderImpl implements Reader {
throw new FormatException(); throw new FormatException();
} }
@SuppressWarnings("unchecked")
private <T> T readObject(Class<T> t) throws IOException, private <T> T readObject(Class<T> t) throws IOException,
GeneralSecurityException { GeneralSecurityException {
try { try {
return (T) readObject(); return t.cast(readObject());
} catch(ClassCastException e) { } catch(ClassCastException e) {
throw new FormatException(); throw new FormatException();
} }
@@ -507,14 +506,12 @@ class ReaderImpl implements Reader {
if(readUserDefinedTag() != tag) throw new FormatException(); if(readUserDefinedTag() != tag) throw new FormatException();
} }
public <T> T readUserDefinedObject(int tag) throws IOException, public <T> T readUserDefinedObject(int tag, Class<T> t) throws IOException,
GeneralSecurityException { GeneralSecurityException {
ObjectReader<?> o = objectReaders.get(tag); ObjectReader<?> o = objectReaders.get(tag);
if(o == null) throw new FormatException(); if(o == null) throw new FormatException();
try { try {
@SuppressWarnings("unchecked") return t.cast(o.readObject(this));
ObjectReader<T> cast = (ObjectReader<T>) o;
return cast.readObject(this);
} catch(ClassCastException e) { } catch(ClassCastException e) {
throw new FormatException(); throw new FormatException();
} }

View File

@@ -8,6 +8,7 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import junit.framework.TestCase; import junit.framework.TestCase;
import net.sf.briar.api.serial.FormatException;
import net.sf.briar.api.serial.ObjectReader; import net.sf.briar.api.serial.ObjectReader;
import net.sf.briar.api.serial.Raw; import net.sf.briar.api.serial.Raw;
import net.sf.briar.api.serial.RawByteArray; import net.sf.briar.api.serial.RawByteArray;
@@ -176,6 +177,17 @@ public class ReaderImplTest extends TestCase {
assertTrue(r.eof()); assertTrue(r.eof());
} }
@Test
public void testReadListTypeSafeThrowsFormatException() throws Exception {
setContents("A" + "3" + "01" + "83666F6F" + "03");
// Trying to read a mixed list as a list of bytes should throw a
// FormatException
try {
r.readList(Byte.class);
assertTrue(false);
} catch(FormatException expected) {}
}
@Test @Test
public void testReadShortMap() throws Exception { public void testReadShortMap() throws Exception {
setContents("B" + "2" + "83666F6F" + "7B" + "90" + "F0"); setContents("B" + "2" + "83666F6F" + "7B" + "90" + "F0");
@@ -338,7 +350,35 @@ public class ReaderImplTest extends TestCase {
} }
}); });
assertEquals(0, r.readUserDefinedTag()); assertEquals(0, r.readUserDefinedTag());
assertEquals("foo", r.<Foo>readUserDefinedObject(0).s); assertEquals("foo", r.readUserDefinedObject(0, Foo.class).s);
}
@Test
public void testUnknownTagThrowsFormatException() throws Exception {
setContents("C0" + "83666F6F");
// No object reader has been added for tag 0
assertEquals(0, r.readUserDefinedTag());
try {
r.readUserDefinedObject(0, Foo.class);
assertTrue(false);
} catch(FormatException expected) {}
}
@Test
public void testWrongClassThrowsFormatException() throws Exception {
setContents("C0" + "83666F6F");
// Add an object reader for tag 0, class Foo
r.addObjectReader(0, new ObjectReader<Foo>() {
public Foo readObject(Reader r) throws IOException {
return new Foo(r.readString());
}
});
assertEquals(0, r.readUserDefinedTag());
// Trying to read the object as class Bar should throw a FormatException
try {
r.readUserDefinedObject(0, Bar.class);
assertTrue(false);
} catch(FormatException expected) {}
} }
@Test @Test