get rid of RuntimeException control flow in UncachedKeyRing.fromStream

This commit is contained in:
Vincent Breitmoser 2015-01-02 02:05:12 +01:00
parent b52fb90380
commit 56f2a3137b
4 changed files with 25 additions and 34 deletions

View File

@ -33,6 +33,7 @@ import org.sufficientlysecure.keychain.operations.results.OperationResult.Operat
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing;
import org.sufficientlysecure.keychain.pgp.PgpKeyOperation; import org.sufficientlysecure.keychain.pgp.PgpKeyOperation;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow;
import org.sufficientlysecure.keychain.pgp.WrappedSignature; import org.sufficientlysecure.keychain.pgp.WrappedSignature;
import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
@ -141,7 +142,7 @@ public class ExportTest {
masterKeyId1 = mStaticRing2.getMasterKeyId(); masterKeyId1 = mStaticRing2.getMasterKeyId();
} }
Iterator<UncachedKeyRing> unc = IteratorWithIOThrow<UncachedKeyRing> unc =
UncachedKeyRing.fromStream(new ByteArrayInputStream(out.toByteArray())); UncachedKeyRing.fromStream(new ByteArrayInputStream(out.toByteArray()));
{ {

View File

@ -27,6 +27,7 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadows.ShadowLog; import org.robolectric.shadows.ShadowLog;
import org.spongycastle.bcpg.sig.KeyFlags; import org.spongycastle.bcpg.sig.KeyFlags;
import org.sufficientlysecure.keychain.operations.results.EditKeyResult; import org.sufficientlysecure.keychain.operations.results.EditKeyResult;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
@ -110,7 +111,7 @@ public class UncachedKeyringTest {
ring.encodeArmored(out, "OpenKeychain"); ring.encodeArmored(out, "OpenKeychain");
pubRing.encodeArmored(out, "OpenKeychain"); pubRing.encodeArmored(out, "OpenKeychain");
Iterator<UncachedKeyRing> it = IteratorWithIOThrow<UncachedKeyRing> it =
UncachedKeyRing.fromStream(new ByteArrayInputStream(out.toByteArray())); UncachedKeyRing.fromStream(new ByteArrayInputStream(out.toByteArray()));
Assert.assertTrue("there should be two rings in the stream", it.hasNext()); Assert.assertTrue("there should be two rings in the stream", it.hasNext());
Assert.assertArrayEquals("first ring should be the first we put in", Assert.assertArrayEquals("first ring should be the first we put in",
@ -139,11 +140,7 @@ public class UncachedKeyringTest {
} }
UncachedKeyRing readRingFromResource(String name) throws Throwable { UncachedKeyRing readRingFromResource(String name) throws Throwable {
try { return UncachedKeyRing.fromStream(UncachedKeyringTest.class.getResourceAsStream(name)).next();
return UncachedKeyRing.fromStream(UncachedKeyringTest.class.getResourceAsStream(name)).next();
} catch (RuntimeException e) {
throw e.getCause();
}
} }
} }

View File

@ -137,35 +137,30 @@ public class UncachedKeyRing {
public static UncachedKeyRing decodeFromData(byte[] data) public static UncachedKeyRing decodeFromData(byte[] data)
throws PgpGeneralException, IOException { throws PgpGeneralException, IOException {
Iterator<UncachedKeyRing> parsed = fromStream(new ByteArrayInputStream(data)); IteratorWithIOThrow<UncachedKeyRing> parsed = fromStream(new ByteArrayInputStream(data));
if ( ! parsed.hasNext()) { if ( ! parsed.hasNext()) {
throw new PgpGeneralException("Object not recognized as PGPKeyRing!"); throw new PgpGeneralException("Object not recognized as PGPKeyRing!");
} }
try { UncachedKeyRing ring = parsed.next();
UncachedKeyRing ring = parsed.next();
if (parsed.hasNext()) { if (parsed.hasNext()) {
throw new PgpGeneralException("Expected single keyring in stream, found at least two"); throw new PgpGeneralException("Expected single keyring in stream, found at least two");
}
return ring;
} catch (RuntimeException e) {
// yes this is bad style. we should rework this in a better way
throw new PgpGeneralException(e.getCause());
} }
return ring;
} }
public static Iterator<UncachedKeyRing> fromStream(final InputStream stream) { public static IteratorWithIOThrow<UncachedKeyRing> fromStream(final InputStream stream) {
return new Iterator<UncachedKeyRing>() { return new IteratorWithIOThrow<UncachedKeyRing>() {
UncachedKeyRing mNext = null; UncachedKeyRing mNext = null;
PGPObjectFactory mObjectFactory = null; PGPObjectFactory mObjectFactory = null;
private void cacheNext() { private void cacheNext() throws IOException {
if (mNext != null) { if (mNext != null) {
return; return;
} }
@ -194,22 +189,19 @@ public class UncachedKeyRing {
// if we are past the while loop, that means the objectFactory had no next // if we are past the while loop, that means the objectFactory had no next
mObjectFactory = null; mObjectFactory = null;
} }
} catch (IOException e) {
throw new RuntimeException(e);
// Log.e(Constants.TAG, "IOException while processing stream. ArmoredInputStream CRC check failed?", e);
} catch (ArrayIndexOutOfBoundsException e) { } catch (ArrayIndexOutOfBoundsException e) {
Log.e(Constants.TAG, "ArmoredInputStream decode failed, symbol is not in decodingTable!", e); throw new IOException(e);
} }
} }
@Override @Override
public boolean hasNext() { public boolean hasNext() throws IOException {
cacheNext(); cacheNext();
return mNext != null; return mNext != null;
} }
@Override @Override
public UncachedKeyRing next() { public UncachedKeyRing next() throws IOException {
try { try {
cacheNext(); cacheNext();
return mNext; return mNext;
@ -217,15 +209,15 @@ public class UncachedKeyRing {
mNext = null; mNext = null;
} }
} }
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}; };
} }
public interface IteratorWithIOThrow<E> {
public boolean hasNext() throws IOException;
public E next() throws IOException;
}
public void encodeArmored(OutputStream out, String version) throws IOException { public void encodeArmored(OutputStream out, String version) throws IOException {
ArmoredOutputStream aos = new ArmoredOutputStream(out); ArmoredOutputStream aos = new ArmoredOutputStream(out);
if (version != null) { if (version != null) {

View File

@ -27,6 +27,7 @@ import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.operations.results.GetKeyResult; import org.sufficientlysecure.keychain.operations.results.GetKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing.IteratorWithIOThrow;
import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.PositionAwareInputStream; import org.sufficientlysecure.keychain.util.PositionAwareInputStream;
@ -127,7 +128,7 @@ public class ImportKeysListLoader
BufferedInputStream bufferedInput = new BufferedInputStream(progressIn); BufferedInputStream bufferedInput = new BufferedInputStream(progressIn);
try { try {
// parse all keyrings // parse all keyrings
Iterator<UncachedKeyRing> it = UncachedKeyRing.fromStream(bufferedInput); IteratorWithIOThrow<UncachedKeyRing> it = UncachedKeyRing.fromStream(bufferedInput);
while (it.hasNext()) { while (it.hasNext()) {
UncachedKeyRing ring = it.next(); UncachedKeyRing ring = it.next();
ImportKeysListEntry item = new ImportKeysListEntry(getContext(), ring); ImportKeysListEntry item = new ImportKeysListEntry(getContext(), ring);