OPP: Check file size before send to prevent crash
Use case :
1. Send large file to dut (Above 4 GB)
Failure:
Crash in com.android.bluetooth.
Process: com.android.bluetooth
java.lang.IllegalArgumentException: Length must be
between 0 and 0xFFFFFFFF
at javax.obex.HeaderSet.setHeader(HeaderSet.java:333)
at com.android.bluetooth.opp.BluetoothOppObexClientSession$ClientThread
.sendFile(BluetoothOppObexClientSession.java:411)
at com.android.bluetooth.opp.BluetoothOppObexClientSession$ClientThread
.doSend(BluetoothOppObexClientSession.java:337)
Root cause :
Largest length in OBEX message header is unsigned 4 bytes, so actual
file length (4 GB) cannot be written into Obex header which leads
to exception in OBEX code.
Fix :
Add length check before push file and skip sendfile if length is above
4GB to prevent crash.
Change-Id: I9066fb7456d85fdc197fe21fed26fb2bb89ff09e
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java
index 1d605c0..56b27d8 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java
@@ -53,6 +53,7 @@
import android.provider.Settings;
import android.util.Log;
import android.util.Patterns;
+import android.widget.Toast;
/**
* This class is designed to act as the entry point of handling the share intent
@@ -109,11 +110,7 @@
// session to DB.
Thread t = new Thread(new Runnable() {
public void run() {
- BluetoothOppManager.getInstance(BluetoothOppLauncherActivity.this)
- .saveSendingFileInfo(type,stream.toString(), false);
- //Done getting file info..Launch device picker and finish this activity
- launchDevicePicker();
- finish();
+ sendFileInfo(type, stream.toString(), false);
}
});
t.start();
@@ -125,12 +122,7 @@
if (fileUri != null) {
Thread t = new Thread(new Runnable() {
public void run() {
- BluetoothOppManager.getInstance(BluetoothOppLauncherActivity.this)
- .saveSendingFileInfo(type,fileUri.toString(), false);
- //Done getting file info..Launch device picker
- //and finish this activity
- launchDevicePicker();
- finish();
+ sendFileInfo(type, fileUri.toString(), false);
}
});
t.start();
@@ -153,12 +145,17 @@
+ mimeType);
Thread t = new Thread(new Runnable() {
public void run() {
- BluetoothOppManager.getInstance(BluetoothOppLauncherActivity.this)
- .saveSendingFileInfo(mimeType,uris, false);
- //Done getting file info..Launch device picker
- //and finish this activity
- launchDevicePicker();
- finish();
+ try {
+ BluetoothOppManager.getInstance(BluetoothOppLauncherActivity.this)
+ .saveSendingFileInfo(mimeType, uris, false);
+ //Done getting file info..Launch device picker
+ //and finish this activity
+ launchDevicePicker();
+ finish();
+ } catch (IllegalArgumentException exception) {
+ showToast(exception.getMessage());
+ finish();
+ }
}
});
t.start();
@@ -377,4 +374,26 @@
}
return text;
}
+
+ private void sendFileInfo(String mimeType, String uriString, boolean isHandover) {
+ BluetoothOppManager manager = BluetoothOppManager.getInstance(getApplicationContext());
+ try {
+ manager.saveSendingFileInfo(mimeType, uriString, isHandover);
+ launchDevicePicker();
+ finish();
+ } catch (IllegalArgumentException exception) {
+ showToast(exception.getMessage());
+ finish();
+ }
+ }
+
+ private void showToast(final String msg) {
+ BluetoothOppLauncherActivity.this.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+
}
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java
index dd8efe0..bdc61c9 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java
@@ -246,7 +246,8 @@
if (V) Log.v(TAG, "Application data stored to SharedPreference! ");
}
- public void saveSendingFileInfo(String mimeType, String uriString, boolean isHandover) {
+ public void saveSendingFileInfo(String mimeType, String uriString, boolean isHandover)
+ throws IllegalArgumentException {
synchronized (BluetoothOppManager.this) {
mMultipleFlag = false;
mMimeTypeOfSendingFile = mimeType;
@@ -259,7 +260,8 @@
}
}
- public void saveSendingFileInfo(String mimeType, ArrayList<Uri> uris, boolean isHandover) {
+ public void saveSendingFileInfo(String mimeType, ArrayList<Uri> uris, boolean isHandover)
+ throws IllegalArgumentException {
synchronized (BluetoothOppManager.this) {
mMultipleFlag = true;
mMimeTypeOfSendingFiles = mimeType;
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java
index b9d2b9f..2495f9b 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java
@@ -212,6 +212,10 @@
if (length == 0) {
Log.e(TAG, "Could not determine size of file");
return SEND_FILE_INFO_ERROR;
+ } else if (length > 0xffffffffL) {
+ String msg = "Files bigger than 4GB can't be transferred";
+ Log.e(TAG, msg);
+ throw new IllegalArgumentException(msg);
}
return new BluetoothOppSendFileInfo(fileName, contentType, length, is, 0);