]> git.sesse.net Git - vlc/blobdiff - include/vlc_url.h
*Really* fix base 64 encoding
[vlc] / include / vlc_url.h
index 280864dc10c39a3db0a7883fef8e468b1a85af16..d7e40d06d53523df601723442becf604e79dcb0f 100644 (file)
@@ -171,85 +171,14 @@ static inline void vlc_UrlClean( vlc_url_t *url )
 
 VLC_EXPORT( char *, unescape_URI_duplicate, ( const char *psz ) );
 VLC_EXPORT( void, unescape_URI, ( char *psz ) );
+VLC_EXPORT( char *, decode_URI_duplicate, ( const char *psz ) );
+VLC_EXPORT( void, decode_URI, ( char *psz ) );
+VLC_EXPORT( char *, encode_URI_component, ( const char *psz ) );
 
-static inline int isurlsafe( int c )
-{
-    return ( (unsigned char)( c - 'a' ) < 26 )
-        || ( (unsigned char)( c - 'A' ) < 26 )
-        || ( (unsigned char)( c - '0' ) < 10 )
-        /* Hmm, we should not encode character that are allowed in URLs
-         * (even if they are not URL-safe), nor URL-safe characters.
-         * We still encode some of them because of Microsoft's crap browser.
-         */
-        || ( strchr( "-_.", c ) != NULL );
-}
-
-static inline char url_hexchar( int c )
-{
-    return ( c < 10 ) ? c + '0' : c + 'A' - 10;
-}
-
-/*****************************************************************************
- * vlc_UrlEncode:
- *****************************************************************************
- * perform URL encoding
- * (you do NOT want to do URL decoding - it is not reversible - do NOT do it)
- *****************************************************************************/
 static inline char *vlc_UrlEncode( const char *psz_url )
 {
-    char psz_enc[3 * strlen( psz_url ) + 1], *out = psz_enc;
-    const unsigned char *in;
-
-    for( in = (const unsigned char *)psz_url; *in; in++ )
-    {
-        unsigned char c = *in;
-
-        if( isurlsafe( c ) )
-            *out++ = (char)c;
-        else
-        {
-            uint16_t cp;
-
-            *out++ = '%';
-            /* UTF-8 to UCS-2 conversion */
-            if( ( c & 0x7f ) == 0 )
-                cp = c;
-            else
-            if( ( c & 0xe0 ) == 0xc0 )
-            {
-                cp = ((c & 0x1f) << 6) | (in[1] & 0x3f);
-                in++;
-            }
-            else
-            if( ( c & 0xf0 ) == 0xe0 )
-            {
-                cp = ((c & 0xf) << 12) | ((in[1] & 0x3f) << 6) | (in[2] & 0x3f);
-                in += 2;
-            }
-            else
-                /* cannot URL-encode code points outside the BMP */
-                return NULL;
-
-            if( cp < 0xff )
-            {
-                /* Encode ISO-8859-1 characters */
-                *out++ = url_hexchar( cp >> 4 );
-                *out++ = url_hexchar( cp & 0xf );
-            }
-            else
-            {
-                /* Encode non-Latin-1 characters */
-                *out++ = 'u';
-                *out++ = url_hexchar( cp >> 12       );
-                *out++ = url_hexchar((cp >>  8) & 0xf );
-                *out++ = url_hexchar((cp >>  4) & 0xf );
-                *out++ = url_hexchar( cp        & 0xf );
-            }
-        }
-    }
-    *out++ = '\0';
-
-    return strdup( psz_enc );
+    /* FIXME: do not encode / : ? and & _when_ not needed */
+    return encode_URI_component( psz_url );
 }
 
 /*****************************************************************************
@@ -274,7 +203,10 @@ static inline int vlc_UrlIsNotEncoded( const char *psz_url )
             ptr += 2;
         }
         else
-        if( !isurlsafe( c ) )
+        if(  ( (unsigned char)( c - 'a' ) < 26 )
+          || ( (unsigned char)( c - 'A' ) < 26 )
+          || ( (unsigned char)( c - '0' ) < 10 )
+          || ( strchr( "-_.", c ) != NULL ) )
             return 1;
     }
     return 0; /* looks fine - but maybe it is not encoded */
@@ -285,11 +217,12 @@ static inline int vlc_UrlIsNotEncoded( const char *psz_url )
  *****************************************************************************
  *
  *****************************************************************************/
-static inline char *vlc_b64_encode( char *src )
+static inline char *vlc_b64_encode( const char *src )
 {
     static const char b64[] =
            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     size_t len = strlen( src );
+    const uint8_t *in = (const uint8_t *)src;
 
     char *ret;
     char *dst = (char *)malloc( ( len + 4 ) * 4 / 3 );
@@ -300,38 +233,29 @@ static inline char *vlc_b64_encode( char *src )
 
     while( len > 0 )
     {
-        /* pops (up to) 3 bytes of input */
-        uint32_t v = *src++ << 24;
+        /* pops (up to) 3 bytes of input, push 4 bytes */
+        uint32_t v = *in++ << 24; // 1/3
+        *dst++ = b64[v >> 26]; // 1/4
+        v = v << 6;
 
         if( len >= 2 )
-        {
-            v |= *src++ << 16;
-            if( len >= 3 )
-                v |= *src++ << 8;
-        }
+            v |= *in++ << 22; // 2/3
+        *dst++ = b64[v >> 26]; // 2/4
+        v = v << 6;
 
-        /* pushes (up to) 4 bytes of output */
-        while( v )
-        {
-            *dst++ = b64[v >> 26];
-            v = v << 6;
-        }
+        if( len >= 3 )
+            v |= *in++ << 20; // 3/3
+        *dst++ = ( len >= 2 ) ? b64[v >> 26] : '='; // 3/4
+        v = v << 6;
+
+        *dst++ = ( len >= 3 ) ? b64[v >> 26] : '='; // 4/4
 
-        switch( len )
+        len--;
+        if( len > 0 )
         {
-            case 1:
-                *dst++ = '=';
-                *dst++ = '=';
+            len--;
+            if( len > 0 )
                 len--;
-                break;
-
-            case 2:
-                *dst++ = '=';
-                len -= 2;
-                break;
-
-            default:
-                len -= 3;
         }
     }