/* * Curl_urldecode() URL decodes the given string. * * Optionally detects control characters (byte codes lower than 32) in the * data and rejects such data. * * Returns a pointer to a malloced string in *ostring with length given in * *olen. If length == 0, the length is assumed to be strlen(string). * */ CURLcode Curl_urldecode(struct SessionHandle *data, const char *string, size_t length, char **ostring, size_t *olen, bool reject_ctrl) { size_t alloc = (length?length:strlen(string))+1; char *ns = malloc(alloc); unsigned char in; size_t strindex=0; unsigned long hex; CURLcode res; if(!ns) return CURLE_OUT_OF_MEMORY; while(--alloc > 0) { in = *string; if(('%' == in) && (alloc > 2) && ISXDIGIT(string[1]) && ISXDIGIT(string[2])) { /* this is two hexadecimal digits following a '%' */ char hexstr[3]; char *ptr; hexstr[0] = string[1]; hexstr[1] = string[2]; hexstr[2] = 0; hex = strtoul(hexstr, &ptr, 16); in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */ res = Curl_convert_from_network(data, &in, 1); if(res) { /* Curl_convert_from_network calls failf if unsuccessful */ free(ns); return res; } string+=2; alloc-=2; } if(reject_ctrl && (in < 0x20)) { free(ns); return CURLE_URL_MALFORMAT; } ns[strindex++] = in; string++; } ns[strindex]=0; /* terminate it */ if(olen) /* store output size */ *olen = strindex; if(ostring) /* store output string */ *ostring = ns; return CURLE_OK; }
/* * Unescapes the given URL escaped string of given length. Returns a * pointer to a malloced string with length given in *olen. * If length == 0, the length is assumed to be strlen(string). * If olen == NULL, no output length is stored. */ char *curl_easy_unescape(CURL *handle, const char *string, int length, int *olen) { int alloc = (length?length:(int)strlen(string))+1; char *ns = malloc(alloc); unsigned char in; int strindex=0; unsigned long hex; #ifndef CURL_DOES_CONVERSIONS /* avoid compiler warnings */ (void)handle; #endif if( !ns ) return NULL; while(--alloc > 0) { in = *string; if(('%' == in) && ISXDIGIT(string[1]) && ISXDIGIT(string[2])) { /* this is two hexadecimal digits following a '%' */ char hexstr[3]; char *ptr; hexstr[0] = string[1]; hexstr[1] = string[2]; hexstr[2] = 0; hex = strtoul(hexstr, &ptr, 16); in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */ #ifdef CURL_DOES_CONVERSIONS /* escape sequences are always in ASCII so convert them on non-ASCII hosts */ if(!handle || (Curl_convert_from_network(handle, &in, 1) != CURLE_OK)) { /* Curl_convert_from_network calls failf if unsuccessful */ free(ns); return NULL; } #endif /* CURL_DOES_CONVERSIONS */ string+=2; alloc-=2; } ns[strindex++] = in; string++; } ns[strindex]=0; /* terminate it */ if(olen) /* store output size */ *olen = strindex; return ns; }
/* * Unescapes the given URL escaped string of given length. Returns a * pointer to a malloced string with length given in *olen. * If length == 0, the length is assumed to be strlen(string). * If olen == NULL, no output length is stored. */ char *curl_easy_unescape(CURL *handle, const char *string, int length, int *olen) { int alloc = (length?length:(int)strlen(string))+1; char *ns = malloc(alloc); unsigned char in; int strindex=0; unsigned long hex; CURLcode res; if(!ns) return NULL; while(--alloc > 0) { in = *string; if(('%' == in) && ISXDIGIT(string[1]) && ISXDIGIT(string[2])) { /* this is two hexadecimal digits following a '%' */ char hexstr[3]; char *ptr; hexstr[0] = string[1]; hexstr[1] = string[2]; hexstr[2] = 0; hex = strtoul(hexstr, &ptr, 16); in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */ res = Curl_convert_from_network(handle, &in, 1); if(res) { /* Curl_convert_from_network calls failf if unsuccessful */ free(ns); return NULL; } string+=2; alloc-=2; } ns[strindex++] = in; string++; } ns[strindex]=0; /* terminate it */ if(olen) /* store output size */ *olen = strindex; return ns; }