- 
    Bug 
- 
    Resolution: Out of scope
- 
    P1: Critical 
- 
    None
- 
    5.9, 5.12, 5.14
- 
    None
- 
    macOS 10.15 (Catalina)
In macOS 10.15 (Catalina), the native Cocoa file save dialog will crash if all of the following are true:
- the user confirms the default filename without modifying it
- an extension is automatically added to the filename based on the selected filter
- a file with the same name already exists
- the user chooses to replace the file when prompted by macOS.
The following program demonstrates the problem:
#include <QApplication>
#include <QFileDialog>
int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    QWidget window;
    QString caption = "Save As";
    QString filter = "Plain text (*.txt);;Markdown (*.md)";
    QString path = "Untitled.txt";
    QString selectedFilter;
    QFileDialog::Options options = QFileDialog::Options();
    path = QFileDialog::getSaveFileName(&window, caption, path, filter,
                                        &selectedFilter, options);
    QFile f(path);
    f.open(QIODevice::WriteOnly);
    f.close();
    path = QFileDialog::getSaveFileName(&window, caption, path, filter, 
                                        &selectedFilter, options);
}
The above program will prompt the user for a filename. If the file exists, and the user agrees to replace the file, the program will crash before the first call to QFileDialog::getSaveFileName() returns. Otherwise, the file will be created. Then the program will once again prompt the user for a filename. Assuming the file creation was successful, if the user chooses the same filename and agrees to replace the file, the program will crash.
I noticed that QNSOpenSavePanelDelegate does not implement the panel:validateURL:error: instance method of the NSOpenSavePanelDelegate protocol. Adding an implementation of this method in
qtbase/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
seems to solve the problem. It can be as simple as this:
- (BOOL)panel:(id)sender validateURL:(NSURL *)url error:(NSError **)outError
{
    Q_UNUSED(sender);
    Q_UNUSED(url);
    Q_UNUSED(outError);
    return YES;
} 
At first, my thought was to retain a reference to the NSURL passed to this method, and use that instead of calling [mSavePanel URL], since that seemed to be where the assertion failure was, but I found that simply providing an implementation of this method allowed the calls to [mSavePanel URL] to succeed.
To be fair, I see this more as a bug in Catalina than in Qt, but I think it would be good to implement this method of the NSOpenSavePanelDelegate protocol, especially since it seems to resolve this issue.