summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2019-07-29 09:52:18 +0200
committerMax Kellermann <max@musicpd.org>2019-07-29 09:58:53 +0200
commit90ea3bf985b94e1e2bc3dc77d79fc2f948c303b3 (patch)
tree0119032b17261ef7f317df5d832978ced9faaa95
parent83b08712481cd06c8a583a2f48b327fdd16d3442 (diff)
playlist/Song: support backslash in relative URIs
Closes https://github.com/MusicPlayerDaemon/MPD/issues/607
-rw-r--r--NEWS2
-rw-r--r--src/playlist/PlaylistSong.cxx16
-rw-r--r--test/test_translate_song.cxx20
3 files changed, 38 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index 3e81a3389..cc13617b9 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,6 @@
ver 0.21.12 (not yet released)
+* Windows
+ - support backslash in relative URIs loaded from playlists
ver 0.21.11 (2019/07/03)
* input
diff --git a/src/playlist/PlaylistSong.cxx b/src/playlist/PlaylistSong.cxx
index 7d63fe76c..543d8d96f 100644
--- a/src/playlist/PlaylistSong.cxx
+++ b/src/playlist/PlaylistSong.cxx
@@ -66,6 +66,22 @@ playlist_check_translate_song(DetachedSong &song, const char *base_uri,
base_uri = nullptr;
const char *uri = song.GetURI();
+
+#ifdef _WIN32
+ if (!PathTraitsUTF8::IsAbsolute(uri) && strchr(uri, '\\') != nullptr) {
+ /* Windows uses the backslash as path separator, but
+ the MPD protocol uses the (forward) slash by
+ definition; to allow backslashes in relative URIs
+ loaded from playlist files, this step converts all
+ backslashes to (forward) slashes */
+
+ std::string new_uri(uri);
+ std::replace(new_uri.begin(), new_uri.end(), '\\', '/');
+ song.SetURI(std::move(new_uri));
+ uri = song.GetURI();
+ }
+#endif
+
if (base_uri != nullptr && !uri_has_scheme(uri) &&
!PathTraitsUTF8::IsAbsolute(uri))
song.SetURI(PathTraitsUTF8::Build(base_uri, uri));
diff --git a/test/test_translate_song.cxx b/test/test_translate_song.cxx
index 604e0c59b..cac712785 100644
--- a/test/test_translate_song.cxx
+++ b/test/test_translate_song.cxx
@@ -270,3 +270,23 @@ TEST_F(TranslateSongTest, Relative)
insecure_loader));
EXPECT_EQ(se, ToString(song4));
}
+
+TEST_F(TranslateSongTest, Backslash)
+{
+ const SongLoader loader(reinterpret_cast<const Database *>(1),
+ storage);
+
+ DetachedSong song1("foo\\bar.ogg", MakeTag2b());
+#ifdef _WIN32
+ /* on Windows, all backslashes are converted to slashes in
+ relative paths from playlists */
+ auto se = ToString(DetachedSong(uri2, MakeTag2c()));
+ EXPECT_TRUE(playlist_check_translate_song(song1, nullptr,
+ loader));
+ EXPECT_EQ(se, ToString(song1));
+#else
+ /* backslash only supported on Windows */
+ EXPECT_FALSE(playlist_check_translate_song(song1, nullptr,
+ loader));
+#endif
+}