~ubuntu-branches/debian/sid/openchange/sid

« back to all changes in this revision

Viewing changes to mapiproxy/libmapistore/mapistore_util.c

  • Committer: Package Import Robot
  • Author(s): Jelmer Vernooij
  • Date: 2012-04-12 20:07:57 UTC
  • mfrom: (11 sid)
  • mto: This revision was merged to the branch mainline in revision 12.
  • Revision ID: package-import@ubuntu.com-20120412200757-k933d9trljmxj1l4
Tags: 1:1.0-4
* openchangeserver: Add dependency on openchangeproxy.
* Rebuild against newer version of Samba 4.
* Use dpkg-buildflags.
* Migrate to Git, update Vcs-Git header.
* Switch to debhelper 9.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * NOTE:  
3
 
 *
4
 
 * This file imported from the Samba4 project which itself is imported
5
 
 * from the Squid project.  The licence below is reproduced intact,
6
 
 * but refers to files in Squid's repository, not in Samba nor
7
 
 * OpenChange.  See COPYING for the GPLv3 notice (being the later
8
 
 * version mentioned below).
9
 
 *
10
 
 * This file has also been modified, in particular to use talloc to
11
 
 * allocate in rfc1738_escape()
12
 
 *
13
 
 * OpenChange version has been modified to include . as an escapable
14
 
 * character for unix and offer the ability to extend the scope for
15
 
 * other operating systems in the future.
16
 
 *
17
 
 * - Andrew Bartlett Oct-2009
18
 
 * - Julien Kerihuel <j.kerihuel@openchange.org> March 2011
19
 
 */
20
 
 
21
 
 
22
 
/*
23
 
 * $Id$
24
 
 *
25
 
 * DEBUG:
26
 
 * AUTHOR: Harvest Derived
27
 
 *
28
 
 * SQUID Web Proxy Cache          http://www.squid-cache.org/
29
 
 * ----------------------------------------------------------
30
 
 *
31
 
 *  Squid is the result of efforts by numerous individuals from
32
 
 *  the Internet community; see the CONTRIBUTORS file for full
33
 
 *  details.   Many organizations have provided support for Squid's
34
 
 *  development; see the SPONSORS file for full details.  Squid is
35
 
 *  Copyrighted (C) 2001 by the Regents of the University of
36
 
 *  California; see the COPYRIGHT file for full details.  Squid
37
 
 *  incorporates software developed and/or copyrighted by other
38
 
 *  sources; see the CREDITS file for full details.
39
 
 *
40
 
 *  This program is free software; you can redistribute it and/or modify
41
 
 *  it under the terms of the GNU General Public License as published by
42
 
 *  the Free Software Foundation; either version 2 of the License, or
43
 
 *  (at your option) any later version.
44
 
 *
45
 
 *  This program is distributed in the hope that it will be useful,
46
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
47
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48
 
 *  GNU General Public License for more details.
49
 
 *
50
 
 *  You should have received a copy of the GNU General Public License
51
 
 *  along with this program; if not, write to the Free Software
52
 
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
53
 
 *
54
 
 */
55
 
 
56
 
#define __STDC_FORMAT_MACROS    1
57
 
#include <inttypes.h>
58
 
 
59
 
#include "mapistore_errors.h"
60
 
#include "mapistore.h"
61
 
#include "mapistore_private.h"
62
 
#include "mapistore_backend.h"
63
 
#include "mapistore_common.h"
64
 
 
65
 
/*
66
 
 *  RFC 1738 defines that these characters should be escaped, as well
67
 
 *  any non-US-ASCII character or anything between 0x00 - 0x1F.
68
 
 */
69
 
static char rfc1738_unsafe_chars[] = {
70
 
    (char) 0x3C,                /* < */
71
 
    (char) 0x3E,                /* > */
72
 
    (char) 0x22,                /* " */
73
 
    (char) 0x23,                /* # */
74
 
#if 0                           /* done in code */
75
 
    (char) 0x25,                /* % */
76
 
#endif
77
 
    (char) 0x7B,                /* { */
78
 
    (char) 0x7D,                /* } */
79
 
    (char) 0x7C,                /* | */
80
 
    (char) 0x5C,                /* \ */
81
 
    (char) 0x5E,                /* ^ */
82
 
    (char) 0x7E,                /* ~ */
83
 
    (char) 0x5B,                /* [ */
84
 
    (char) 0x5D,                /* ] */
85
 
    (char) 0x60,                /* ` */
86
 
    (char) 0x27,                /* ' */
87
 
    (char) 0x20                 /* space */
88
 
};
89
 
 
90
 
static char rfc1738_reserved_chars[] = {
91
 
    (char) 0x3b,                /* ; */
92
 
    (char) 0x2f,                /* / */
93
 
    (char) 0x3f,                /* ? */
94
 
    (char) 0x3a,                /* : */
95
 
    (char) 0x40,                /* @ */
96
 
    (char) 0x3d,                /* = */
97
 
    (char) 0x26                 /* & */
98
 
};
99
 
 
100
 
/* */
101
 
static char mapistore_reserved_unix_chars[] = {
102
 
        (char) 0x2e,                    /* . */
103
 
        (char) 0x2f,                    /* / */
104
 
};
105
 
 
106
 
enum mapistore_encoding {
107
 
        MAPISTORE_ENCODING_RFC1738_UNSAFE_CHARS                 = (int) -1,
108
 
        MAPISTORE_ENCODING_RFC1738_UNSAFE_CHARS_AND_PERCENT     = (int) 0,
109
 
        MAPISTORE_ENCODING_RFC1738_RESERVED_CHARS               = (int) 1,
110
 
        MAPISTORE_ENCODING_UNIX_RESERVED_CHARS                  = (int) 2,
111
 
        MAPISTORE_ENCODING_WINDOWS_RESERVED_CHARS               = (int) 3
112
 
};
113
 
 
114
 
/*
115
 
 *  do_escape - Returns a static buffer contains the RFC 1738
116
 
 *  compliant or not (depending on encoding value), escaped version of
117
 
 *  the given url
118
 
 *
119
 
 */
120
 
static char *
121
 
mapistore_util_do_escape(TALLOC_CTX *mem_ctx, const char *url, enum mapistore_encoding encoding)
122
 
{
123
 
    size_t bufsize = 0;
124
 
    const char *p;
125
 
    char *buf;
126
 
    char *q;
127
 
    unsigned int i, do_escape;
128
 
 
129
 
    bufsize = strlen(url) * 3 + 1;
130
 
    buf = talloc_array(mem_ctx, char, bufsize);
131
 
    if (!buf) {
132
 
            return NULL;
133
 
    }
134
 
 
135
 
    talloc_set_name_const(buf, buf);
136
 
    buf[0] = '\0';
137
 
 
138
 
    for (p = url, q = buf; *p != '\0' && q < (buf + bufsize - 1); p++, q++) {
139
 
        do_escape = 0;
140
 
 
141
 
        /* RFC 1738 defines these chars as unsafe */
142
 
        for (i = 0; i < sizeof(rfc1738_unsafe_chars); i++) {
143
 
            if (*p == rfc1738_unsafe_chars[i]) {
144
 
                do_escape = 1;
145
 
                break;
146
 
            }
147
 
        }
148
 
 
149
 
        /* Handle % separately */
150
 
        if (encoding >= 0 && *p == '%')
151
 
            do_escape = 1;
152
 
 
153
 
        switch (encoding) {
154
 
        case MAPISTORE_ENCODING_RFC1738_RESERVED_CHARS:
155
 
                /* RFC 1738 defines these chars as reserved */
156
 
                for (i = 0; i < sizeof(rfc1738_reserved_chars); i++) {
157
 
                        if (*p == rfc1738_reserved_chars[i]) {
158
 
                                do_escape = 1;
159
 
                                break;
160
 
                        }
161
 
                }
162
 
                break;
163
 
        case MAPISTORE_ENCODING_UNIX_RESERVED_CHARS:
164
 
                for (i = 0; i < sizeof(mapistore_reserved_unix_chars); i++) {
165
 
                        if (*p == mapistore_reserved_unix_chars[i]) {
166
 
                                do_escape = 1;
167
 
                                break;
168
 
                        }
169
 
                }
170
 
                break;
171
 
        default:
172
 
                break;
173
 
        }
174
 
 
175
 
        /* RFC 1738 says any control chars (0x00-0x1F) are encoded */
176
 
        if ((unsigned char) *p <= (unsigned char) 0x1F) {
177
 
            do_escape = 1;
178
 
        }
179
 
        /* RFC 1738 says 0x7f is encoded */
180
 
        if (*p == (char) 0x7F) {
181
 
            do_escape = 1;
182
 
        }
183
 
        /* RFC 1738 says any non-US-ASCII are encoded */
184
 
        if (((unsigned char) *p >= (unsigned char) 0x80)) {
185
 
            do_escape = 1;
186
 
        }
187
 
        /* Do the triplet encoding, or just copy the char */
188
 
        /* note: while we do not need snprintf here as q is appropriately
189
 
         * allocated, Samba does to avoid our macro banning it -- abartlet */
190
 
 
191
 
        if (do_escape == 1) {
192
 
                (void) snprintf(q, 4, "%%%02X", (unsigned char) *p);
193
 
            q += sizeof(char) * 2;
194
 
        } else {
195
 
            *q = *p;
196
 
        }
197
 
    }
198
 
    *q = '\0';
199
 
    return (buf);
200
 
}
201
 
 
202
 
/*
203
 
 * rfc1738_escape - Returns a buffer that contains the RFC
204
 
 * 1738 compliant, escaped version of the given url. (escapes unsafe and % characters)
205
 
 */
206
 
char *
207
 
mapistore_util_rfc1738_escape(TALLOC_CTX *mem_ctx, const char *url)
208
 
{
209
 
        return mapistore_util_do_escape(mem_ctx, url, MAPISTORE_ENCODING_RFC1738_UNSAFE_CHARS_AND_PERCENT);
210
 
}
211
 
 
212
 
/*
213
 
 * rfc1738_escape_unescaped - Returns a buffer that contains
214
 
 * the RFC 1738 compliant, escaped version of the given url (escapes unsafe chars only)
215
 
 */
216
 
char *
217
 
mapistore_util_rfc1738_escape_unescaped(TALLOC_CTX *mem_ctx, const char *url)
218
 
{
219
 
        return mapistore_util_do_escape(mem_ctx, url, MAPISTORE_ENCODING_RFC1738_UNSAFE_CHARS);
220
 
}
221
 
 
222
 
/*
223
 
 * rfc1738_escape_part - Returns a buffer that contains the RFC
224
 
 * 1738 compliant, escaped version of the given url segment. (escapes
225
 
 * unsafe, reserved and % chars) It would mangle the :// in http://,
226
 
 * and mangle paths (because of /).
227
 
 */
228
 
char *
229
 
mapistore_util_rfc1738_escape_part(TALLOC_CTX *mem_ctx, const char *url)
230
 
{
231
 
        return mapistore_util_do_escape(mem_ctx, url, MAPISTORE_ENCODING_RFC1738_RESERVED_CHARS);
232
 
}
233
 
 
234
 
char *
235
 
mapistore_util_unix_name_escape(TALLOC_CTX *mem_ctx, const char *url)
236
 
{
237
 
        return mapistore_util_do_escape(mem_ctx, url, MAPISTORE_ENCODING_UNIX_RESERVED_CHARS);
238
 
}
239
 
 
240
 
/*
241
 
 *  rfc1738_unescape() - Converts escaped characters (%xy numbers) in
242
 
 *  given the string.  %% is a %. %ab is the 8-bit hexadecimal number "ab"
243
 
 */
244
 
_PUBLIC_ void
245
 
mapistore_util_string_unescape(char *s)
246
 
{
247
 
    char hexnum[3];
248
 
    int i, j;                   /* i is write, j is read */
249
 
    unsigned int x;
250
 
    for (i = j = 0; s[j]; i++, j++) {
251
 
        s[i] = s[j];
252
 
        if (s[i] != '%')
253
 
            continue;
254
 
        if (s[j + 1] == '%') {  /* %% case */
255
 
            j++;
256
 
            continue;
257
 
        }
258
 
        if (s[j + 1] && s[j + 2]) {
259
 
            if (s[j + 1] == '0' && s[j + 2] == '0') {   /* %00 case */
260
 
                j += 2;
261
 
                continue;
262
 
            }
263
 
            hexnum[0] = s[j + 1];
264
 
            hexnum[1] = s[j + 2];
265
 
            hexnum[2] = '\0';
266
 
            if (1 == sscanf(hexnum, "%x", &x)) {
267
 
                s[i] = (char) (0x0ff & x);
268
 
                j += 2;
269
 
            }
270
 
        }
271
 
    }
272
 
    s[i] = '\0';
273
 
}