Skip to content

fix(v3/macOS): prevent OpenFile dialog crash when UTType cannot resolve filter extensions#5678

Open
phergul wants to merge 4 commits into
wailsapp:masterfrom
phergul:fix/issue-5675-macos-filedialog-crash
Open

fix(v3/macOS): prevent OpenFile dialog crash when UTType cannot resolve filter extensions#5678
phergul wants to merge 4 commits into
wailsapp:masterfrom
phergul:fix/issue-5675-macos-filedialog-crash

Conversation

@phergul

@phergul phergul commented Jun 26, 2026

Copy link
Copy Markdown

Description

Fixes a crash on macOS when a file dialog filter contains extensions that UTType cannot resolve

showOpenFileDialog builds allowedContentTypes by calling UTType typeWithFilenameExtension for each filter extension. That API returns nil when it is not a 'recognised' UTType. Inserting nil into the NSMutableArray throws NSInvalidArgumentException and crashes the app.

  • dialogs_darwin.go: Skip nil UTTypes and add unrecognized extensions to the legacy setAllowedFileTypes API (same path that is used for macOS < 11). Recognized extensions continue to use setAllowedContentTypes.
  • dialogs_darwin_delegate.m: Match files by filename suffix instead of pathExtension, so compound extensions like tar.gz are selectable (pathExtension only returns gz for example.tar.gz).

I checked how Electron handles this, and they simply take only the last extension from the users input (e.g. .tar.gz -> .gz) and filter on that. Comparing using the filename suffix lets matching be more accurate.

Fixes #5675

Type of change

Please select the option that is relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

  • Windows

  • macOS

  • Linux

  • go test ./...

  • go mod replace with branch, tested the unrecognised extensions (tar.gz, busted.exe). Also tested with full list of both recognised and unrecognised ones.

Test Configuration

Wails v3.0.0-alpha2.106 › Wails Doctor

# System

┌──────────────────────────────┐
| Name          | MacOS        |
| Version       | 26.5.1       |
| ID            | 25F80        |
| Branding      | MacOS 26.5.1 |
| Platform      | darwin       |
| Architecture  | arm64        |
| Apple Silicon | true         |
| CPU           | Apple M4 Pro |
| CPU           | Apple M4 Pro |
| GPU           | 16 cores     |
| Memory        | 24 GB        |
└──────────────────────────────┘

# Build Environment

┌──────────────────────────────────────────────────────────────────────┐
| Wails CLI      | v3.0.0-alpha2.106                                   |
| Go Version     | go1.26.4                                            |
| -buildmode     | exe                                                 |
| -compiler      | gc                                                  |
| CGO_CFLAGS     |                                                     |
| CGO_CPPFLAGS   |                                                     |
| CGO_CXXFLAGS   |                                                     |
| CGO_ENABLED    | 1                                                   |
| CGO_LDFLAGS    |                                                     |
| DefaultGODEBUG | cryptocustomrand=1,tlssecpmlkem=0,urlstrictcolons=0 |
| GOARCH         | arm64                                               |
| GOARM64        | v8.0                                                |
| GOOS           | darwin                                              |
└──────────────────────────────────────────────────────────────────────┘

# Dependencies

┌──────────────────────────────────────────────────────────────────────────────────────────────────────────┐
| *Android SDK       | Not found. Set ANDROID_HOME (install via Android Studio or the command-line tools). |
| *NSIS              | Not Installed. Install with `brew install makensis`.                                |
| *Xcode (iOS)       | Xcode 26.2, Build version 17C52                                                     |
| *iOS Device SDK    | 26.2                                                                                |
| *iOS Simulator SDK | 26.2                                                                                |
| Xcode cli tools    | 2416                                                                                |
| npm                | 11.12.1                                                                             |
| docker             | *Docker version 28.4.0, build d8eb465 (daemon not running)                          |
|                                                                                                          |
└──────────────────────────────────────── * - Optional Dependency ─────────────────────────────────────────┘

# Signing

┌────────────────────────────────────────┐
| macOS Signing   | Not configured       |
| Windows Signing | Not configured       |
| Linux Signing   | Not configured (GPG) |
└────────────────────────────────────────┘

# Checking for issues

 SUCCESS  No issues found

# Diagnosis

 SUCCESS  Your system is ready for Wails development!

Checklist:

  • (v2 only) I have updated website/src/pages/changelog.mdx with details of this PR (v3 changelog entries are added automatically)
  • My code follows the general coding style of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Summary by CodeRabbit

  • Bug Fixes
    • Improved macOS file open dialog filtering by handling allowed filename extensions more reliably.
    • Updated how the dialog maps extensions to system file type filters, avoiding situations where some extensions could produce incomplete or missing matches.
    • Refined validation so allowed files are matched using case-insensitive filename suffix checks, reducing cases where file selections were incorrectly accepted or rejected.

phergul added 2 commits June 25, 2026 20:39
for compound extensions like "tar.gz", pathExtension only returns the
last segment ("gz")
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

macOS open-file dialog filtering now splits recognized and unrecognized filename extensions, and the delegate now validates allowed files by matching the lowercase filename suffix instead of relying on the URL path extension.

Changes

macOS open-file dialog filtering

Layer / File(s) Summary
Filter resolution fallback
v3/pkg/application/dialogs_darwin.go
Resolved filename extensions are added as UTType content types, while unresolved extensions are collected separately and applied as legacy file types.
Allowed extension suffix match
v3/pkg/application/dialogs_darwin_delegate.m
The delegate lowercases the last path component, rejects nil or empty filenames, skips empty allowed entries, and accepts URLs whose filenames end with the allowed extension suffix.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

A bunny peeks at dialog night,
And nibbles filters left and right.
🐰 One path for types that bloom and sprout,
One suffix check to smooth things out.
Hoppy files now bounce along just right.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the macOS OpenFile crash fix and the UTType filter issue.
Description check ✅ Passed The description includes the fix summary, linked issue, test results, test configuration, and checklist items required by the template.
Linked Issues check ✅ Passed The changes address #5675 by skipping nil UTTypes, preserving valid filters, and safely handling unsupported extensions on macOS.
Out of Scope Changes check ✅ Passed No unrelated code changes are evident; both modified files directly support the macOS file-dialog crash fix.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain modules listed in go.work or their selected dependencies"


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@leaanthony

Copy link
Copy Markdown
Member

Amazing! Thanks 🙏

@leaanthony leaanthony enabled auto-merge (squash) June 27, 2026 07:05

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@v3/pkg/application/dialogs_darwin_delegate.m`:
- Around line 29-34: Normalize allowed extension values in the Darwin dialog
filtering path by stripping any leading dots before they reach the matching
logic, since allowedExtensions can still contain entries like .png that will
never match the hasSuffix check or resolve correctly through UTType
typeWithFilenameExtension. Update the normalization in the dialog setup and keep
the checks in dialogs_darwin_delegate.m consistent with the cleaned extension
values so both suffix matching and type resolution use the same canonical form.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b5385b82-9234-41f3-b0c5-91d6c4ec49c8

📥 Commits

Reviewing files that changed from the base of the PR and between 820ee9a and d9258c3.

📒 Files selected for processing (2)
  • v3/pkg/application/dialogs_darwin.go
  • v3/pkg/application/dialogs_darwin_delegate.m

Comment on lines 29 to +34
for (NSString *allowedExt in self.allowedExtensions) {
if ([[allowedExt lowercaseString] isEqualToString:extension]) {
NSString *allowed = [allowedExt lowercaseString];
if ([allowed length] == 0) {
continue;
}
if ([filename hasSuffix:[@"." stringByAppendingString:allowed]]) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
fd -a 'dialogs*' v3/pkg/application
rg -n -C4 '\ballowedExtensions\b' v3/pkg/application
rg -n -C4 'typeWithFilenameExtension|setAllowedFileTypes|setAllowedContentTypes|hasSuffix' v3/pkg/application

Repository: wailsapp/wails

Length of output: 8077


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the Darwin dialog path and the upstream filter normalization.
sed -n '1,260p' v3/pkg/application/dialogs_darwin.go
printf '\n---\n'
sed -n '1,260p' v3/pkg/application/dialogs.go
printf '\n---\n'
sed -n '1,260p' v3/pkg/application/dialogs_test.go
printf '\n---\n'
rg -n -C3 'filterPatterns|allowedExtensions|AllowedFileTypes|AllowedContentTypes|Filter' v3/pkg/application

Repository: wailsapp/wails

Length of output: 38141


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '486,508p' v3/pkg/application/dialogs_darwin.go
printf '\n---\n'
rg -n -C4 'TrimPrefix|TrimSpace|strings\.Join|patternComponents|filterPatterns' v3/pkg/application/dialogs_darwin.go

Repository: wailsapp/wails

Length of output: 3562


Strip leading dots during Darwin filter normalization.
dialogs_darwin.go trims *. but leaves values like .png unchanged, so allowedExtensions can still contain entries that never match the ." + allowed check or resolve cleanly through UTType typeWithFilenameExtension:.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@v3/pkg/application/dialogs_darwin_delegate.m` around lines 29 - 34, Normalize
allowed extension values in the Darwin dialog filtering path by stripping any
leading dots before they reach the matching logic, since allowedExtensions can
still contain entries like .png that will never match the hasSuffix check or
resolve correctly through UTType typeWithFilenameExtension. Update the
normalization in the dialog setup and keep the checks in
dialogs_darwin_delegate.m consistent with the cleaned extension values so both
suffix matching and type resolution use the same canonical form.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[v3] macOS: Dialogs.OpenFile crashes when filter contains unrecognised extensions

2 participants