Georg Huettenegger's patch curl-7.8.1-pre5-patch-20010819
[platform/upstream/curl.git] / lib / escape.c
1 /*****************************************************************************
2  *                                  _   _ ____  _     
3  *  Project                     ___| | | |  _ \| |    
4  *                             / __| | | | |_) | |    
5  *                            | (__| |_| |  _ <| |___ 
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * In order to be useful for every potential user, curl and libcurl are
11  * dual-licensed under the MPL and the MIT/X-derivate licenses.
12  *
13  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
14  * copies of the Software, and permit persons to whom the Software is
15  * furnished to do so, under the terms of the MPL or the MIT/X-derivate
16  * licenses. You may pick one of these licenses.
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
35 /* The last #include file should be: */
36 #ifdef MALLOCDEBUG
37 #include "memdebug.h"
38 #endif
39
40 char *curl_escape(const char *string, int length)
41 {
42   int alloc = (length?length:(int)strlen(string))+1;  
43   char *ns = malloc(alloc);
44   unsigned char in;
45   int newlen = alloc;
46   int index=0;
47
48   length = alloc-1;
49   while(length--) {
50     in = *string;
51     if(' ' == in)
52       ns[index++] = '+';
53     else if(!(in >= 'a' && in <= 'z') &&
54             !(in >= 'A' && in <= 'Z') &&
55             !(in >= '0' && in <= '9')) {
56       /* encode it */
57       newlen += 2; /* the size grows with two, since this'll become a %XX */
58       if(newlen > alloc) {
59         alloc *= 2;
60         ns = realloc(ns, alloc);
61         if(!ns)
62           return NULL;
63       }
64       sprintf(&ns[index], "%%%02X", in);
65
66       index+=3;
67     }
68     else {
69       /* just copy this */
70       ns[index++]=in;
71     }
72     string++;
73   }
74   ns[index]=0; /* terminate it */
75   return ns;
76 }
77
78 char *curl_unescape(const char *string, int length)
79 {
80   int alloc = (length?length:(int)strlen(string))+1;
81   char *ns = malloc(alloc);
82   unsigned char in;
83   int index=0;
84   unsigned int hex;
85   char querypart=FALSE; /* everything to the right of a '?' letter is
86                            the "query part" where '+' should become ' '.
87                            RFC 2316, section 3.10 */
88   
89   while(--alloc > 0) {
90     in = *string;
91     if(querypart && ('+' == in))
92       in = ' ';
93     else if(!querypart && ('?' == in)) {
94       /* we have "walked in" to the query part */
95       querypart=TRUE;
96     }
97     else if('%' == in) {
98       /* encoded part */
99       if(sscanf(string+1, "%02X", &hex)) {
100         in = hex;
101         string+=2;
102         alloc-=2;
103       }
104     }
105     
106     ns[index++] = in;
107     string++;
108   }
109   ns[index]=0; /* terminate it */
110   return ns;
111   
112 }