escape.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                  _   _ ____  _
00003  *  Project                     ___| | | |  _ \| |
00004  *                             / __| | | | |_) | |
00005  *                            | (__| |_| |  _ <| |___
00006  *                             \___|\___/|_| \_\_____|
00007  *
00008  * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
00009  *
00010  * This software is licensed as described in the file COPYING, which
00011  * you should have received as part of this distribution. The terms
00012  * are also available at https://curl.haxx.se/docs/copyright.html.
00013  *
00014  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
00015  * copies of the Software, and permit persons to whom the Software is
00016  * furnished to do so, under the terms of the COPYING file.
00017  *
00018  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
00019  * KIND, either express or implied.
00020  *
00021  ***************************************************************************/
00022 
00023 /* Escape and unescape URL encoding in strings. The functions return a new
00024  * allocated string or NULL if an error occurred.  */
00025 
00026 #include "curl_setup.h"
00027 
00028 #include <curl/curl.h>
00029 
00030 #include "urldata.h"
00031 #include "warnless.h"
00032 #include "non-ascii.h"
00033 #include "escape.h"
00034 #include "strdup.h"
00035 /* The last 3 #include files should be in this order */
00036 #include "curl_printf.h"
00037 #include "curl_memory.h"
00038 #include "memdebug.h"
00039 
00040 /* Portable character check (remember EBCDIC). Do not use isalnum() because
00041    its behavior is altered by the current locale.
00042    See https://tools.ietf.org/html/rfc3986#section-2.3
00043 */
00044 static bool Curl_isunreserved(unsigned char in)
00045 {
00046   switch(in) {
00047     case '0': case '1': case '2': case '3': case '4':
00048     case '5': case '6': case '7': case '8': case '9':
00049     case 'a': case 'b': case 'c': case 'd': case 'e':
00050     case 'f': case 'g': case 'h': case 'i': case 'j':
00051     case 'k': case 'l': case 'm': case 'n': case 'o':
00052     case 'p': case 'q': case 'r': case 's': case 't':
00053     case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
00054     case 'A': case 'B': case 'C': case 'D': case 'E':
00055     case 'F': case 'G': case 'H': case 'I': case 'J':
00056     case 'K': case 'L': case 'M': case 'N': case 'O':
00057     case 'P': case 'Q': case 'R': case 'S': case 'T':
00058     case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
00059     case '-': case '.': case '_': case '~':
00060       return TRUE;
00061     default:
00062       break;
00063   }
00064   return FALSE;
00065 }
00066 
00067 /* for ABI-compatibility with previous versions */
00068 char *curl_escape(const char *string, int inlength)
00069 {
00070   return curl_easy_escape(NULL, string, inlength);
00071 }
00072 
00073 /* for ABI-compatibility with previous versions */
00074 char *curl_unescape(const char *string, int length)
00075 {
00076   return curl_easy_unescape(NULL, string, length, NULL);
00077 }
00078 
00079 char *curl_easy_escape(struct Curl_easy *data, const char *string,
00080                        int inlength)
00081 {
00082   size_t alloc;
00083   char *ns;
00084   char *testing_ptr = NULL;
00085   unsigned char in; /* we need to treat the characters unsigned */
00086   size_t newlen;
00087   size_t strindex=0;
00088   size_t length;
00089   CURLcode result;
00090 
00091   if(inlength < 0)
00092     return NULL;
00093 
00094   alloc = (inlength?(size_t)inlength:strlen(string))+1;
00095   newlen = alloc;
00096 
00097   ns = malloc(alloc);
00098   if(!ns)
00099     return NULL;
00100 
00101   length = alloc-1;
00102   while(length--) {
00103     in = *string;
00104 
00105     if(Curl_isunreserved(in))
00106       /* just copy this */
00107       ns[strindex++]=in;
00108     else {
00109       /* encode it */
00110       newlen += 2; /* the size grows with two, since this'll become a %XX */
00111       if(newlen > alloc) {
00112         alloc *= 2;
00113         testing_ptr = Curl_saferealloc(ns, alloc);
00114         if(!testing_ptr)
00115           return NULL;
00116         else {
00117           ns = testing_ptr;
00118         }
00119       }
00120 
00121       result = Curl_convert_to_network(data, &in, 1);
00122       if(result) {
00123         /* Curl_convert_to_network calls failf if unsuccessful */
00124         free(ns);
00125         return NULL;
00126       }
00127 
00128       snprintf(&ns[strindex], 4, "%%%02X", in);
00129 
00130       strindex+=3;
00131     }
00132     string++;
00133   }
00134   ns[strindex]=0; /* terminate it */
00135   return ns;
00136 }
00137 
00138 /*
00139  * Curl_urldecode() URL decodes the given string.
00140  *
00141  * Optionally detects control characters (byte codes lower than 32) in the
00142  * data and rejects such data.
00143  *
00144  * Returns a pointer to a malloced string in *ostring with length given in
00145  * *olen. If length == 0, the length is assumed to be strlen(string).
00146  *
00147  */
00148 CURLcode Curl_urldecode(struct Curl_easy *data,
00149                         const char *string, size_t length,
00150                         char **ostring, size_t *olen,
00151                         bool reject_ctrl)
00152 {
00153   size_t alloc = (length?length:strlen(string))+1;
00154   char *ns = malloc(alloc);
00155   unsigned char in;
00156   size_t strindex=0;
00157   unsigned long hex;
00158   CURLcode result;
00159 
00160   if(!ns)
00161     return CURLE_OUT_OF_MEMORY;
00162 
00163   while(--alloc > 0) {
00164     in = *string;
00165     if(('%' == in) && (alloc > 2) &&
00166        ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
00167       /* this is two hexadecimal digits following a '%' */
00168       char hexstr[3];
00169       char *ptr;
00170       hexstr[0] = string[1];
00171       hexstr[1] = string[2];
00172       hexstr[2] = 0;
00173 
00174       hex = strtoul(hexstr, &ptr, 16);
00175 
00176       in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */
00177 
00178       result = Curl_convert_from_network(data, &in, 1);
00179       if(result) {
00180         /* Curl_convert_from_network calls failf if unsuccessful */
00181         free(ns);
00182         return result;
00183       }
00184 
00185       string+=2;
00186       alloc-=2;
00187     }
00188 
00189     if(reject_ctrl && (in < 0x20)) {
00190       free(ns);
00191       return CURLE_URL_MALFORMAT;
00192     }
00193 
00194     ns[strindex++] = in;
00195     string++;
00196   }
00197   ns[strindex]=0; /* terminate it */
00198 
00199   if(olen)
00200     /* store output size */
00201     *olen = strindex;
00202 
00203   /* store output string */
00204   *ostring = ns;
00205 
00206   return CURLE_OK;
00207 }
00208 
00209 /*
00210  * Unescapes the given URL escaped string of given length. Returns a
00211  * pointer to a malloced string with length given in *olen.
00212  * If length == 0, the length is assumed to be strlen(string).
00213  * If olen == NULL, no output length is stored.
00214  */
00215 char *curl_easy_unescape(struct Curl_easy *data, const char *string,
00216                          int length, int *olen)
00217 {
00218   char *str = NULL;
00219   if(length >= 0) {
00220     size_t inputlen = length;
00221     size_t outputlen;
00222     CURLcode res = Curl_urldecode(data, string, inputlen, &str, &outputlen,
00223                                   FALSE);
00224     if(res)
00225       return NULL;
00226 
00227     if(olen) {
00228       if(outputlen <= (size_t) INT_MAX)
00229         *olen = curlx_uztosi(outputlen);
00230       else
00231         /* too large to return in an int, fail! */
00232         Curl_safefree(str);
00233     }
00234   }
00235   return str;
00236 }
00237 
00238 /* For operating systems/environments that use different malloc/free
00239    systems for the app and for this library, we provide a free that uses
00240    the library's memory system */
00241 void curl_free(void *p)
00242 {
00243   free(p);
00244 }


rc_visard_driver
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Ruess
autogenerated on Thu Jun 6 2019 20:43:02