Mercurial > mplayer.hg
changeset 17048:9e02b9cb171b
Fix URL escaping to correctly handle URL containing an ip6 address or
escaped special chars like & or ;
author | albeu |
---|---|
date | Sat, 26 Nov 2005 15:57:39 +0000 |
parents | d628bc96cb47 |
children | 4b04284b7a92 |
files | libmpdemux/url.c |
diffstat | 1 files changed, 65 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/libmpdemux/url.c Sat Nov 26 15:52:17 2005 +0000 +++ b/libmpdemux/url.c Sat Nov 26 15:57:39 2005 +0000 @@ -19,18 +19,11 @@ int pos1, pos2,v6addr = 0; URL_t* Curl = NULL; char *escfilename=NULL; - char *unescfilename=NULL; char *ptr1=NULL, *ptr2=NULL, *ptr3=NULL, *ptr4=NULL; int jumpSize = 3; if( url==NULL ) return NULL; - // Create temp filename space - unescfilename=malloc(strlen(url)+1); - if (!unescfilename ) { - mp_msg(MSGT_NETWORK,MSGL_FATAL,MSGTR_MemAllocFailed); - goto err_out; - } escfilename=malloc(strlen(url)*3+1); if (!escfilename ) { mp_msg(MSGT_NETWORK,MSGL_FATAL,MSGTR_MemAllocFailed); @@ -47,12 +40,7 @@ // Initialisation of the URL container members memset( Curl, 0, sizeof(URL_t) ); - //create unescaped/escaped versions of url - url_unescape_string(unescfilename,url); // this is to prevent us from escaping an unescaped string - // violating RFC 2396 - url_escape_string(escfilename,unescfilename); - free(unescfilename); - unescfilename = NULL; + url_escape_string(escfilename,url); // Copy the url in the URL container Curl->url = strdup(escfilename); @@ -198,7 +186,6 @@ return Curl; err_out: if (escfilename) free(escfilename); - if (unescfilename) free(unescfilename); if (Curl) url_free(Curl); return NULL; } @@ -243,10 +230,8 @@ *outbuf++='\0'; //add nullterm to string } -/* Replace specific characters in the URL string by an escape sequence */ -/* works like strcpy(), but without return argument */ -void -url_escape_string(char *outbuf, const char *inbuf) { +static void +url_escape_string_part(char *outbuf, const char *inbuf) { unsigned char c,c1,c2; int i,len=strlen(inbuf); @@ -261,12 +246,7 @@ if( (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || - (c >= 0x7f) || /* fareast languages(Chinese, Korean, Japanese) */ - c=='-' || c=='_' || c=='.' || c=='!' || c=='~' || /* mark characters */ - c=='*' || c=='\'' || c=='(' || c==')' || /* do not touch escape character */ - c==';' || c=='/' || c=='?' || c==':' || c=='@' || /* reserved characters */ - c=='&' || c=='=' || c=='+' || c=='$' || c==',' || /* see RFC 2396 */ - c=='\0' ) { /* string term char */ + (c >= 0x7f)) { *outbuf++ = c; } else if ( c=='%' && ((c1 >= '0' && c1 <= '9') || (c1 >= 'A' && c1 <= 'F')) && ((c2 >= '0' && c2 <= '9') || (c2 >= 'A' && c2 <= 'F'))) { @@ -293,6 +273,67 @@ *outbuf++='\0'; } +/* Replace specific characters in the URL string by an escape sequence */ +/* works like strcpy(), but without return argument */ +void +url_escape_string(char *outbuf, const char *inbuf) { + unsigned char c; + int i = 0,j,len = strlen(inbuf); + char* tmp,*unesc = NULL, *in; + + // Look if we have an ip6 address, if so skip it there is + // no need to escape anything in there. + tmp = strstr(inbuf,"://["); + if(tmp) { + tmp = strchr(tmp+4,']'); + if(tmp && (tmp[1] == '/' || tmp[1] == ':' || + tmp[1] == '\0')) { + i = tmp+1-inbuf; + strncpy(outbuf,inbuf,i); + outbuf += i; + tmp = NULL; + } + } + + while(i < len) { + // look for the next char that must be kept + for (j=i;j<len;j++) { + c = inbuf[j]; + if(c=='-' || c=='_' || c=='.' || c=='!' || c=='~' || /* mark characters */ + c=='*' || c=='\'' || c=='(' || c==')' || /* do not touch escape character */ + c==';' || c=='/' || c=='?' || c==':' || c=='@' || /* reserved characters */ + c=='&' || c=='=' || c=='+' || c=='$' || c==',') /* see RFC 2396 */ + break; + } + // we are on a reserved char, write it out + if(j == i) { + *outbuf++ = c; + i++; + continue; + } + // we found one, take that part of the string + if(j < len) { + if(!tmp) tmp = malloc(len+1); + strncpy(tmp,inbuf+i,j-i); + tmp[j-i] = '\0'; + in = tmp; + } else // take the rest of the string + in = (char*)inbuf+i; + + if(!unesc) unesc = malloc(len+1); + // unescape first to avoid escaping escape + url_unescape_string(unesc,in); + // then escape, including mark and other reserved chars + // that can come from escape sequences + url_escape_string_part(outbuf,unesc); + outbuf += strlen(outbuf); + i += strlen(in); + } + *outbuf = '\0'; + if(tmp) free(tmp); + if(unesc) free(unesc); +} + #ifdef __URL_DEBUG void url_debug(const URL_t *url) {