From dab4edb24e0e2219e5a363bb26642db5e230c0d0 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sun, 24 Jul 2016 15:11:49 +0200 Subject: [PATCH] inputdataoperation: Only consider data MIME if Content-Type header is present --- .../operations/InputDataOperation.java | 9 ++++-- .../keychain/pgp/InputDataOperationTest.java | 29 +++++++++++++++++-- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/InputDataOperation.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/InputDataOperation.java index 6682cc6e7..68220857b 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/InputDataOperation.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/InputDataOperation.java @@ -35,6 +35,7 @@ import android.webkit.MimeTypeMap; import org.apache.james.mime4j.MimeException; import org.apache.james.mime4j.codec.DecodeMonitor; import org.apache.james.mime4j.dom.field.ContentDispositionField; +import org.apache.james.mime4j.dom.field.ContentTypeField; import org.apache.james.mime4j.field.DefaultFieldParser; import org.apache.james.mime4j.parser.AbstractContentHandler; import org.apache.james.mime4j.parser.MimeStreamParser; @@ -166,7 +167,7 @@ public class InputDataOperation extends BaseOperation { parser.setContentDecoding(true); parser.setRecurse(); parser.setContentHandler(new AbstractContentHandler() { - private boolean mFoundHeaderWithFields = false; + private boolean mFoundContentTypeHeader = false; private Uri uncheckedSignedDataUri; String mFilename; @@ -224,7 +225,7 @@ public class InputDataOperation extends BaseOperation { @Override public void endHeader() throws MimeException { - if ( ! mFoundHeaderWithFields) { + if (!mFoundContentTypeHeader) { parser.stop(); } } @@ -235,7 +236,9 @@ public class InputDataOperation extends BaseOperation { if (field instanceof ContentDispositionField) { mFilename = ((ContentDispositionField) field).getFilename(); } - mFoundHeaderWithFields = true; + if (field instanceof ContentTypeField) { + mFoundContentTypeHeader = true; + } } private void bodySignature(BodyDescriptor bd, InputStream is) throws MimeException, IOException { diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/InputDataOperationTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/InputDataOperationTest.java index fba8be061..01a425af6 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/InputDataOperationTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/pgp/InputDataOperationTest.java @@ -62,6 +62,7 @@ import static org.mockito.Mockito.when; @Config(constants = WorkaroundBuildConfig.class, sdk = 21, manifest = "src/main/AndroidManifest.xml") public class InputDataOperationTest { + public static final Uri FAKE_CONTENT_INPUT_URI_1 = Uri.parse("content://fake/1"); static PrintStream oldShadowStream; @BeforeClass @@ -263,6 +264,29 @@ public class InputDataOperationTest { result.getLog().containsType(LogType.MSG_DATA_MIME_CHARSET_GUESS)); } + @Test + public void testMimeDecodingWithNoContentTypeHeader() throws Exception { + + String mimeContent = "Some-Header: dummy\n" + + "\n" + + "some message text\n"; + + InputDataResult result = runSimpleDataInputOperation(mimeContent.getBytes()); + + // must be successful, no verification, have two output URIs + Assert.assertTrue(result.success()); + Assert.assertNull(result.mDecryptVerifyResult); + + OpenPgpMetadata metadata = result.mMetadata.get(0); + Assert.assertNull(null, metadata.getMimeType()); + + Assert.assertTrue("should not be mime parsed", + result.getLog().containsType(LogType.MSG_DATA_MIME_NONE)); + + Assert.assertEquals("output uri should simply be passed-through input uri", + result.getOutputUris().get(0), FAKE_CONTENT_INPUT_URI_1); + } + private InputDataResult runSimpleDataInputOperation(byte[] mimeContentBytes) throws FileNotFoundException { ByteArrayOutputStream outStream1 = new ByteArrayOutputStream(); ByteArrayOutputStream outStream2 = new ByteArrayOutputStream(); @@ -273,8 +297,7 @@ public class InputDataOperationTest { .thenReturn(outStream1, outStream2); // fake openInputStream - Uri fakeInputUri = Uri.parse("content://fake/1"); - when(mockResolver.openInputStream(fakeInputUri)).thenReturn( + when(mockResolver.openInputStream(FAKE_CONTENT_INPUT_URI_1)).thenReturn( new ByteArrayInputStream(mimeContentBytes)); Uri fakeOutputUri1 = Uri.parse("content://fake/out/1"); @@ -288,7 +311,7 @@ public class InputDataOperationTest { InputDataOperation op = new InputDataOperation(spyApplication, new ProviderHelper(RuntimeEnvironment.application), null); - InputDataParcel input = new InputDataParcel(fakeInputUri, null); + InputDataParcel input = new InputDataParcel(FAKE_CONTENT_INPUT_URI_1, null); return op.execute(input, new CryptoInputParcel()); }