From 822edd448764978fae50411410bae4705b30391a Mon Sep 17 00:00:00 2001
From: jdgleaver <james@leaver.myzen.co.uk>
Date: Tue, 5 Mar 2019 15:37:50 +0000
Subject: [PATCH] Fix sorting of playlists with blank labels

---
 playlist.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 68 insertions(+), 5 deletions(-)

diff --git a/playlist.c b/playlist.c
index a4ec675a66..8911b0d4bb 100644
--- a/playlist.c
+++ b/playlist.c
@@ -1567,13 +1567,76 @@ playlist_t *playlist_init(const char *path, size_t size)
 static int playlist_qsort_func(const struct playlist_entry *a,
       const struct playlist_entry *b)
 {
-   const char *a_label = a ? a->label : NULL;
-   const char *b_label = b ? b->label : NULL;
+   char *a_str            = NULL;
+   char *b_str            = NULL;
+   char *a_fallback_label = NULL;
+   char *b_fallback_label = NULL;
+   int ret                = 0;
 
-   if (!a_label || !b_label)
-      return 0;
+   if (!a || !b)
+      goto end;
 
-   return strcasecmp(a_label, b_label);
+   a_str = a->label;
+   b_str = b->label;
+
+   /* It is quite possible for playlist labels
+    * to be blank. If that is the case, have to use
+    * filename as a fallback (this is slow, but we
+    * have no other option...) */
+   if (string_is_empty(a_str))
+   {
+      if (string_is_empty(a->path))
+         goto end;
+
+      a_fallback_label = (char*)calloc(PATH_MAX_LENGTH, sizeof(char));
+      if (!a_fallback_label)
+         goto end;
+
+      fill_short_pathname_representation(a_fallback_label, a->path, PATH_MAX_LENGTH * sizeof(char));
+
+      if (string_is_empty(a_fallback_label))
+         goto end;
+
+      a_str = a_fallback_label;
+   }
+
+   if (string_is_empty(b_str))
+   {
+      if (string_is_empty(b->path))
+         goto end;
+
+      b_fallback_label = (char*)calloc(PATH_MAX_LENGTH, sizeof(char));
+      if (!b_fallback_label)
+         goto end;
+
+      fill_short_pathname_representation(b_fallback_label, b->path, PATH_MAX_LENGTH * sizeof(char));
+
+      if (string_is_empty(b_fallback_label))
+         goto end;
+
+      b_str = b_fallback_label;
+   }
+
+   ret = strcasecmp(a_str, b_str);
+
+end:
+
+   a_str = NULL;
+   b_str = NULL;
+
+   if (a_fallback_label)
+   {
+      free(a_fallback_label);
+      a_fallback_label = NULL;
+   }
+
+   if (b_fallback_label)
+   {
+      free(b_fallback_label);
+      b_fallback_label = NULL;
+   }
+
+   return ret;
 }
 
 void playlist_qsort(playlist_t *playlist)