From dbe8db505c6e8b5ece0e9d8506bd49e37d78bed9 Mon Sep 17 00:00:00 2001 From: Luca Bacci Date: Thu, 20 Feb 2025 15:50:19 +0100 Subject: [PATCH 1/2] splitPath: Do not rely on basename Getting the basename is not well defined on Windows for paths like: "C:", "C:\\". GLib::path_get_basename() returns "\\", and os.path.basename(), pathlib.Path.name() (from Python) return an empty string. This leaves the drive letter out of the returned path components. --- src/io/fix-broken-links.cpp | 41 ++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/io/fix-broken-links.cpp b/src/io/fix-broken-links.cpp index bcd96b7abe..d0840bff7b 100644 --- a/src/io/fix-broken-links.cpp +++ b/src/io/fix-broken-links.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -31,26 +32,32 @@ namespace Inkscape { -std::vector splitPath( std::string const &path ) +std::vector splitPath( std::string const &path_ ) { - std::vector parts; - - std::string prior; - std::string tmp = path; - while ( !tmp.empty() && (tmp != prior) ) { - prior = tmp; - - parts.push_back( Glib::path_get_basename(tmp) ); - tmp = Glib::path_get_dirname(tmp); - } - if ( !parts.empty() ) { - std::reverse(parts.begin(), parts.end()); - if ( (parts[0] == ".") && (path[0] != '.') ) { - parts.erase(parts.begin()); - } + std::string path(path_); + std::vector result; + char **parts; +#ifdef _WIN32 + const char *separator = "\\"; +#else + const char *separator = "/"; +#endif + +#ifdef _WIN32 + std::replace(path.begin(), path.end(), '/', '\\'); +#endif + + parts = g_strsplit (path.c_str(), separator, -1); + + for (char **iter = parts; *iter != nullptr; ++iter) { + char *p = *iter; + if (p[0] != '\0' && std::strcmp (p, ".") != 0) + result.push_back(p); } - return parts; + g_strfreev (parts); + + return result; } /** -- GitLab From c681467be18d741b64da79147ad91372be7d247b Mon Sep 17 00:00:00 2001 From: Luca Bacci Date: Thu, 20 Feb 2025 16:03:34 +0100 Subject: [PATCH 2/2] getShortenedPathMap: Do not assume that path components must differ GtkRecentManager removes duplicated entries and applies normalization, so two entries must differ in a path component. However the current code checks for a differing component only up to min(# of components of entry A, # of components of entry B). This falls apart with two entries like: - /A/B/C - /A/B/C/D/C This can only happen if a file /A/B/C has been opened, deleted by the user, and recreated as a directory. It's very rare, but better be defensive. Closes https://gitlab.com/inkscape/inkscape/-/issues/5311 --- src/io/recent-files.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/io/recent-files.cpp b/src/io/recent-files.cpp index 7eedd4bc15..10292dd9f1 100644 --- a/src/io/recent-files.cpp +++ b/src/io/recent-files.cpp @@ -134,7 +134,8 @@ std::map getShortenedPathMap(std::vector getShortenedPathMap(std::vector