From 9703a401c5ac3f679503b845805fe24db22c458c Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
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