changeset 2786:3934ac8b394c

iOS: Make dw_file_browse() grant access to security scoped resources. At some point revoke access, so we don't leak kernel resources... so maintain a list of URLs and when the list gets too long revoke access.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 13 Jul 2022 04:51:09 +0000
parents 220d63da2183
children 56312f9c1d6c
files ios/dw.m
diffstat 1 files changed, 24 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/ios/dw.m	Sun Jul 10 09:53:19 2022 +0000
+++ b/ios/dw.m	Wed Jul 13 04:51:09 2022 +0000
@@ -567,7 +567,6 @@
 
                 if([object isKindOfClass:[UITableView class]] && event)
                 {
-                    
                     if([event isKindOfClass:[NSPointerArray class]])
                     {
                        /* The NSPointerArray count will be 2 for Containers */
@@ -1092,6 +1091,9 @@
 -(void)setDialog:(DWDialog *)newdialog;
 @end
 
+#define _DW_URL_LIMIT 10
+static NSMutableArray *_dw_URLs = nil;
+
 @implementation DWDocumentPickerDelegate
 -(void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls
 {
@@ -1102,8 +1104,28 @@
     {
         const char *tmp = [url fileSystemRepresentation];
 
-        if(tmp)
+        if(tmp && [url startAccessingSecurityScopedResource])
+        {
+            /* We need to allow access to the returned URLs on iOS 13
+             * but we have no way of knowing when it is no longer needed...
+             * since the C API we are connected to does not have that information.
+             * So maintain a list of URLs, and when the list exceeds the limit...
+             * revoke access to the oldest URL.
+             */
+            if(!_dw_URLs)
+                _dw_URLs = [[[NSMutableArray alloc] init] retain];
+            if(_dw_URLs)
+            {
+                if([_dw_URLs count] >= _DW_URL_LIMIT)
+                {
+                    NSURL *oldurl = [_dw_URLs firstObject];
+                    [oldurl stopAccessingSecurityScopedResource];
+                    [_dw_URLs removeObject:oldurl];
+                }
+                [_dw_URLs addObject:url];
+            }
             file = strdup(tmp);
+        }
     }
     dw_dialog_dismiss(dialog, file);
 }