From 9703a401c5ac3f679503b845805fe24db22c458c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 18 Oct 2017 10:05:26 +0200 Subject: [PATCH] Playlist{File,Save}: always use UTF-8 in playlists on Windows Turns out that using CP_ACP is a lousy idea, because only very few Unicode characters can be represented by it. Instead, switch to UTF-8 (which every sane person on other operating system already uses). Closes #102 --- NEWS | 1 + src/PlaylistFile.cxx | 11 +++++------ src/PlaylistSave.cxx | 10 ++++++++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 25bf749f5..2ad95f03d 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ ver 0.20.11 (not yet released) - gme: fix track numbering * improve random song order when switching songs manually * fix case insensitive search without libicu +* fix Unicode file names in playlists on Windows * fix endless loop when accessing malformed file names in ZIP files ver 0.20.10 (2017/08/24) diff --git a/src/PlaylistFile.cxx b/src/PlaylistFile.cxx index 2deae4321..c1fcdeb3c 100644 --- a/src/PlaylistFile.cxx +++ b/src/PlaylistFile.cxx @@ -207,13 +207,12 @@ try { continue; #ifdef _UNICODE - wchar_t buffer[MAX_PATH]; - auto result = MultiByteToWideChar(CP_ACP, 0, s, -1, - buffer, ARRAY_SIZE(buffer)); - if (result <= 0) + /* on Windows, playlists always contain UTF-8, because + its "narrow" charset (i.e. CP_ACP) is incapable of + storing all Unicode paths */ + const auto path = AllocatedPath::FromUTF8(s); + if (path.IsNull()) continue; - - const Path path = Path::FromFS(buffer); #else const Path path = Path::FromFS(s); #endif diff --git a/src/PlaylistSave.cxx b/src/PlaylistSave.cxx index 88d8cbe74..d3ec30bb2 100644 --- a/src/PlaylistSave.cxx +++ b/src/PlaylistSave.cxx @@ -28,7 +28,6 @@ #include "fs/AllocatedPath.hxx" #include "fs/Traits.hxx" #include "fs/FileSystem.hxx" -#include "fs/NarrowPath.hxx" #include "fs/io/FileOutputStream.hxx" #include "fs/io/BufferedOutputStream.hxx" #include "util/UriUtil.hxx" @@ -38,7 +37,14 @@ static void playlist_print_path(BufferedOutputStream &os, const Path path) { - os.Format("%s\n", NarrowPath(path).c_str()); +#ifdef _UNICODE + /* on Windows, playlists always contain UTF-8, because its + "narrow" charset (i.e. CP_ACP) is incapable of storing all + Unicode paths */ + os.Format("%s\n", path.ToUTF8().c_str()); +#else + os.Format("%s\n", path.c_str()); +#endif } void