inputdataoperation: Only consider data MIME if Content-Type header is present

This commit is contained in:
Vincent Breitmoser
2016-07-24 15:11:49 +02:00
parent 166ac9832b
commit dab4edb24e
2 changed files with 32 additions and 6 deletions

View File

@@ -35,6 +35,7 @@ import android.webkit.MimeTypeMap;
import org.apache.james.mime4j.MimeException; import org.apache.james.mime4j.MimeException;
import org.apache.james.mime4j.codec.DecodeMonitor; import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.dom.field.ContentDispositionField; 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.field.DefaultFieldParser;
import org.apache.james.mime4j.parser.AbstractContentHandler; import org.apache.james.mime4j.parser.AbstractContentHandler;
import org.apache.james.mime4j.parser.MimeStreamParser; import org.apache.james.mime4j.parser.MimeStreamParser;
@@ -166,7 +167,7 @@ public class InputDataOperation extends BaseOperation<InputDataParcel> {
parser.setContentDecoding(true); parser.setContentDecoding(true);
parser.setRecurse(); parser.setRecurse();
parser.setContentHandler(new AbstractContentHandler() { parser.setContentHandler(new AbstractContentHandler() {
private boolean mFoundHeaderWithFields = false; private boolean mFoundContentTypeHeader = false;
private Uri uncheckedSignedDataUri; private Uri uncheckedSignedDataUri;
String mFilename; String mFilename;
@@ -224,7 +225,7 @@ public class InputDataOperation extends BaseOperation<InputDataParcel> {
@Override @Override
public void endHeader() throws MimeException { public void endHeader() throws MimeException {
if ( ! mFoundHeaderWithFields) { if (!mFoundContentTypeHeader) {
parser.stop(); parser.stop();
} }
} }
@@ -235,7 +236,9 @@ public class InputDataOperation extends BaseOperation<InputDataParcel> {
if (field instanceof ContentDispositionField) { if (field instanceof ContentDispositionField) {
mFilename = ((ContentDispositionField) field).getFilename(); mFilename = ((ContentDispositionField) field).getFilename();
} }
mFoundHeaderWithFields = true; if (field instanceof ContentTypeField) {
mFoundContentTypeHeader = true;
}
} }
private void bodySignature(BodyDescriptor bd, InputStream is) throws MimeException, IOException { private void bodySignature(BodyDescriptor bd, InputStream is) throws MimeException, IOException {

View File

@@ -62,6 +62,7 @@ import static org.mockito.Mockito.when;
@Config(constants = WorkaroundBuildConfig.class, sdk = 21, manifest = "src/main/AndroidManifest.xml") @Config(constants = WorkaroundBuildConfig.class, sdk = 21, manifest = "src/main/AndroidManifest.xml")
public class InputDataOperationTest { public class InputDataOperationTest {
public static final Uri FAKE_CONTENT_INPUT_URI_1 = Uri.parse("content://fake/1");
static PrintStream oldShadowStream; static PrintStream oldShadowStream;
@BeforeClass @BeforeClass
@@ -263,6 +264,29 @@ public class InputDataOperationTest {
result.getLog().containsType(LogType.MSG_DATA_MIME_CHARSET_GUESS)); 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 { private InputDataResult runSimpleDataInputOperation(byte[] mimeContentBytes) throws FileNotFoundException {
ByteArrayOutputStream outStream1 = new ByteArrayOutputStream(); ByteArrayOutputStream outStream1 = new ByteArrayOutputStream();
ByteArrayOutputStream outStream2 = new ByteArrayOutputStream(); ByteArrayOutputStream outStream2 = new ByteArrayOutputStream();
@@ -273,8 +297,7 @@ public class InputDataOperationTest {
.thenReturn(outStream1, outStream2); .thenReturn(outStream1, outStream2);
// fake openInputStream // fake openInputStream
Uri fakeInputUri = Uri.parse("content://fake/1"); when(mockResolver.openInputStream(FAKE_CONTENT_INPUT_URI_1)).thenReturn(
when(mockResolver.openInputStream(fakeInputUri)).thenReturn(
new ByteArrayInputStream(mimeContentBytes)); new ByteArrayInputStream(mimeContentBytes));
Uri fakeOutputUri1 = Uri.parse("content://fake/out/1"); Uri fakeOutputUri1 = Uri.parse("content://fake/out/1");
@@ -288,7 +311,7 @@ public class InputDataOperationTest {
InputDataOperation op = new InputDataOperation(spyApplication, InputDataOperation op = new InputDataOperation(spyApplication,
new ProviderHelper(RuntimeEnvironment.application), null); 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()); return op.execute(input, new CryptoInputParcel());
} }