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