]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
channel icons: add '%U' to pass UTF-8 filenames, fixes #4755
authorJaroslav Kysela <perex@perex.cz>
Sun, 3 Dec 2017 08:47:44 +0000 (09:47 +0100)
committerJaroslav Kysela <perex@perex.cz>
Sun, 3 Dec 2017 08:59:24 +0000 (09:59 +0100)
docs/property/config_channelicon_path.md
src/channels.c
src/tvheadend.h
src/utils.c

index 15d14dd430ed3499a240c06783ab31794a9873ae..2c6f2aadcc801cc0ef17086bc3701aff55803b70 100644 (file)
@@ -4,7 +4,16 @@ The following placeholders are available:
 
 Placeholder | Function
 :----------:| --------
-**%C**      | The transliterated channel name in ASCII (safe characters, no spaces, etc. - so `Das Erste HD` will be `Das_Erste_HD`, but `WDR Köln` will be `WDR_Koln`)
-**%c**      | The channel name (URL encoded ASCII)
+**%C**      | The transliterated channel name in URL encoded ASCII with safe characters only - `WDR Köln :<>*?'"` will be `WDR%20Koln%20________`
+**%c**      | The transliterated channel name in URL encoded ASCII
+**%U**      | UTF-8 encoded URL
 
 Example: `file:///tmp/icons/%C.png` or `http://example.com/%c.png`
+
+Note: The `file://` URLs are deescaped back when used, so `%20` means space
+for the filename for example.
+
+Safety note: For the channel name, the first dot characters (possible
+hidden files or special directories) are replaced with the underscore
+character. The possible directory delimiters (slash) and the special
+character backslash are replaced with the minus character.
index 8dff4bda0ca0c794b023cf0fa80aed6d6744be5e..17a89ce31d82a8ebbb1fe1cab6f05d12c3fbb767 100644 (file)
@@ -832,8 +832,7 @@ channel_get_icon ( channel_t *ch )
       chi = strdup(chicon);
 
       /* Check for and replace placeholders */
-      if ((send = strstr(chi, "%C"))) {
-
+      if ((send = strstr(chi, "%C")) || (send = strstr(chi, "%c"))) {
         sname = intlconv_utf8safestr(intlconv_charset_id("ASCII", 1, 1),
                                      chname, strlen(chname) * 2);
         if (sname == NULL)
@@ -848,34 +847,24 @@ channel_get_icon ( channel_t *ch )
           s = sname;
           while (s && *s) {
             c = *s;
-            if (c > 122 || strchr(":<>|*?'\"", c) != NULL)
+            if (send[1] == 'C' && (c > 122 || strchr(":<>|*?'\"", c) != NULL))
               *(char *)s = '_';
             else if (config.chicon_scheme == CHICON_LOWERCASE && c >= 'A' && c <= 'Z')
               *(char *)s = c - 'A' + 'a';
             s++;
           }
         }
-
-      } else if ((send = strstr(chi, "%c"))) {
-
-        sname = intlconv_utf8safestr(intlconv_charset_id("ASCII", 1, 1),
-                                     chname, strlen(chname) * 2);
-
+      } else if ((send = strstr(chi, "%U"))) {
         if (sname == NULL)
           sname = strdup(chname);
 
         if (config.chicon_scheme == CHICON_LOWERCASE) {
-          for (s = sname; *s; s++) {
-            c = *s;
-            if (c >= 'A' && c <= 'Z')
-              *(char *)s = c - 'A' + 'a';
-          }
+          utf8_lowercase_inplace((char *)sname);
         } else if (config.chicon_scheme == CHICON_SVCNAME) {
           s = svcnamepicons(sname);
           free((char *)sname);
           sname = (char *)s;
         }
-
       } else {
         buf[0] = '\0';
         sname = NULL;
index f5b6ddc014f3e11557edc5717aae283f4d381131..d87bead40f3fcd41b96005e86cdc8c868c31f60d 100644 (file)
@@ -746,6 +746,8 @@ char *base64_encode(char *out, int out_size, const uint8_t *in, int in_size);
 
 int put_utf8(char *out, int c);
 
+char *utf8_lowercase_inplace(char *s);
+
 static inline int64_t ts_rescale(int64_t ts, int tb)
 {
   //  return (ts * tb + (tb / 2)) / 90000LL;
index c34762cf42998423313190bfc5117c751354cc94..a92d4c7dabe76a9f8539172f9530cb23c5b0badd 100644 (file)
@@ -290,6 +290,38 @@ put_utf8(char *out, int c)
   return 6;
 }
 
+char *utf8_lowercase_inplace(char *s)
+{
+  char *r = s;
+  uint8_t c;
+
+  for ( ; *s; s++) {
+    /* FIXME: this is really wrong version of lowercase for utf-8 */
+    /* but it's a deep issue with the different locale handling */
+    c = (uint8_t)*s;
+    if (c & 0x80) {
+      if ((c & 0xe0) == 0xc0) {
+        s++;
+        continue;
+      } else if ((c & 0xf0) == 0xe0) {
+        s++;
+        if (*s) s++;
+      } else if ((c & 0xf8) == 0xf0) {
+        s++;
+        if (*s) s++;
+        if (*s) s++;
+      }
+    }
+    if (c >= 'A' && c <= 'Z')
+      *(char *)s = c - 'A' + 'a';
+  }
+  return r;
+}
+
+/**
+ *
+ */
+
 static void
 sbuf_alloc_fail(int len)
 {