Fix T55503: File browser filter not working correctly.
There were two issues here, introduced by rB66aa4af836: * Forgot to change length of some filter_glob var deep in filebrowser code. * Truncating filter_glob in general can be dangerous, generating unexpected patterns. Last point was the root of the issue here, truncating to 63 chars string left last group as 'match everything' `*` pattern. To fix that to some extent, added a new BLI_path_extension_glob_validate helper to BLI_path_util, which ensures we do not have last wildcards-only group in our pattern, when there are more than one group.
This commit is contained in:
parent
b66ae8259e
commit
579631819f
@ -75,6 +75,7 @@ bool BLI_path_extension_check(const char *str, const char *ext) ATTR_NONNULL() A
|
||||
bool BLI_path_extension_check_n(const char *str, ...) ATTR_NONNULL(1) ATTR_SENTINEL(0);
|
||||
bool BLI_path_extension_check_array(const char *str, const char **ext_array) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
|
||||
bool BLI_path_extension_check_glob(const char *str, const char *ext_fnmatch) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
|
||||
bool BLI_path_extension_glob_validate(char *ext_fnmatch) ATTR_NONNULL();
|
||||
bool BLI_path_extension_replace(char *path, size_t maxlen, const char *ext) ATTR_NONNULL();
|
||||
bool BLI_path_extension_ensure(char *path, size_t maxlen, const char *ext) ATTR_NONNULL();
|
||||
bool BLI_ensure_filename(char *filepath, size_t maxlen, const char *filename) ATTR_NONNULL();
|
||||
|
@ -1438,6 +1438,37 @@ bool BLI_path_extension_check_glob(const char *str, const char *ext_fnmatch)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does basic validation of the given glob string, to prevent common issues from string truncation.
|
||||
*
|
||||
* For now, only forbids last group to be a wildcard-only one, if there are more than one group
|
||||
* (i.e. things like "*.txt;*.cpp;*" are changed to "*.txt;*.cpp;")
|
||||
*
|
||||
* \returns true if it had to modify given \a ext_fnmatch pattern.
|
||||
*/
|
||||
bool BLI_path_extension_glob_validate(char *ext_fnmatch)
|
||||
{
|
||||
bool only_wildcards = false;
|
||||
|
||||
for (size_t i = strlen(ext_fnmatch); i-- > 0; ) {
|
||||
if (ext_fnmatch[i] == ';') {
|
||||
/* Group separator, we truncate here if we only had wildcards so far. Otherwise, all is sound and fine. */
|
||||
if (only_wildcards) {
|
||||
ext_fnmatch[i] = '\0';
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (!ELEM(ext_fnmatch[i], '?', '*')) {
|
||||
/* Non-wildcard char, we can break here and consider the pattern valid. */
|
||||
return false;
|
||||
}
|
||||
/* So far, only wildcards in last group of the pattern... */
|
||||
only_wildcards = true;
|
||||
}
|
||||
/* Only one group in the pattern, so even if its only made of wildcard(s), it is assumed vaid. */
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any existing extension on the end of \a path and appends \a ext.
|
||||
|
@ -267,10 +267,11 @@ typedef struct FileListEntryPreview {
|
||||
ImBuf *img;
|
||||
} FileListEntryPreview;
|
||||
|
||||
|
||||
typedef struct FileListFilter {
|
||||
unsigned int filter;
|
||||
unsigned int filter_id;
|
||||
char filter_glob[256];
|
||||
char filter_glob[FILE_MAXFILE];
|
||||
char filter_search[66]; /* + 2 for heading/trailing implicit '*' wildcards. */
|
||||
short flags;
|
||||
} FileListFilter;
|
||||
@ -2464,7 +2465,7 @@ static void filelist_readjob_do(
|
||||
BLI_Stack *todo_dirs;
|
||||
TodoDir *td_dir;
|
||||
char dir[FILE_MAX_LIBEXTRA];
|
||||
char filter_glob[64]; /* TODO should be define! */
|
||||
char filter_glob[FILE_MAXFILE];
|
||||
const char *root = filelist->filelist.root;
|
||||
const int max_recursion = filelist->max_recursion;
|
||||
int nbr_done_dirs = 0, nbr_todo_dirs = 1;
|
||||
|
@ -196,6 +196,10 @@ short ED_fileselect_set_params(SpaceFile *sfile)
|
||||
if (tmp != params->filter_glob) {
|
||||
BLI_strncpy(params->filter_glob, tmp, sizeof(params->filter_glob));
|
||||
MEM_freeN(tmp);
|
||||
|
||||
/* Fix stupid things that truncating might have generated,
|
||||
* like last group being a 'match everything' wildcard-only one... */
|
||||
BLI_path_extension_glob_validate(params->filter_glob);
|
||||
}
|
||||
params->filter |= (FILE_TYPE_OPERATOR | FILE_TYPE_FOLDER);
|
||||
}
|
||||
|
@ -630,7 +630,7 @@ typedef struct FileSelectParams {
|
||||
char renamefile[256];
|
||||
char renameedit[256]; /* annoying but the first is only used for initialization */
|
||||
|
||||
char filter_glob[256]; /* list of filetypes to filter */
|
||||
char filter_glob[256]; /* FILE_MAXFILE */ /* list of filetypes to filter */
|
||||
|
||||
char filter_search[64]; /* text items' name must match to be shown. */
|
||||
int filter_id; /* same as filter, but for ID types (aka library groups). */
|
||||
|
@ -258,6 +258,8 @@ const EnumPropertyItem rna_enum_file_sort_items[] = {
|
||||
#include "DNA_userdef_types.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_brush.h"
|
||||
@ -1634,6 +1636,16 @@ static const EnumPropertyItem *rna_FileSelectParams_recursion_level_itemf(
|
||||
return fileselectparams_recursion_level_items;
|
||||
}
|
||||
|
||||
static void rna_FileSelectPrams_filter_glob_set(PointerRNA *ptr, const char *value)
|
||||
{
|
||||
FileSelectParams *params = ptr->data;
|
||||
|
||||
BLI_strncpy(params->filter_glob, value, sizeof(params->filter_glob));
|
||||
|
||||
/* Remove stupi things like last group being a wildcard-only one... */
|
||||
BLI_path_extension_glob_validate(params->filter_glob);
|
||||
}
|
||||
|
||||
static void rna_FileBrowser_FSMenuEntry_path_get(PointerRNA *ptr, char *value)
|
||||
{
|
||||
char *path = ED_fsmenu_entry_get_path(ptr->data);
|
||||
@ -4038,7 +4050,10 @@ static void rna_def_fileselect_params(BlenderRNA *brna)
|
||||
|
||||
prop = RNA_def_property(srna, "filter_glob", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "filter_glob");
|
||||
RNA_def_property_ui_text(prop, "Extension Filter", "");
|
||||
RNA_def_property_ui_text(prop, "Extension Filter",
|
||||
"UNIX shell-like filename patterns matching, supports wildcards ('*') "
|
||||
"and list of patterns separated by ';'");
|
||||
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_FileSelectPrams_filter_glob_set");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "filter_search", PROP_STRING, PROP_NONE);
|
||||
|
Loading…
Reference in New Issue
Block a user