Warning, /graphics/krita/3rdparty/ext_qt/0007-Android-handle-check-permissions-before-any-file-ope.patch is written in an unsupported language. File is not indexed.
0001 From a38d869fd045bba2272757357b1d15e60a3fb119 Mon Sep 17 00:00:00 2001 0002 From: Assam Boudjelthia <assam.boudjelthia@qt.io> 0003 Date: Fri, 14 Feb 2020 14:20:13 +0200 0004 Subject: [PATCH 07/46] Android: handle check permissions before any file 0005 operations 0006 0007 This is required because opening a Uri with no permissions can cause 0008 crashes. 0009 Some exceptions were not handled at all. 0010 0011 Change-Id: I2e8f9505879b9fc4c1c47bdfa1bf173b39ada3ea 0012 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> 0013 --- 0014 .../org/qtproject/qt5/android/QtNative.java | 72 ++++++++++++++++--- 0015 .../android/qandroidplatformservices.cpp | 15 ++-- 0016 2 files changed, 71 insertions(+), 16 deletions(-) 0017 0018 diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java 0019 index c9521e09b1..6a4ec6687a 100644 0020 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java 0021 +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java 0022 @@ -47,11 +47,13 @@ import java.util.concurrent.Semaphore; 0023 0024 import android.app.Activity; 0025 import android.app.Service; 0026 +import android.content.ActivityNotFoundException; 0027 import android.content.Context; 0028 import android.content.ContentResolver; 0029 import android.content.Intent; 0030 import android.content.pm.PackageManager; 0031 import android.content.pm.ActivityInfo; 0032 +import android.content.UriPermission; 0033 import android.net.Uri; 0034 import android.os.Build; 0035 import android.os.Handler; 0036 @@ -74,6 +76,7 @@ import java.lang.reflect.Method; 0037 import java.security.KeyStore; 0038 import java.security.cert.X509Certificate; 0039 import java.util.Iterator; 0040 +import java.util.List; 0041 import javax.net.ssl.TrustManagerFactory; 0042 import javax.net.ssl.TrustManager; 0043 import javax.net.ssl.X509TrustManager; 0044 @@ -153,32 +156,83 @@ public class QtNative 0045 } 0046 } 0047 0048 - public static boolean openURL(String url, String mime) 0049 + private static Uri getUriWithValidPermission(Context context, String uri, String openMode) 0050 { 0051 - boolean ok = true; 0052 + try { 0053 + List<UriPermission> permissions = context.getContentResolver().getPersistedUriPermissions(); 0054 + String uriStr = Uri.parse(uri).getPath(); 0055 + 0056 + for (int i = 0; i < permissions.size(); ++i) { 0057 + Uri iterUri = permissions.get(i).getUri(); 0058 + boolean isRightPermission = permissions.get(i).isReadPermission(); 0059 + 0060 + if (!openMode.equals("r")) 0061 + isRightPermission = permissions.get(i).isWritePermission(); 0062 + 0063 + if (iterUri.getPath().equals(uriStr) && isRightPermission) 0064 + return iterUri; 0065 + } 0066 + 0067 + return null; 0068 + } catch (SecurityException e) { 0069 + e.printStackTrace(); 0070 + return null; 0071 + } 0072 + } 0073 + 0074 + public static boolean openURL(Context context, String url, String mime) 0075 + { 0076 + Uri uri; 0077 + if (url.startsWith("content:")) { 0078 + uri = getUriWithValidPermission(context, url, "r"); 0079 + if (uri == null) { 0080 + Log.e(QtTAG, "openURL(): No permissions to open Uri"); 0081 + return false; 0082 + } 0083 + } else { 0084 + uri = Uri.parse(url); 0085 + } 0086 0087 try { 0088 - Uri uri = Uri.parse(url); 0089 Intent intent = new Intent(Intent.ACTION_VIEW, uri); 0090 + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 0091 if (!mime.isEmpty()) 0092 intent.setDataAndType(uri, mime); 0093 + 0094 activity().startActivity(intent); 0095 - } catch (Exception e) { 0096 + 0097 + return true; 0098 + } catch (IllegalArgumentException e) { 0099 + Log.e(QtTAG, "openURL(): Invalid Uri"); 0100 + return false; 0101 + } catch (UnsupportedOperationException e) { 0102 + Log.e(QtTAG, "openURL(): Unsupported operation for given Uri"); 0103 + return false; 0104 + } catch (ActivityNotFoundException e) { 0105 e.printStackTrace(); 0106 - ok = false; 0107 + return false; 0108 } 0109 - 0110 - return ok; 0111 } 0112 0113 public static int openFdForContentUrl(Context context, String contentUrl, String openMode) 0114 { 0115 + Uri uri = getUriWithValidPermission(context, contentUrl, openMode); 0116 + int error = -1; 0117 + 0118 + if (uri == null) { 0119 + Log.e(QtTAG, "openFdForContentUrl(): No permissions to open Uri"); 0120 + return error; 0121 + } 0122 + 0123 try { 0124 ContentResolver resolver = context.getContentResolver(); 0125 - ParcelFileDescriptor fdDesc = resolver.openFileDescriptor(Uri.parse(contentUrl), openMode); 0126 + ParcelFileDescriptor fdDesc = resolver.openFileDescriptor(uri, openMode); 0127 return fdDesc.detachFd(); 0128 } catch (FileNotFoundException e) { 0129 - return -1; 0130 + return error; 0131 + } catch (IllegalArgumentException e) { 0132 + Log.e(QtTAG, "openFdForContentUrl(): Invalid Uri"); 0133 + return error; 0134 } 0135 } 0136 0137 diff --git a/src/plugins/platforms/android/qandroidplatformservices.cpp b/src/plugins/platforms/android/qandroidplatformservices.cpp 0138 index 136637800b..c095613ce7 100644 0139 --- a/src/plugins/platforms/android/qandroidplatformservices.cpp 0140 +++ b/src/plugins/platforms/android/qandroidplatformservices.cpp 0141 @@ -43,6 +43,7 @@ 0142 #include <QDebug> 0143 #include <QMimeDatabase> 0144 #include <QtCore/private/qjni_p.h> 0145 +#include <private/qjnihelpers_p.h> 0146 0147 QT_BEGIN_NAMESPACE 0148 0149 @@ -57,20 +58,20 @@ bool QAndroidPlatformServices::openUrl(const QUrl &theUrl) 0150 0151 // if the file is local, we need to pass the MIME type, otherwise Android 0152 // does not start an Intent to view this file 0153 - if ((url.scheme().isEmpty() && QFile::exists(url.path())) || url.isLocalFile()) { 0154 + QLatin1String fileScheme("file"); 0155 + if ((url.scheme().isEmpty() || url.scheme() == fileScheme) && QFile::exists(url.path())) { 0156 // a real URL including the scheme is needed, else the Intent can not be started 0157 - url.setScheme(QLatin1String("file")); 0158 - 0159 + url.setScheme(fileScheme); 0160 QMimeDatabase mimeDb; 0161 mime = mimeDb.mimeTypeForUrl(url).name(); 0162 } 0163 0164 QJNIObjectPrivate urlString = QJNIObjectPrivate::fromString(url.toString()); 0165 QJNIObjectPrivate mimeString = QJNIObjectPrivate::fromString(mime); 0166 - return QJNIObjectPrivate::callStaticMethod<jboolean>(QtAndroid::applicationClass(), 0167 - "openURL", 0168 - "(Ljava/lang/String;Ljava/lang/String;)Z", 0169 - urlString.object(), mimeString.object()); 0170 + return QJNIObjectPrivate::callStaticMethod<jboolean>( 0171 + QtAndroid::applicationClass(), "openURL", 0172 + "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)Z", 0173 + QtAndroidPrivate::context(), urlString.object(), mimeString.object()); 0174 } 0175 0176 bool QAndroidPlatformServices::openDocument(const QUrl &url) 0177 -- 0178 2.33.0 0179