From 099ed4eb80a69d1cd1c8294d6c433ee51c609bb5 Mon Sep 17 00:00:00 2001 From: Zachary Hall Date: Thu, 20 Jul 2023 09:53:19 -0700 Subject: [PATCH] URL decode file paths --- file_browser.cpp | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/file_browser.cpp b/file_browser.cpp index 73ba71c..861fc2b 100644 --- a/file_browser.cpp +++ b/file_browser.cpp @@ -1,6 +1,7 @@ #include "file_browser.h" -#include "imfilebrowser.h" - +#include +#include +#include FileBrowser::FileBrowser(bool save, ImGuiFileBrowserFlags extra_fallback_flags) { #ifdef PORTALS @@ -82,6 +83,26 @@ void FileBrowser::Open() { #endif } #ifdef PORTALS +path url_decode(string str) { + static const string file_proto = "file://"; + if (str.starts_with(file_proto)) { + str = str.substr(file_proto.length()); + } + string ret; + int len = str.length(); + for (int i = 0; i < len; i++) { + if (str[i] != '%') { + // Don't decode '+' as a space as libportal doesn't encode space as '+', and encodes '+' in a file path verbatim + ret += str[i]; + } else { + unsigned int ch_int; + sscanf(str.substr(i + 1, 2).c_str(), "%x", &ch_int); + ret += static_cast(ch_int); + i = i + 2; + } + } + return ret; +} void FileBrowser::FileBrowserOpenCallback(GObject *src, GAsyncResult *res, gpointer data) { (void)src; FileBrowser *self = (FileBrowser*)data; @@ -102,12 +123,9 @@ void FileBrowser::FileBrowserOpenCallback(GObject *src, GAsyncResult *res, gpoin c_str_vec.push_back('\0'); const char *c_str = c_str_vec.data(); printf("Selected file %s\n", c_str); - string str = c_str; - if (str.starts_with("file://")) { - str = str.substr(string("file://").length()); - } + path path = url_decode(c_str); self->open = false; - self->selected.emplace(path(str)); + self->selected.emplace(path); } void FileBrowser::FileBrowserSaveCallback(GObject *src, GAsyncResult *res, gpointer data) { @@ -130,12 +148,9 @@ void FileBrowser::FileBrowserSaveCallback(GObject *src, GAsyncResult *res, gpoin c_str_vec.push_back('\0'); const char *c_str = c_str_vec.data(); printf("Selected file %s\n", c_str); - string str = c_str; - if (str.starts_with("file://")) { - str = str.substr(string("file://").length()); - } + path path = url_decode(c_str); self->open = false; - self->selected.emplace(path(str)); + self->selected.emplace(path); } #endif