From: Rémi Denis-Courmont Date: Mon, 27 Mar 2006 14:47:05 +0000 (+0000) Subject: Fix lame encoded URL decoder (closes #613) X-Git-Tag: 0.9.0-test0~11749 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=8f390d8eaa598a72c79e7cce11e3442e74985775;p=vlc Fix lame encoded URL decoder (closes #613) --- diff --git a/src/misc/strings.c b/src/misc/strings.c index 645f355d59..cefe5f48b4 100644 --- a/src/misc/strings.c +++ b/src/misc/strings.c @@ -6,6 +6,7 @@ * * Authors: Antoine Cellerier * Daniel Stranger + * Rémi Denis-Courmont * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,9 +26,11 @@ /***************************************************************************** * Preamble *****************************************************************************/ +#include #include #include #include +#include #include "vlc_strings.h" @@ -48,38 +51,70 @@ char *decode_encoded_URI_duplicate( const char *psz ) */ void decode_encoded_URI( char *psz ) { - char *dup = strdup( psz ); - char *p = dup; + unsigned char *in = (unsigned char *)psz, *out = in, c; - while( *p ) + while( ( c = *in++ ) != '\0' ) { - if( *p == '%' ) + switch( c ) { - char val[3]; - p++; - if( !*p ) + case '%': { + char val[5], *pval = val; + unsigned long cp; + + switch( c = *in++ ) + { + case '\0': + return; + + case 'u': + case 'U': + if( ( *pval++ = *in++ ) == '\0' ) + return; + if( ( *pval++ = *in++ ) == '\0' ) + return; + c = *in++; + + default: + *pval++ = c; + if( ( *pval++ = *in++ ) == '\0' ) + return; + *pval = '\0'; + } + + cp = strtoul( val, NULL, 0x10 ); + if( cp < 0x80 ) + *out++ = cp; + else + if( cp < 0x800 ) + { + *out++ = (( cp >> 6) | 0xc0); + *out++ = (( cp & 0x3f) | 0x80); + } + else + { + assert( cp < 0x10000 ); + *out++ = (( cp >> 12) | 0xe0); + *out++ = (((cp >> 6) & 0x3f) | 0x80); + *out++ = (( cp & 0x3f) | 0x80); + } break; } - val[0] = *p++; - val[1] = *p++; - val[2] = '\0'; + case '+': + *out++ = ' '; + break; - *psz++ = strtol( val, NULL, 16 ); - } - else if( *p == '+' ) - { - *psz++ = ' '; - p++; - } - else - { - *psz++ = *p++; + default: + /* Inserting non-ASCII or non-printable characters is unsafe, + * and no sane browser will send these unencoded */ + if( ( c < 32 ) || ( c > 127 ) ) + *out++ = '?'; + else + *out++ = c; } } - *psz++ = '\0'; - free( dup ); + *out = '\0'; } /**