From 662dd44587796072b81b47f202597569f4e8c48d Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Fri, 28 Oct 2022 18:49:32 -0400
Subject: [PATCH] Fix leaks in mac filepicker code

---
 indra/newview/llfilepicker.cpp    |  10 +-
 indra/newview/llfilepicker.h      |   2 +-
 indra/newview/llfilepicker_mac.h  |   4 +-
 indra/newview/llfilepicker_mac.mm | 157 +++++++++++++++---------------
 4 files changed, 88 insertions(+), 85 deletions(-)

diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 3669fb1eeb0..e3a695fc79b 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -586,9 +586,9 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename,
 
 #elif LL_DARWIN
 
-std::vector<std::string>* LLFilePicker::navOpenFilterProc(ELoadFilter filter) //(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode)
+std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadFilter filter) //(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode)
 {
-    std::vector<std::string> *allowedv = new std::vector< std::string >;
+    std::unique_ptr<std::vector<std::string>> allowedv(new std::vector< std::string >);
     switch(filter)
     {
         case FFLOAD_ALL:
@@ -661,9 +661,9 @@ bool	LLFilePicker::doNavChooseDialog(ELoadFilter filter)
     
 	gViewerWindow->getWindow()->beforeDialog();
     
-    std::vector<std::string> *allowed_types=navOpenFilterProc(filter);
+    std::unique_ptr<std::vector<std::string>> allowed_types = navOpenFilterProc(filter);
     
-    std::vector<std::string> *filev  = doLoadDialog(allowed_types, 
+    std::unique_ptr<std::vector<std::string>> filev  = doLoadDialog(allowed_types.get(),
                                                     mPickOptions);
 
 	gViewerWindow->getWindow()->afterDialog();
@@ -780,7 +780,7 @@ bool	LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filena
 	gViewerWindow->getWindow()->beforeDialog();
 
 	// Run the dialog
-    std::string* filev = doSaveDialog(&namestring, 
+    std::unique_ptr<std::string> filev = doSaveDialog(&namestring, 
                  &type,
                  &creator,
                  &extension,
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index 04ba4416d7e..73baeca1c01 100644
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -167,7 +167,7 @@ class LLFilePicker
 	
 	bool doNavChooseDialog(ELoadFilter filter);
 	bool doNavSaveDialog(ESaveFilter filter, const std::string& filename);
-    std::vector<std::string>* navOpenFilterProc(ELoadFilter filter);
+    std::unique_ptr<std::vector<std::string>> navOpenFilterProc(ELoadFilter filter);
 #endif
 
 #if LL_GTK
diff --git a/indra/newview/llfilepicker_mac.h b/indra/newview/llfilepicker_mac.h
index e0b7e2e8ce0..b2fb371afea 100644
--- a/indra/newview/llfilepicker_mac.h
+++ b/indra/newview/llfilepicker_mac.h
@@ -39,9 +39,9 @@
 #include <vector>
 
 //void modelessPicker();
-std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types, 
+std::unique_ptr<std::vector<std::string>> doLoadDialog(const std::vector<std::string>* allowed_types,
                  unsigned int flags);
-std::string* doSaveDialog(const std::string* file, 
+std::unique_ptr<std::string> doSaveDialog(const std::string* file, 
                   const std::string* type,
                   const std::string* creator,
                   const std::string* extension,
diff --git a/indra/newview/llfilepicker_mac.mm b/indra/newview/llfilepicker_mac.mm
index 1438e4dc0a9..0ae5fc3f774 100644
--- a/indra/newview/llfilepicker_mac.mm
+++ b/indra/newview/llfilepicker_mac.mm
@@ -29,104 +29,107 @@
 #include <iostream>
 #include "llfilepicker_mac.h"
 
-std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types, 
+std::unique_ptr<std::vector<std::string>> doLoadDialog(const std::vector<std::string>* allowed_types,
                  unsigned int flags)
 {
-    int i, result;
-    
-    //Aura TODO:  We could init a small window and release it at the end of this routine
-    //for a modeless interface.
-    
-    NSOpenPanel *panel = [NSOpenPanel openPanel];
-    //NSString *fileName = nil;
-    NSMutableArray *fileTypes = nil;
-    
-    
-    if ( allowed_types && !allowed_types->empty()) 
-    {
-        fileTypes = [[NSMutableArray alloc] init];
+    std::unique_ptr<std::vector<std::string>> outfiles;
+
+    @autoreleasepool {
+        int i, result;
+        //Aura TODO:  We could init a small window and release it at the end of this routine
+        //for a modeless interface.
+        
+        NSOpenPanel *panel = [NSOpenPanel openPanel];
+        //NSString *fileName = nil;
+        NSMutableArray *fileTypes = nil;
         
-        for (i=0;i<allowed_types->size();++i)
+        if ( allowed_types && !allowed_types->empty())
         {
-            [fileTypes addObject: 
-             [NSString stringWithCString:(*allowed_types)[i].c_str() 
-                                encoding:[NSString defaultCStringEncoding]]];
+            fileTypes = [[[NSMutableArray alloc] init] autorelease];
+            
+            for (i=0;i<allowed_types->size();++i)
+            {
+                [fileTypes addObject:
+                 [NSString stringWithCString:(*allowed_types)[i].c_str()
+                                    encoding:[NSString defaultCStringEncoding]]];
+            }
         }
-    }
         
-    //[panel setMessage:@"Import one or more files or directories."];
-    [panel setAllowsMultipleSelection: ( (flags & F_MULTIPLE)?true:false ) ];
-    [panel setCanChooseDirectories: ( (flags & F_DIRECTORY)?true:false ) ];
-    [panel setCanCreateDirectories: true];
-    [panel setResolvesAliases: true];
-    [panel setCanChooseFiles: ( (flags & F_FILE)?true:false )];
-    [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
-    
-    std::vector<std::string>* outfiles = NULL; 
-    
-    if (fileTypes)
-    {
-        [panel setAllowedFileTypes:fileTypes];
-        result = [panel runModal];
-    }
-    else 
-    {
-        // I suggest it's better to open the last path and let this default to home dir as necessary
-        // for consistency with other OS X apps
-        //
-        //[panel setDirectoryURL: fileURLWithPath(NSHomeDirectory()) ];
-        result = [panel runModal];
-    }
-    
-    if (result == NSOKButton) 
-    {
-        NSArray *filesToOpen = [panel URLs];
-        int i, count = [filesToOpen count];
+        //[panel setMessage:@"Import one or more files or directories."];
+        [panel setAllowsMultipleSelection: ( (flags & F_MULTIPLE)?true:false ) ];
+        [panel setCanChooseDirectories: ( (flags & F_DIRECTORY)?true:false ) ];
+        [panel setCanCreateDirectories: true];
+        [panel setResolvesAliases: true];
+        [panel setCanChooseFiles: ( (flags & F_FILE)?true:false )];
+        [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
         
-        if (count > 0)
+        if (fileTypes)
+        {
+            [panel setAllowedFileTypes:fileTypes];
+            result = [panel runModal];
+        }
+        else
         {
-            outfiles = new std::vector<std::string>;
+            // I suggest it's better to open the last path and let this default to home dir as necessary
+            // for consistency with other OS X apps
+            //
+            //[panel setDirectoryURL: fileURLWithPath(NSHomeDirectory()) ];
+            result = [panel runModal];
         }
         
-        for (i=0; i<count; i++) {
-            NSString *aFile = [[filesToOpen objectAtIndex:i] path];
-            std::string *afilestr = new std::string([aFile UTF8String]);
-            outfiles->push_back(*afilestr);
+        if (result == NSOKButton)
+        {
+            NSArray *filesToOpen = [panel URLs];
+            int i, count = [filesToOpen count];
+            
+            if (count > 0)
+            {
+                outfiles.reset(new std::vector<std::string>);
+            }
+            
+            for (i=0; i<count; i++) {
+                NSString *aFile = [[filesToOpen objectAtIndex:i] path];
+                std::string afilestr = std::string([aFile UTF8String]);
+                outfiles->push_back(afilestr);
+            }
         }
     }
+
     return outfiles;
 }
 
 
-std::string* doSaveDialog(const std::string* file, 
+std::unique_ptr<std::string> doSaveDialog(const std::string* file,
                   const std::string* type,
                   const std::string* creator,
                   const std::string* extension,
                   unsigned int flags)
 {
-    NSSavePanel *panel = [NSSavePanel savePanel]; 
-    
-    NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]];
-    NSArray *fileType = [extensionns componentsSeparatedByString:@","];
-    
-    //[panel setMessage:@"Save Image File"]; 
-    [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
-    [panel setCanSelectHiddenExtension:true]; 
-    [panel setAllowedFileTypes:fileType];
-    NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]];
-    
-    std::string *outfile = NULL;
-    NSURL* url = [NSURL fileURLWithPath:fileName];
-    [panel setNameFieldStringValue: fileName];
-    [panel setDirectoryURL: url];
-    if([panel runModal] == 
-       NSFileHandlingPanelOKButton) 
-    {
-        NSURL* url = [panel URL];
-        NSString* p = [url path];
-        outfile = new std::string( [p UTF8String] );
-        // write the file 
-    } 
+    std::unique_ptr<std::string> outfile;
+    @autoreleasepool {
+        NSSavePanel *panel = [NSSavePanel savePanel];
+        
+        NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]];
+        NSArray *fileType = [extensionns componentsSeparatedByString:@","];
+        
+        //[panel setMessage:@"Save Image File"];
+        [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
+        [panel setCanSelectHiddenExtension:true];
+        [panel setAllowedFileTypes:fileType];
+        NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]];
+        
+        NSURL* url = [NSURL fileURLWithPath:fileName];
+        [panel setNameFieldStringValue: fileName];
+        [panel setDirectoryURL: url];
+        if([panel runModal] ==
+           NSFileHandlingPanelOKButton)
+        {
+            NSURL* url = [panel URL];
+            NSString* p = [url path];
+            outfile.reset(new std::string([p UTF8String]));
+            // write the file
+        }
+    }
     return outfile;
 }
 
-- 
GitLab