* move some more vars from the session context to strbuf (the use of StrBufAppendTemp...
[citadel.git] / webcit / utils.c
1 /*
2  * $Id: utils.c 6808 2008-12-11 00:00:36Z dothebart $
3  *
4  * de/encoding stuff. hopefully mostly to be depricated in favour of subst.c + strbuf
5  */
6
7 #define SHOW_ME_VAPPEND_PRINTF
8 #include <stdio.h>
9 #include <stdarg.h>
10 #include "webcit.h"
11
12
13 /*   
14  * remove escaped strings from i.e. the url string (like %20 for blanks)
15  */
16 long unescape_input(char *buf)
17 {
18         unsigned int a, b;
19         char hex[3];
20         long buflen;
21         long len;
22
23         buflen = strlen(buf);
24
25         while ((buflen > 0) && (isspace(buf[buflen - 1]))){
26                 buf[buflen - 1] = 0;
27                 buflen --;
28         }
29
30         a = 0; 
31         while (a < buflen) {
32                 if (buf[a] == '+')
33                         buf[a] = ' ';
34                 if (buf[a] == '%') {
35                         /* don't let % chars through, rather truncate the input. */
36                         if (a + 2 > buflen) {
37                                 buf[a] = '\0';
38                                 buflen = a;
39                         }
40                         else {                  
41                                 hex[0] = buf[a + 1];
42                                 hex[1] = buf[a + 2];
43                                 hex[2] = 0;
44                                 b = 0;
45                                 sscanf(hex, "%02x", &b);
46                                 buf[a] = (char) b;
47                                 len = buflen - a - 2;
48                                 if (len > 0)
49                                         memmove(&buf[a + 1], &buf[a + 3], len);
50                         
51                                 buflen -=2;
52                         }
53                 }
54                 a++;
55         }
56         return a;
57 }
58
59 /*
60  * Copy a string, escaping characters which have meaning in HTML.  
61  *
62  * target              target buffer
63  * strbuf              source buffer
64  * nbsp                        If nonzero, spaces are converted to non-breaking spaces.
65  * nolinebreaks                if set, linebreaks are removed from the string.
66  */
67 long stresc(char *target, long tSize, char *strbuf, int nbsp, int nolinebreaks)
68 {
69         char *aptr, *bptr, *eptr;
70  
71         *target = '\0';
72         aptr = strbuf;
73         bptr = target;
74         eptr = target + tSize - 6; /* our biggest unit to put in...  */
75  
76  
77         while ((bptr < eptr) && !IsEmptyStr(aptr) ){
78                 if (*aptr == '<') {
79                         memcpy(bptr, "&lt;", 4);
80                         bptr += 4;
81                 }
82                 else if (*aptr == '>') {
83                         memcpy(bptr, "&gt;", 4);
84                         bptr += 4;
85                 }
86                 else if (*aptr == '&') {
87                         memcpy(bptr, "&amp;", 5);
88                         bptr += 5;
89                 }
90                 else if (*aptr == '\"') {
91                         memcpy(bptr, "&quot;", 6);
92                         bptr += 6;
93                 }
94                 else if (*aptr == '\'') {
95                         memcpy(bptr, "&#39;", 5);
96                         bptr += 5;
97                 }
98                 else if (*aptr == LB) {
99                         *bptr = '<';
100                         bptr ++;
101                 }
102                 else if (*aptr == RB) {
103                         *bptr = '>';
104                         bptr ++;
105                 }
106                 else if (*aptr == QU) {
107                         *bptr ='"';
108                         bptr ++;
109                 }
110                 else if ((*aptr == 32) && (nbsp == 1)) {
111                         memcpy(bptr, "&nbsp;", 6);
112                         bptr += 6;
113                 }
114                 else if ((*aptr == '\n') && (nolinebreaks)) {
115                         *bptr='\0';     /* nothing */
116                 }
117                 else if ((*aptr == '\r') && (nolinebreaks)) {
118                         *bptr='\0';     /* nothing */
119                 }
120                 else{
121                         *bptr = *aptr;
122                         bptr++;
123                 }
124                 aptr ++;
125         }
126         *bptr = '\0';
127         if ((bptr = eptr - 1 ) && !IsEmptyStr(aptr) )
128                 return -1;
129         return (bptr - target);
130 }
131
132
133 void escputs1(const char *strbuf, int nbsp, int nolinebreaks)
134 {
135         StrEscAppend(WC->WBuf, NULL, strbuf, nbsp, nolinebreaks);
136 }
137
138 void StrEscputs1(const StrBuf *strbuf, int nbsp, int nolinebreaks)
139 {
140         StrEscAppend(WC->WBuf, strbuf, NULL, nbsp, nolinebreaks);
141 }
142
143 /* 
144  * static wrapper for ecsputs1
145  */
146 void escputs(const char *strbuf)
147 {
148         escputs1(strbuf, 0, 0);
149 }
150
151
152 /* 
153  * static wrapper for ecsputs1
154  */
155 void StrEscPuts(const StrBuf *strbuf)
156 {
157         StrEscputs1(strbuf, 0, 0);
158 }
159
160
161 /*
162  * urlescape buffer and print it to the client
163  */
164 void urlescputs(const char *strbuf)
165 {
166         StrBufUrlescAppend(WC->WBuf, NULL, strbuf);
167 }
168
169 /*
170  * urlescape buffer and print it to the client
171  */
172 void UrlescPutStrBuf(const StrBuf *strbuf)
173 {
174         StrBufUrlescAppend(WC->WBuf, strbuf, NULL);
175 }
176
177 /**
178  * urlescape buffer and print it as header 
179  */
180 void hurlescputs(const char *strbuf) 
181 {
182         StrBufUrlescAppend(WC->HBuf, NULL, strbuf);
183 }
184
185
186 /*
187  * Copy a string, escaping characters for JavaScript strings.
188  */
189 void jsesc(char *target, size_t tlen, char *strbuf)
190 {
191         int len;
192         char *tend;
193         char *send;
194         char *tptr;
195         char *sptr;
196
197         target[0]='\0';
198         len = strlen (strbuf);
199         send = strbuf + len;
200         tend = target + tlen;
201         sptr = strbuf;
202         tptr = target;
203         
204         while (!IsEmptyStr(sptr) && 
205                (sptr < send) &&
206                (tptr < tend)) {
207                
208                 if (*sptr == '<')
209                         *tptr = '[';
210                 else if (*sptr == '>')
211                         *tptr = ']';
212                 else if (*sptr == '\'') {
213                         if (tend - tptr < 3)
214                                 return;
215                         *(tptr++) = '\\';
216                         *tptr = '\'';
217                 }
218                 else if (*sptr == '"') {
219                         if (tend - tptr < 8)
220                                 return;
221                         *(tptr++) = '&';
222                         *(tptr++) = 'q';
223                         *(tptr++) = 'u';
224                         *(tptr++) = 'o';
225                         *(tptr++) = 't';
226                         *tptr = ';';
227                 }
228                 else if (*sptr == '&') {
229                         if (tend - tptr < 7)
230                                 return;
231                         *(tptr++) = '&';
232                         *(tptr++) = 'a';
233                         *(tptr++) = 'm';
234                         *(tptr++) = 'p';
235                         *tptr = ';';
236                 } else {
237                         *tptr = *sptr;
238                 }
239                 tptr++; sptr++;
240         }
241         *tptr = '\0';
242 }
243
244 /*
245  * escape and print javascript
246  */
247 void jsescputs(char *strbuf)
248 {
249         char outbuf[SIZ];
250         
251         jsesc(outbuf, SIZ, strbuf);
252         wprintf("%s", outbuf);
253 }
254
255 /*
256  * print a string to the client after cleaning it with msgesc() and stresc()
257  */
258 void msgescputs1( char *strbuf)
259 {
260         StrBuf *OutBuf;
261
262         if ((strbuf == NULL) || IsEmptyStr(strbuf))
263                 return;
264         OutBuf = NewStrBuf();
265         StrMsgEscAppend(OutBuf, NULL, strbuf);
266         StrEscAppend(WC->WBuf, OutBuf, NULL, 0, 0);
267         FreeStrBuf(&OutBuf);
268 }
269
270 /*
271  * print a string to the client after cleaning it with msgesc()
272  */
273 void msgescputs(char *strbuf) {
274         if ((strbuf != NULL) && !IsEmptyStr(strbuf))
275                 StrMsgEscAppend(WC->WBuf, NULL, strbuf);
276 }
277
278
279