]> git.sesse.net Git - vlc/blobdiff - src/text/strings.c
IsUTF8: reject surrogates and non-Unicode code points
[vlc] / src / text / strings.c
index 1c507c0fe4523885e56644d3a575584ee050ce6a..a37fe165ead0f408ac1f694240d81a0f4fdc7c45 100644 (file)
@@ -606,8 +606,7 @@ char *str_format_time( const char *tformat )
                     if( string != NULL )                            \
                     {                                               \
                         int len = strlen( string );                 \
-                        dst = realloc( dst, i_size = i_size + len );\
-                        assert( dst );                              \
+                        dst = xrealloc( dst, i_size = i_size + len );\
                         memcpy( (dst+d), string, len );             \
                         d += len;                                   \
                         free( string );                             \
@@ -622,8 +621,7 @@ char *str_format_time( const char *tformat )
 #define INSERT_STRING_NO_FREE( string )                             \
                     {                                               \
                         int len = strlen( string );                 \
-                        dst = realloc( dst, i_size = i_size + len );\
-                        assert( dst );                              \
+                        dst = xrealloc( dst, i_size = i_size + len );\
                         memcpy( dst+d, string, len );               \
                         d += len;                                   \
                     }
@@ -1049,12 +1047,18 @@ void path_sanitize( char *str )
 #include <vlc_url.h>
 
 /**
- * Convert a file path to an URI. If already an URI, do nothing.
+ * Convert a file path to an URI.
+ * If already an URI, return a copy of the string.
+ * @path path path to convert (or URI to copy)
+ * @return a nul-terminated URI string (use free() to release it),
+ * or NULL in case of error
  */
 char *make_URI (const char *path)
 {
     if (path == NULL)
         return NULL;
+    if (!strcmp (path, "-"))
+        return strdup ("fd://0"); // standard input
     if (strstr (path, "://") != NULL)
         return strdup (path); /* Already an URI */
     /* Note: VLC cannot handle URI schemes without double slash after the
@@ -1142,3 +1146,93 @@ char *make_URI (const char *path)
             return buf;
     }
 }
+
+/**
+ * Tries to convert an URI to a local (UTF-8-encoded) file path.
+ * @param url URI to convert
+ * @return NULL on error, a nul-terminated string otherwise
+ * (use free() to release it)
+ */
+char *make_path (const char *url)
+{
+    char *ret = NULL;
+    char *end;
+
+    char *path = strstr (url, "://");
+    if (path == NULL)
+        return NULL; /* unsupported scheme or invalid syntax */
+
+    end = memchr (url, '/', path - url);
+    size_t schemelen = ((end != NULL) ? end : path) - url;
+    path += 3; /* skip "://" */
+
+    /* Remove HTML anchor if present */
+    end = strchr (path, '#');
+    if (end)
+        path = strndup (path, end - path);
+    else
+        path = strdup (path);
+    if (unlikely(path == NULL))
+        return NULL; /* boom! */
+
+    /* Decode path */
+    decode_URI (path);
+
+    if (schemelen == 4 && !strncasecmp (url, "file", 4))
+    {
+#if (DIR_SEP_CHAR != '/')
+        for (char *p = strchr (path, '/'); p; p = strchr (p, '/'))
+            *p == DIR_SEP_CHAR;
+#endif
+        if (*path == DIR_SEP_CHAR)
+            return path;
+
+        /* Local path disguised as a remote one (MacOS X) */
+        if (!strncasecmp (path, "localhost"DIR_SEP, 10))
+        {
+            memmove (path, path + 9, strlen (path + 9) + 1);
+            return path;
+        }
+
+#ifdef WIN32
+        if (*path && asprintf (&ret, "\\\\%s", path) == -1)
+            ret = NULL;
+#endif
+        /* non-local path :-( */
+    }
+    else
+    if (schemelen == 2 && !strncasecmp (url, "fd", 2))
+    {
+        int fd = strtol (path, &end, 0);
+
+        if (*end)
+            goto out;
+
+#ifndef WIN32
+        switch (fd)
+        {
+            case 0:
+                ret = strdup ("/dev/stdin");
+                break;
+            case 1:
+                ret = strdup ("/dev/stdout");
+                break;
+            case 2:
+                ret = strdup ("/dev/strerr");
+                break;
+            default:
+                if (asprintf (&ret, "/dev/fd/%d", fd) == -1)
+                    ret = NULL;
+        }
+#else
+        if (fd < 2)
+            ret = strdup ("CON");
+        else
+            ret = NULL;
+#endif
+    }
+
+out:
+    free (path);
+    return ret; /* unknown scheme */
+}