[Bf-blender-cvs] [7687f3ed676] temp-asset-browser-catalogs-ui: Properly null-check the asset catalog tree before accessing for UI
Julian Eisel
noreply at git.blender.org
Fri Sep 24 20:31:51 CEST 2021
Commit: 7687f3ed6768d75450f4a320c0c98392b25eec0b
Author: Julian Eisel
Date: Fri Sep 24 20:15:45 2021 +0200
Branches: temp-asset-browser-catalogs-ui
https://developer.blender.org/rB7687f3ed6768d75450f4a320c0c98392b25eec0b
Properly null-check the asset catalog tree before accessing for UI
===================================================================
A source/blender/blenlib/intern/path_util.cc
A source/blender/blenlib/intern/storage.cc
M source/blender/editors/space_file/asset_catalog_tree_view.cc
===================================================================
diff --git a/source/blender/blenlib/intern/path_util.cc b/source/blender/blenlib/intern/path_util.cc
new file mode 100644
index 00000000000..760e7910a77
--- /dev/null
+++ b/source/blender/blenlib/intern/path_util.cc
@@ -0,0 +1,2083 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ * various string, file, list operations.
+ */
+
+/** \file
+ * \ingroup bli
+ */
+
+#include <algorithm>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "DNA_listBase.h"
+
+#include "BLI_fileops.h"
+#include "BLI_fnmatch.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+#include "BLI_string_utf8.h"
+#include "BLI_utildefines.h"
+#ifdef USE_CPP_FILESYSTEM
+# include "BLI_filesystem.hh"
+#endif
+
+#ifdef WIN32
+# include "utf_winfunc.h"
+# include "utfconv.h"
+# include <io.h>
+# ifdef _WIN32_IE
+# undef _WIN32_IE
+# endif
+# define _WIN32_IE 0x0501
+# include "BLI_alloca.h"
+# include "BLI_winstuff.h"
+# include <shlobj.h>
+# include <windows.h>
+#else
+# include "unistd.h"
+#endif /* WIN32 */
+
+#include "MEM_guardedalloc.h"
+
+#ifdef USE_CPP_FILESYSTEM
+using namespace blender::bli;
+#endif
+
+/* Declarations */
+
+#ifdef WIN32
+
+/**
+ * Return true if the path is absolute ie starts with a drive specifier
+ * (eg A:\) or is a UNC path.
+ */
+static bool BLI_path_is_abs(const char *name);
+
+#endif /* WIN32 */
+
+// #define DEBUG_STRSIZE
+
+/* implementation */
+
+/**
+ * Looks for a sequence of decimal digits in string, preceding any filename extension,
+ * returning the integer value if found, or 0 if not.
+ *
+ * \param string: String to scan.
+ * \param head: Optional area to return copy of part of string prior to digits,
+ * or before dot if no digits.
+ * \param tail: Optional area to return copy of part of string following digits,
+ * or from dot if no digits.
+ * \param r_num_len: Optional to return number of digits found.
+ */
+int BLI_path_sequence_decode(const char *string, char *head, char *tail, ushort *r_num_len)
+{
+ uint nums = 0, nume = 0;
+ int i;
+ bool found_digit = false;
+ const char *const lslash = BLI_path_slash_rfind(string);
+ const uint string_len = strlen(string);
+ const uint lslash_len = lslash != NULL ? (int)(lslash - string) : 0;
+ uint name_end = string_len;
+
+ while (name_end > lslash_len && string[--name_end] != '.') {
+ /* name ends at dot if present */
+ }
+ if (name_end == lslash_len && string[name_end] != '.') {
+ name_end = string_len;
+ }
+
+ for (i = name_end - 1; i >= (int)lslash_len; i--) {
+ if (isdigit(string[i])) {
+ if (found_digit) {
+ nums = i;
+ }
+ else {
+ nume = i;
+ nums = i;
+ found_digit = true;
+ }
+ }
+ else {
+ if (found_digit) {
+ break;
+ }
+ }
+ }
+
+ if (found_digit) {
+ const long long int ret = strtoll(&(string[nums]), NULL, 10);
+ if (ret >= INT_MIN && ret <= INT_MAX) {
+ if (tail) {
+ strcpy(tail, &string[nume + 1]);
+ }
+ if (head) {
+ strcpy(head, string);
+ head[nums] = 0;
+ }
+ if (r_num_len) {
+ *r_num_len = nume - nums + 1;
+ }
+ return (int)ret;
+ }
+ }
+
+ if (tail) {
+ strcpy(tail, string + name_end);
+ }
+ if (head) {
+ /* name_end points to last character of head,
+ * make it +1 so null-terminator is nicely placed
+ */
+ BLI_strncpy(head, string, name_end + 1);
+ }
+ if (r_num_len) {
+ *r_num_len = 0;
+ }
+ return 0;
+}
+
+/**
+ * Returns in area pointed to by string a string of the form "<head><pic><tail>", where pic
+ * is formatted as numlen digits with leading zeroes.
+ */
+void BLI_path_sequence_encode(
+ char *string, const char *head, const char *tail, unsigned short numlen, int pic)
+{
+ sprintf(string, "%s%.*d%s", head, numlen, MAX2(0, pic), tail);
+}
+
+static int BLI_path_unc_prefix_len(const char *path); /* defined below in same file */
+
+/* ******************** string encoding ***************** */
+
+/**
+ * Remove redundant characters from \a path and optionally make absolute.
+ *
+ * \param relabase: The path this is relative to, or ignored when NULL.
+ * \param path: Can be any input, and this function converts it to a regular full path.
+ * Also removes garbage from directory paths, like `/../` or double slashes etc.
+ *
+ * \note \a path isn't protected for max string names...
+ */
+void BLI_path_normalize(const char *relabase, char *path)
+{
+ ptrdiff_t a;
+ char *start, *eind;
+ if (relabase) {
+ BLI_path_abs(path, relabase);
+ }
+ else {
+ if (path[0] == '/' && path[1] == '/') {
+ if (path[2] == '\0') {
+ return; /* path is "//" - can't clean it */
+ }
+ path = path + 2; /* leave the initial "//" untouched */
+ }
+ }
+
+ /* Note
+ * memmove(start, eind, strlen(eind) + 1);
+ * is the same as
+ * strcpy(start, eind);
+ * except strcpy should not be used because there is overlap,
+ * so use memmove's slightly more obscure syntax - Campbell
+ */
+
+#ifdef WIN32
+ while ((start = strstr(path, "\\..\\"))) {
+ eind = start + strlen("\\..\\") - 1;
+ a = start - path - 1;
+ while (a > 0) {
+ if (path[a] == '\\') {
+ break;
+ }
+ a--;
+ }
+ if (a < 0) {
+ break;
+ }
+ else {
+ memmove(path + a, eind, strlen(eind) + 1);
+ }
+ }
+
+ while ((start = strstr(path, "\\.\\"))) {
+ eind = start + strlen("\\.\\") - 1;
+ memmove(start, eind, strlen(eind) + 1);
+ }
+
+ /* remove two consecutive backslashes, but skip the UNC prefix,
+ * which needs to be preserved */
+ while ((start = strstr(path + BLI_path_unc_prefix_len(path), "\\\\"))) {
+ eind = start + strlen("\\\\") - 1;
+ memmove(start, eind, strlen(eind) + 1);
+ }
+#else
+ while ((start = strstr(path, "/../"))) {
+ a = start - path - 1;
+ if (a > 0) {
+ /* <prefix>/<parent>/../<postfix> => <prefix>/<postfix> */
+ eind = start + (4 - 1) /* strlen("/../") - 1 */; /* strip "/.." and keep last "/" */
+ while (a > 0 && path[a] != '/') { /* find start of <parent> */
+ a--;
+ }
+ memmove(path + a, eind, strlen(eind) + 1);
+ }
+ else {
+ /* Support for odd paths: eg `/../home/me` --> `/home/me`
+ * this is a valid path in blender but we can't handle this the usual way below
+ * simply strip this prefix then evaluate the path as usual.
+ * Python's `os.path.normpath()` does this. */
+
+ /* NOTE: previous version of following call used an offset of 3 instead of 4,
+ * which meant that the `/../home/me` example actually became `home/me`.
+ * Using offset of 3 gives behavior consistent with the aforementioned
+ * Python routine. */
+ memmove(path, path + 3, strlen(path + 3) + 1);
+ }
+ }
+
+ while ((start = strstr(path, "/./"))) {
+ eind = start + (3 - 1) /* strlen("/./") - 1 */;
+ memmove(start, eind, strlen(eind) + 1);
+ }
+
+ while ((start = strstr(path, "//"))) {
+ eind = start + (2 - 1) /* strlen("//") - 1 */;
+ memmove(start, eind, strlen(eind) + 1);
+ }
+#endif
+}
+
+/**
+ * Cleanup filepath ensuring a trailing slash.
+ */
+void BLI_path_normalize_dir(const char *relabase, char *dir)
+{
+ /* Would just create an unexpected "/" path, just early exit entirely. */
+ if (dir[0] == '\0') {
+ return;
+ }
+
+ BLI_path_normalize(relabase, dir);
+ BLI_path_slash_ensure(dir);
+}
+
+/**
+ * Make given name safe to be used in paths.
+ *
+ * \return true if \a fname was changed, false otherwise.
+ *
+ * For now, simply replaces reserved chars (as listed in
+ * https://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words )
+ * by underscores ('_').
+ *
+ * \note Space case ' ' is a bit of an edge case here - in theory it is allowed,
+ * but again can be an issue in some cases, so we simply replace it by an underscore too
+ * (good practice anyway).
+ * REMOVED based on popular demand (see T45900).
+ * Percent '%' char is a bit same case - not recommended to use it,
+ * but supported by all decent file-systems/operating-systems around.
+ *
+ * \note On Windows, it also ensures there is no '.' (dot char) at the end of the file,
+ * this can lead to issues.
+ *
+ * \note On Windows, it also checks for forbidden names
+ * (see https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx ).
+ */
+bool BLI_filename_make_safe(char *fname)
+{
+ const char *invalid =
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "/\\?*:|\"<>";
+ char *fn;
+ bool changed = false;
+
+ if (*fname == '\0') {
+ return changed;
+ }
+
+ for (fn = fname; *fn && (fn = strpbrk(fn, invalid)); fn++) {
+ *fn = '_';
+ changed = true;
+ }
+
+ /* Forbid only dots. */
+ for (fn = fname; *fn == '.'; fn++) {
+ /* pass */
+ }
+ if (*fn == '\0') {
+ *fname = '_';
+ changed = true;
+ }
+
+#ifdef WIN32
+ {
+ const size_t len = strlen(fname);
+ const char *invalid_names[] = {
+ "con", "prn", "aux", "null", "com1", "com2", "com3", "com4",
+ "com5", "com6", "com7", "com8", "com9", "lpt1", "lpt2", "lpt3",
+ "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", NULL,
+ };
+ char *lower_fname = BLI_strdup(fname);
+ const char **iname;
+
+ /* Forbid trailing dot (trailing space has already been replaced above). */
+ if (f
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list