diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2018-06-18 13:26:47 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2018-06-18 13:26:47 +0300 |
commit | 579631819f0136ab0fbb0f6c7c21265b468940dc (patch) | |
tree | 4c5ee6372525cb87827e0c09c7ffb03cc35b888a | |
parent | b66ae8259e01526bb682c5081c4c0146416f8908 (diff) |
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.
-rw-r--r-- | source/blender/blenlib/BLI_path_util.h | 1 | ||||
-rw-r--r-- | source/blender/blenlib/intern/path_util.c | 31 | ||||
-rw-r--r-- | source/blender/editors/space_file/filelist.c | 5 | ||||
-rw-r--r-- | source/blender/editors/space_file/filesel.c | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_space_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_space.c | 17 |
6 files changed, 56 insertions, 4 deletions
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h index ebdf116ba7a..b4329bf81ac 100644 --- a/source/blender/blenlib/BLI_path_util.h +++ b/source/blender/blenlib/BLI_path_util.h @@ -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(); diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index cff11ec0361..6272f2109d2 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -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. diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 658725879cb..09e2660a762 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -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; diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 4723ee07a7d..1c86ecc327b 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -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); } diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 76ec6569b82..6879c3044a6 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -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). */ diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index a3ba43db2d4..c69679185aa 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -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); |