summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAssam Boudjelthia <assam.boudjelthia@qt.io>2020-02-14 14:20:13 +0200
committerAssam Boudjelthia <assam.boudjelthia@qt.io>2020-02-17 19:05:20 +0200
commitf36b042e2b66a3ad32980b21e9fafc1bd9b0c7c1 (patch)
treeffc427b5f4f195957529adebfffe759f9eb779e6
parent189ae68d2a93358efa48b65bb798aa2ae2b25b59 (diff)
Android: handle check permissions before any file operations
This is required because opening a Uri with no permissions can cause crashes. Some exceptions were not handled at all. Change-Id: I2e8f9505879b9fc4c1c47bdfa1bf173b39ada3ea Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java71
-rw-r--r--src/plugins/platforms/android/qandroidplatformservices.cpp15
2 files changed, 67 insertions, 19 deletions
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index c1c4d5559d..87d326e225 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -47,11 +47,13 @@ import java.util.concurrent.Semaphore;
import android.app.Activity;
import android.app.Service;
+import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ActivityInfo;
+import android.content.UriPermission;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
@@ -73,6 +75,7 @@ import java.lang.reflect.Method;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
import java.util.Iterator;
+import java.util.List;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
@@ -152,35 +155,79 @@ public class QtNative
}
}
- public static boolean openURL(String url, String mime)
+ private static Uri getUriWithValidPermission(Context context, String uri, String openMode)
{
- boolean ok = true;
+ try {
+ List<UriPermission> permissions = context.getContentResolver().getPersistedUriPermissions();
+ String uriStr = Uri.parse(uri).getPath();
+
+ for (int i = 0; i < permissions.size(); ++i) {
+ Uri iterUri = permissions.get(i).getUri();
+ boolean isRightPermission = permissions.get(i).isReadPermission();
+
+ if (!openMode.equals("r"))
+ isRightPermission = permissions.get(i).isWritePermission();
+
+ if (iterUri.getPath().equals(uriStr) && isRightPermission)
+ return iterUri;
+ }
+
+ return null;
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public static boolean openURL(Context context, String url, String mime)
+ {
+ Uri uri = getUriWithValidPermission(context, url, "r");
+
+ if (uri == null) {
+ Log.e(QtTAG, "openURL(): No permissions to open Uri");
+ return false;
+ }
try {
- Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (!mime.isEmpty())
intent.setDataAndType(uri, mime);
+
activity().startActivity(intent);
- } catch (Exception e) {
+
+ return true;
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "openURL(): Invalid Uri");
+ return false;
+ } catch (UnsupportedOperationException e) {
+ Log.e(QtTAG, "openURL(): Unsupported operation for given Uri");
+ return false;
+ } catch (ActivityNotFoundException e) {
e.printStackTrace();
- ok = false;
+ return false;
}
-
- return ok;
}
public static int openFdForContentUrl(Context context, String contentUrl, String openMode)
{
+ Uri uri = getUriWithValidPermission(context, contentUrl, openMode);
+ int error = -1;
+
+ if (uri == null) {
+ Log.e(QtTAG, "openFdForContentUrl(): No permissions to open Uri");
+ return error;
+ }
+
try {
ContentResolver resolver = context.getContentResolver();
- ParcelFileDescriptor fdDesc = resolver.openFileDescriptor(Uri.parse(contentUrl), openMode);
+ ParcelFileDescriptor fdDesc = resolver.openFileDescriptor(uri, openMode);
return fdDesc.detachFd();
} catch (FileNotFoundException e) {
- return -1;
- } catch (SecurityException e) {
- Log.e(QtTAG, "Exception when opening file", e);
- return -1;
+ return error;
+ } catch (IllegalArgumentException e) {
+ Log.e(QtTAG, "openFdForContentUrl(): Invalid Uri");
+ return error;
}
}
diff --git a/src/plugins/platforms/android/qandroidplatformservices.cpp b/src/plugins/platforms/android/qandroidplatformservices.cpp
index 136637800b..c095613ce7 100644
--- a/src/plugins/platforms/android/qandroidplatformservices.cpp
+++ b/src/plugins/platforms/android/qandroidplatformservices.cpp
@@ -43,6 +43,7 @@
#include <QDebug>
#include <QMimeDatabase>
#include <QtCore/private/qjni_p.h>
+#include <private/qjnihelpers_p.h>
QT_BEGIN_NAMESPACE
@@ -57,20 +58,20 @@ bool QAndroidPlatformServices::openUrl(const QUrl &theUrl)
// if the file is local, we need to pass the MIME type, otherwise Android
// does not start an Intent to view this file
- if ((url.scheme().isEmpty() && QFile::exists(url.path())) || url.isLocalFile()) {
+ QLatin1String fileScheme("file");
+ if ((url.scheme().isEmpty() || url.scheme() == fileScheme) && QFile::exists(url.path())) {
// a real URL including the scheme is needed, else the Intent can not be started
- url.setScheme(QLatin1String("file"));
-
+ url.setScheme(fileScheme);
QMimeDatabase mimeDb;
mime = mimeDb.mimeTypeForUrl(url).name();
}
QJNIObjectPrivate urlString = QJNIObjectPrivate::fromString(url.toString());
QJNIObjectPrivate mimeString = QJNIObjectPrivate::fromString(mime);
- return QJNIObjectPrivate::callStaticMethod<jboolean>(QtAndroid::applicationClass(),
- "openURL",
- "(Ljava/lang/String;Ljava/lang/String;)Z",
- urlString.object(), mimeString.object());
+ return QJNIObjectPrivate::callStaticMethod<jboolean>(
+ QtAndroid::applicationClass(), "openURL",
+ "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)Z",
+ QtAndroidPrivate::context(), urlString.object(), mimeString.object());
}
bool QAndroidPlatformServices::openDocument(const QUrl &url)