mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-19 06:09:55 +01:00
[android] reject invalid mime types for image attachments
This commit is contained in:
@@ -44,6 +44,7 @@ import static org.briarproject.bramble.util.IoUtils.tryToClose;
|
|||||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.LogUtils.now;
|
import static org.briarproject.bramble.util.LogUtils.now;
|
||||||
|
import static org.briarproject.briar.api.messaging.MessagingConstants.IMAGE_MIME_TYPES;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class AttachmentController {
|
class AttachmentController {
|
||||||
@@ -146,6 +147,14 @@ class AttachmentController {
|
|||||||
unsentItems.put(uri, item);
|
unsentItems.put(uri, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isValidMimeType(@Nullable String mimeType) {
|
||||||
|
if (mimeType == null) return false;
|
||||||
|
for (String supportedType : IMAGE_MIME_TYPES) {
|
||||||
|
if (supportedType.equals(mimeType)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@DatabaseExecutor
|
@DatabaseExecutor
|
||||||
void deleteUnsentAttachments() {
|
void deleteUnsentAttachments() {
|
||||||
for (AttachmentItem item : unsentItems.values()) {
|
for (AttachmentItem item : unsentItems.values()) {
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ public class ConversationViewModel extends AndroidViewModel implements
|
|||||||
@CryptoExecutor
|
@CryptoExecutor
|
||||||
private final Executor cryptoExecutor;
|
private final Executor cryptoExecutor;
|
||||||
private final TransactionManager db;
|
private final TransactionManager db;
|
||||||
private final AndroidExecutor androidExecutor;
|
|
||||||
private final MessagingManager messagingManager;
|
private final MessagingManager messagingManager;
|
||||||
private final ContactManager contactManager;
|
private final ContactManager contactManager;
|
||||||
private final SettingsManager settingsManager;
|
private final SettingsManager settingsManager;
|
||||||
@@ -107,13 +106,12 @@ public class ConversationViewModel extends AndroidViewModel implements
|
|||||||
ConversationViewModel(Application application,
|
ConversationViewModel(Application application,
|
||||||
@DatabaseExecutor Executor dbExecutor,
|
@DatabaseExecutor Executor dbExecutor,
|
||||||
@CryptoExecutor Executor cryptoExecutor, TransactionManager db,
|
@CryptoExecutor Executor cryptoExecutor, TransactionManager db,
|
||||||
AndroidExecutor androidExecutor, MessagingManager messagingManager,
|
MessagingManager messagingManager, ContactManager contactManager,
|
||||||
ContactManager contactManager, SettingsManager settingsManager,
|
SettingsManager settingsManager,
|
||||||
PrivateMessageFactory privateMessageFactory) {
|
PrivateMessageFactory privateMessageFactory) {
|
||||||
super(application);
|
super(application);
|
||||||
this.dbExecutor = dbExecutor;
|
this.dbExecutor = dbExecutor;
|
||||||
this.cryptoExecutor = cryptoExecutor;
|
this.cryptoExecutor = cryptoExecutor;
|
||||||
this.androidExecutor = androidExecutor;
|
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.messagingManager = messagingManager;
|
this.messagingManager = messagingManager;
|
||||||
this.contactManager = contactManager;
|
this.contactManager = contactManager;
|
||||||
@@ -197,16 +195,24 @@ public class ConversationViewModel extends AndroidViewModel implements
|
|||||||
@Override
|
@Override
|
||||||
public LiveData<AttachmentResult> storeAttachment(Uri uri,
|
public LiveData<AttachmentResult> storeAttachment(Uri uri,
|
||||||
boolean needsSize) {
|
boolean needsSize) {
|
||||||
if (messagingGroupId.getValue() == null) loadGroupId();
|
|
||||||
// use LiveData to not keep references to view scope
|
// use LiveData to not keep references to view scope
|
||||||
MutableLiveData<AttachmentResult> result = new MutableLiveData<>();
|
MutableLiveData<AttachmentResult> result = new MutableLiveData<>();
|
||||||
|
// check first if mime type is supported
|
||||||
|
ContentResolver contentResolver =
|
||||||
|
getApplication().getContentResolver();
|
||||||
|
String mimeType = contentResolver.getType(uri);
|
||||||
|
if (!attachmentController.isValidMimeType(mimeType)) {
|
||||||
|
String errorMsg = getApplication().getString(
|
||||||
|
R.string.image_attach_error_invalid_mime_type, mimeType);
|
||||||
|
result.setValue(new AttachmentResult(errorMsg));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (messagingGroupId.getValue() == null) loadGroupId();
|
||||||
observeForeverOnce(messagingGroupId, groupId -> dbExecutor.execute(()
|
observeForeverOnce(messagingGroupId, groupId -> dbExecutor.execute(()
|
||||||
-> {
|
-> {
|
||||||
if (groupId == null) throw new IllegalStateException();
|
if (groupId == null) throw new IllegalStateException();
|
||||||
long start = now();
|
long start = now();
|
||||||
try {
|
try {
|
||||||
ContentResolver contentResolver =
|
|
||||||
getApplication().getContentResolver();
|
|
||||||
attachmentController.createAttachmentHeader(contentResolver,
|
attachmentController.createAttachmentHeader(contentResolver,
|
||||||
groupId, uri, needsSize);
|
groupId, uri, needsSize);
|
||||||
result.postValue(new AttachmentResult(uri));
|
result.postValue(new AttachmentResult(uri));
|
||||||
|
|||||||
@@ -131,6 +131,7 @@
|
|||||||
<string name="image_attach">Attach image</string>
|
<string name="image_attach">Attach image</string>
|
||||||
<string name="image_attach_error">Could not attach image(s)</string>
|
<string name="image_attach_error">Could not attach image(s)</string>
|
||||||
<string name="image_attach_error_too_big">Image too big. Limit is %d MB.</string>
|
<string name="image_attach_error_too_big">Image too big. Limit is %d MB.</string>
|
||||||
|
<string name="image_attach_error_invalid_mime_type">Image format unsupported: %s</string>
|
||||||
<string name="set_contact_alias">Change contact name</string>
|
<string name="set_contact_alias">Change contact name</string>
|
||||||
<string name="set_contact_alias_hint">Contact name</string>
|
<string name="set_contact_alias_hint">Contact name</string>
|
||||||
<string name="set_alias_button">Change</string>
|
<string name="set_alias_button">Change</string>
|
||||||
|
|||||||
@@ -94,23 +94,6 @@ public class AttachmentControllerTest extends BrambleMockTestCase {
|
|||||||
assertFalse(item.hasError());
|
assertFalse(item.hasError());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testImageHealsWrongMimeType() {
|
|
||||||
AttachmentHeader h = getAttachmentHeader("image/png");
|
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
|
||||||
oneOf(imageHelper).decodeStream(with(any(InputStream.class)));
|
|
||||||
will(returnValue(new DecodeResult(160, 240, "image/jpeg")));
|
|
||||||
oneOf(imageHelper).getExtensionFromMimeType("image/jpeg");
|
|
||||||
will(returnValue("jpg"));
|
|
||||||
}});
|
|
||||||
|
|
||||||
AttachmentItem item = controller.getAttachmentItem(h, attachment, true);
|
|
||||||
assertEquals("image/jpeg", item.getMimeType());
|
|
||||||
assertEquals("jpg", item.getExtension());
|
|
||||||
assertFalse(item.hasError());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBigJpegImage() {
|
public void testBigJpegImage() {
|
||||||
String mimeType = "image/jpeg";
|
String mimeType = "image/jpeg";
|
||||||
|
|||||||
Reference in New Issue
Block a user