From 726e82d0f3d99273acb247fee7b6527b751cdde1 Mon Sep 17 00:00:00 2001
From: Semphris <[EMAIL REDACTED]>
Date: Tue, 21 Apr 2026 16:40:57 -0400
Subject: [PATCH] Update Zenity dialog filters to ignore case
---
src/dialog/SDL_dialog_utils.c | 28 +++++++++++++++++---------
src/dialog/SDL_dialog_utils.h | 8 +++++---
src/dialog/unix/SDL_zenitydialog.c | 2 +-
src/dialog/windows/SDL_windowsdialog.c | 2 +-
4 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/src/dialog/SDL_dialog_utils.c b/src/dialog/SDL_dialog_utils.c
index 826cc601c4cae..5af3b47689805 100644
--- a/src/dialog/SDL_dialog_utils.c
+++ b/src/dialog/SDL_dialog_utils.c
@@ -27,7 +27,8 @@ char *convert_filters(const SDL_DialogFileFilter *filters, int nfilters,
const char *separator, const char *suffix,
const char *filt_prefix, const char *filt_separator,
const char *filt_suffix, const char *ext_prefix,
- const char *ext_separator, const char *ext_suffix)
+ const char *ext_separator, const char *ext_suffix,
+ bool anycase)
{
char *combined;
char *new_combined;
@@ -52,7 +53,7 @@ char *convert_filters(const SDL_DialogFileFilter *filters, int nfilters,
converted = convert_filter(*f, ntf, filt_prefix, filt_separator,
filt_suffix, ext_prefix, ext_separator,
- ext_suffix);
+ ext_suffix, anycase);
if (!converted) {
SDL_free(combined);
@@ -97,7 +98,8 @@ char *convert_filters(const SDL_DialogFileFilter *filters, int nfilters,
char *convert_filter(SDL_DialogFileFilter filter, NameTransform ntf,
const char *prefix, const char *separator,
const char *suffix, const char *ext_prefix,
- const char *ext_separator, const char *ext_suffix)
+ const char *ext_separator, const char *ext_suffix,
+ bool anycase)
{
char *converted;
char *name_filtered;
@@ -105,7 +107,7 @@ char *convert_filter(SDL_DialogFileFilter filter, NameTransform ntf,
char *list;
list = convert_ext_list(filter.pattern, ext_prefix, ext_separator,
- ext_suffix);
+ ext_suffix, anycase);
if (!list) {
return NULL;
@@ -145,7 +147,7 @@ char *convert_filter(SDL_DialogFileFilter filter, NameTransform ntf,
}
char *convert_ext_list(const char *list, const char *prefix,
- const char *separator, const char *suffix)
+ const char *separator, const char *suffix, bool anycase)
{
char *converted;
int semicolons;
@@ -158,7 +160,7 @@ char *convert_ext_list(const char *list, const char *prefix,
}
total_length =
- SDL_strlen(list) - semicolons // length of list contents
+ (SDL_strlen(list) - semicolons) * 4 // length of list contents (including "a" -> "[aA]")
+ semicolons * SDL_strlen(separator) // length of separators
+ SDL_strlen(prefix) + SDL_strlen(suffix) // length of prefix/suffix
+ 1; // terminating null byte
@@ -179,9 +181,17 @@ char *convert_ext_list(const char *list, const char *prefix,
SDL_strlcat(converted, "*", total_length);
} else {
for (const char *c = list; *c; c++) {
- if ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z')
- || (*c >= '0' && *c <= '9') || *c == '-' || *c == '_'
- || *c == '.') {
+ if (anycase && ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z'))) {
+ char str[5];
+ str[0] = '[';
+ str[1] = *c;
+ str[2] = *c ^ 0x20; // ASCII case toggle
+ str[3] = ']';
+ str[4] = '\0';
+ SDL_strlcat(converted, str, total_length);
+ } else if ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z')
+ || (*c >= '0' && *c <= '9') || *c == '-' || *c == '_'
+ || *c == '.') {
char str[2];
str[0] = *c;
str[1] = '\0';
diff --git a/src/dialog/SDL_dialog_utils.h b/src/dialog/SDL_dialog_utils.h
index 773fb967bce36..c1ad9237d6a52 100644
--- a/src/dialog/SDL_dialog_utils.h
+++ b/src/dialog/SDL_dialog_utils.h
@@ -37,19 +37,21 @@ char *convert_filters(const SDL_DialogFileFilter *filters, int nfilters,
const char *separator, const char *suffix,
const char *filt_prefix, const char *filt_separator,
const char *filt_suffix, const char *ext_prefix,
- const char *ext_separator, const char *ext_suffix);
+ const char *ext_separator, const char *ext_suffix,
+ bool anycase);
// Converts one filter into a single string.
// <prefix>[filter name]<separator>[filter extension list]<suffix>
char *convert_filter(SDL_DialogFileFilter filter, NameTransform ntf,
const char *prefix, const char *separator,
const char *suffix, const char *ext_prefix,
- const char *ext_separator, const char *ext_suffix);
+ const char *ext_separator, const char *ext_suffix,
+ bool anycase);
// Converts the extension list of a filter into a single string.
// <prefix>[extension]{<separator>[extension]...}<suffix>
char *convert_ext_list(const char *list, const char *prefix,
- const char *separator, const char *suffix);
+ const char *separator, const char *suffix, bool anycase);
/* Must be used if convert_* functions aren't used */
// Returns an error message if there's a problem, NULL otherwise
diff --git a/src/dialog/unix/SDL_zenitydialog.c b/src/dialog/unix/SDL_zenitydialog.c
index 6cd310ed93477..7478a4821744f 100644
--- a/src/dialog/unix/SDL_zenitydialog.c
+++ b/src/dialog/unix/SDL_zenitydialog.c
@@ -192,7 +192,7 @@ static zenityArgs *create_zenity_args(SDL_FileDialogType type, SDL_DialogFileCal
char *filter_str = convert_filter(filters[i],
zenity_clean_name,
"--file-filter=", " | ", "",
- "*.", " *.", "");
+ "*.", " *.", "", true);
if (!filter_str) {
while (i--) {
diff --git a/src/dialog/windows/SDL_windowsdialog.c b/src/dialog/windows/SDL_windowsdialog.c
index 400fcf03ad1f1..99a49384d6e8a 100644
--- a/src/dialog/windows/SDL_windowsdialog.c
+++ b/src/dialog/windows/SDL_windowsdialog.c
@@ -1143,7 +1143,7 @@ wchar_t *win_get_filters(const SDL_DialogFileFilter *filters, int nfilters)
// suffix needs two null bytes in case the filter list is empty
char *filterlist = convert_filters(filters, nfilters, clear_filt_names,
"", "", "\x01\x01", "", "\x01",
- "\x01", "*.", ";*.", "");
+ "\x01", "*.", ";*.", "", false);
if (!filterlist) {
return NULL;