/src/p11-kit/common/url.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2011 Collabora Ltd. |
3 | | * Copyright (C) 2013 Red Hat Inc. |
4 | | * |
5 | | * Redistribution and use in source and binary forms, with or without |
6 | | * modification, are permitted provided that the following conditions |
7 | | * are met: |
8 | | * |
9 | | * * Redistributions of source code must retain the above |
10 | | * copyright notice, this list of conditions and the |
11 | | * following disclaimer. |
12 | | * * Redistributions in binary form must reproduce the |
13 | | * above copyright notice, this list of conditions and |
14 | | * the following disclaimer in the documentation and/or |
15 | | * other materials provided with the distribution. |
16 | | * * The names of contributors to this software may not be |
17 | | * used to endorse or promote products derived from this |
18 | | * software without specific prior written permission. |
19 | | * |
20 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
21 | | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
22 | | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
23 | | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
24 | | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
25 | | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
26 | | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
27 | | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
28 | | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
29 | | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF |
30 | | * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
31 | | * DAMAGE. |
32 | | * |
33 | | * Author: Stef Walter <stefw@collabora.co.uk> |
34 | | */ |
35 | | |
36 | | #include "config.h" |
37 | | |
38 | | #include "debug.h" |
39 | | #include "url.h" |
40 | | |
41 | | #include <assert.h> |
42 | | #include <ctype.h> |
43 | | #include <stdlib.h> |
44 | | #include <stdio.h> |
45 | | #include <string.h> |
46 | | |
47 | | const static char HEX_CHARS_UPPER[] = "0123456789ABCDEF"; |
48 | | const static char HEX_CHARS_LOWER[] = "0123456789abcdef"; |
49 | | |
50 | | unsigned char * |
51 | | p11_url_decode (const char *value, |
52 | | const char *end, |
53 | | const char *skip, |
54 | | size_t *length) |
55 | 0 | { |
56 | 0 | char *a, *b; |
57 | 0 | unsigned char *result, *p; |
58 | |
|
59 | 0 | assert (value <= end); |
60 | 0 | assert (skip != NULL); |
61 | | |
62 | | /* String can only get shorter */ |
63 | 0 | result = malloc ((end - value) + 1); |
64 | 0 | return_val_if_fail (result != NULL, NULL); |
65 | | |
66 | | /* Now loop through looking for escapes */ |
67 | 0 | p = result; |
68 | 0 | while (value != end) { |
69 | | /* |
70 | | * A percent sign followed by two hex digits means |
71 | | * that the digits represent an escaped character. |
72 | | */ |
73 | 0 | if (*value == '%') { |
74 | 0 | value++; |
75 | 0 | if (end - value < 2) { |
76 | 0 | free (result); |
77 | 0 | return NULL; |
78 | 0 | } |
79 | 0 | a = strchr (HEX_CHARS_UPPER, p11_ascii_toupper (value[0])); |
80 | 0 | b = strchr (HEX_CHARS_UPPER, p11_ascii_toupper (value[1])); |
81 | 0 | if (!a || !b) { |
82 | 0 | free (result); |
83 | 0 | return NULL; |
84 | 0 | } |
85 | 0 | *p = (a - HEX_CHARS_UPPER) << 4; |
86 | 0 | *(p++) |= (b - HEX_CHARS_UPPER); |
87 | 0 | value += 2; |
88 | | |
89 | | /* Ignore whitespace characters */ |
90 | 0 | } else if (strchr (skip, *value)) { |
91 | 0 | value++; |
92 | | |
93 | | /* A different character */ |
94 | 0 | } else { |
95 | 0 | *(p++) = *(value++); |
96 | 0 | } |
97 | 0 | } |
98 | | |
99 | | /* Null terminate string, in case its a string */ |
100 | 0 | *p = 0; |
101 | |
|
102 | 0 | if (length) |
103 | 0 | *length = p - result; |
104 | 0 | return result; |
105 | 0 | } |
106 | | |
107 | | void |
108 | | p11_url_encode (const unsigned char *value, |
109 | | const unsigned char *end, |
110 | | const char *verbatim, |
111 | | p11_buffer *buf) |
112 | 0 | { |
113 | 0 | char hex[3]; |
114 | 0 | const char *env; |
115 | 0 | const char *hex_chars; |
116 | |
|
117 | 0 | assert (value <= end); |
118 | | |
119 | | /* Opt to output lowercase hex-digits for compatibility */ |
120 | 0 | env = secure_getenv ("P11_KIT_URI_LOWERCASE"); |
121 | 0 | if (env && *env != '\0') |
122 | 0 | hex_chars = HEX_CHARS_LOWER; |
123 | 0 | else |
124 | 0 | hex_chars = HEX_CHARS_UPPER; |
125 | | |
126 | | /* Now loop through looking for escapes */ |
127 | 0 | while (value != end) { |
128 | | |
129 | | /* These characters we let through verbatim */ |
130 | 0 | if (*value && strchr (verbatim, *value) != NULL) { |
131 | 0 | p11_buffer_add (buf, value, 1); |
132 | | |
133 | | /* All others get encoded */ |
134 | 0 | } else { |
135 | 0 | hex[0] = '%'; |
136 | 0 | hex[1] = hex_chars[((unsigned char)*value) >> 4]; |
137 | 0 | hex[2] = hex_chars[((unsigned char)*value) & 0x0F]; |
138 | 0 | p11_buffer_add (buf, hex, 3); |
139 | 0 | } |
140 | |
|
141 | 0 | ++value; |
142 | 0 | } |
143 | 0 | } |