From b18074f8998f7aefc326e09932db37aae4f13062 Mon Sep 17 00:00:00 2001 From: Thomas Guillem Date: Tue, 14 Apr 2020 22:07:51 +0200 Subject: [PATCH] storage/curl: fix path comparison when the server escapes differently Unescape the base path and the path coming from the server (href) to fix the comparison when the server uses different escaped characters. The outputted name need to be unescaped. Doing that before or after the HrefToEscapedName() call should not change the current behavior. --- NEWS | 1 + src/storage/plugins/CurlStorage.cxx | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index 15a4fb77a..ac5656a6b 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ ver 0.21.23 (not yet released) * storage - curl: fix corrupt "href" values in the presence of XML entities + - curl: unescape "href" values * output - alsa: implement channel mapping for 5.0 and 7.0 * player diff --git a/src/storage/plugins/CurlStorage.cxx b/src/storage/plugins/CurlStorage.cxx index 9452f7e54..e47aa7ae9 100644 --- a/src/storage/plugins/CurlStorage.cxx +++ b/src/storage/plugins/CurlStorage.cxx @@ -482,7 +482,7 @@ class HttpListDirectoryOperation final : public PropfindOperation { public: HttpListDirectoryOperation(CurlGlobal &curl, const char *uri) :PropfindOperation(curl, uri, 1), - base_path(UriPathOrSlash(uri)) {} + base_path(CurlUnescape(GetEasy(), UriPathOrSlash(uri))) {} std::unique_ptr Perform() { DeferStart(); @@ -507,8 +507,7 @@ private: /* kludge: ignoring case in this comparison to avoid false negatives if the web server uses a different - case in hex digits in escaped characters; TODO: - implement properly */ + case */ path = StringAfterPrefixIgnoreCase(path, base_path.c_str()); if (path == nullptr || *path == 0) return nullptr; @@ -531,11 +530,12 @@ protected: if (r.status != 200) return; - const auto escaped_name = HrefToEscapedName(r.href.c_str()); - if (escaped_name.IsNull()) + std::string href = CurlUnescape(GetEasy(), r.href.c_str()); + const auto name = HrefToEscapedName(href.c_str()); + if (name.IsNull()) return; - entries.emplace_front(CurlUnescape(GetEasy(), escaped_name)); + entries.emplace_front(std::string(name.data, name.size)); auto &info = entries.front().info; info = StorageFileInfo(r.collection