Commit 8f390d8e authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Fix lame encoded URL decoder (closes #613)

parent fa37652a
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* *
* Authors: Antoine Cellerier <dionoea at videolan dot org> * Authors: Antoine Cellerier <dionoea at videolan dot org>
* Daniel Stranger <vlc at schmaller dot de> * Daniel Stranger <vlc at schmaller dot de>
* Rémi Denis-Courmont <rem # videolan org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -25,9 +26,11 @@ ...@@ -25,9 +26,11 @@
/***************************************************************************** /*****************************************************************************
* Preamble * Preamble
*****************************************************************************/ *****************************************************************************/
#include <vlc/vlc.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h>
#include "vlc_strings.h" #include "vlc_strings.h"
...@@ -48,38 +51,70 @@ char *decode_encoded_URI_duplicate( const char *psz ) ...@@ -48,38 +51,70 @@ char *decode_encoded_URI_duplicate( const char *psz )
*/ */
void decode_encoded_URI( char *psz ) void decode_encoded_URI( char *psz )
{ {
char *dup = strdup( psz ); unsigned char *in = (unsigned char *)psz, *out = in, c;
char *p = dup;
while( *p ) while( ( c = *in++ ) != '\0' )
{ {
if( *p == '%' ) switch( c )
{ {
char val[3]; case '%':
p++;
if( !*p )
{ {
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; break;
} }
val[0] = *p++; case '+':
val[1] = *p++; *out++ = ' ';
val[2] = '\0'; break;
*psz++ = strtol( val, NULL, 16 ); default:
} /* Inserting non-ASCII or non-printable characters is unsafe,
else if( *p == '+' ) * and no sane browser will send these unencoded */
{ if( ( c < 32 ) || ( c > 127 ) )
*psz++ = ' '; *out++ = '?';
p++; else
} *out++ = c;
else
{
*psz++ = *p++;
} }
} }
*psz++ = '\0'; *out = '\0';
free( dup );
} }
/** /**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment