curl_free() doesn't free(NULL) but just returns
[platform/upstream/curl.git] / lib / escape.c
1 /***************************************************************************
2  *                                  _   _ ____  _     
3  *  Project                     ___| | | |  _ \| |    
4  *                             / __| | | | |_) | |    
5  *                            | (__| |_| |  _ <| |___ 
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at http://curl.haxx.se/docs/copyright.html.
13  * 
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  * $Id$
22  ***************************************************************************/
23
24 /* Escape and unescape URL encoding in strings. The functions return a new
25  * allocated string or NULL if an error occurred.  */
26
27 #include "setup.h"
28 #include <ctype.h>
29 #include <curl/curl.h>
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include "memory.h"
35
36 /* The last #include file should be: */
37 #include "memdebug.h"
38
39 char *curl_escape(const char *string, int length)
40 {
41   size_t alloc = (length?(size_t)length:strlen(string))+1;  
42   char *ns;
43   char *testing_ptr = NULL;
44   unsigned char in;
45   size_t newlen = alloc;
46   int strindex=0;
47
48   ns = malloc(alloc);
49   if(!ns)
50     return NULL;
51
52   length = alloc-1;
53   while(length--) {
54     in = *string;
55     if(!(in >= 'a' && in <= 'z') &&
56        !(in >= 'A' && in <= 'Z') &&
57        !(in >= '0' && in <= '9')) {
58       /* encode it */
59       newlen += 2; /* the size grows with two, since this'll become a %XX */
60       if(newlen > alloc) {
61         alloc *= 2;
62         testing_ptr = realloc(ns, alloc);
63         if(!testing_ptr) {
64           free( ns );
65           return NULL;
66         }
67         else {
68           ns = testing_ptr;
69         }
70       }
71       sprintf(&ns[strindex], "%%%02X", in);
72
73       strindex+=3;
74     }
75     else {
76       /* just copy this */
77       ns[strindex++]=in;
78     }
79     string++;
80   }
81   ns[strindex]=0; /* terminate it */
82   return ns;
83 }
84
85 #define ishex(in) ((in >= 'a' && in <= 'f') || \
86                    (in >= 'A' && in <= 'F') || \
87                    (in >= '0' && in <= '9'))
88
89 char *curl_unescape(const char *string, int length)
90 {
91   int alloc = (length?length:(int)strlen(string))+1;
92   char *ns = malloc(alloc);
93   unsigned char in;
94   int strindex=0;
95   long hex;
96  
97   if( !ns )
98     return NULL;
99   
100   while(--alloc > 0) {
101     in = *string;
102     if(('%' == in) && ishex(string[1]) && ishex(string[2])) {
103       /* this is two hexadecimal digits following a '%' */
104       char hexstr[3];
105       char *ptr;
106       hexstr[0] = string[1];
107       hexstr[1] = string[2];
108       hexstr[2] = 0;
109
110       hex = strtol(hexstr, &ptr, 16);
111
112       in = (unsigned char)hex; /* this long is never bigger than 255 anyway */
113       string+=2;
114       alloc-=2;
115     }
116     
117     ns[strindex++] = in;
118     string++;
119   }
120   ns[strindex]=0; /* terminate it */
121   return ns;
122 }
123
124 /* For operating systems/environments that use different malloc/free
125    ssystems for the app and for this library, we provide a free that uses
126    the library's memory system */
127 void curl_free(void *p)
128 {
129   if(p)
130     free(p);
131 }