summaryrefslogtreecommitdiffstats
path: root/plugins/uriparser/UriShorten.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/uriparser/UriShorten.c')
-rw-r--r--plugins/uriparser/UriShorten.c320
1 files changed, 320 insertions, 0 deletions
diff --git a/plugins/uriparser/UriShorten.c b/plugins/uriparser/UriShorten.c
new file mode 100644
index 0000000..c839ae5
--- /dev/null
+++ b/plugins/uriparser/UriShorten.c
@@ -0,0 +1,320 @@
1/*
2 * uriparser - RFC 3986 URI parsing library
3 *
4 * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>
5 * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * * Redistributions of source code must retain the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer.
15 *
16 * * Redistributions in binary form must reproduce the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer in the documentation and/or other materials
19 * provided with the distribution.
20 *
21 * * Neither the name of the <ORGANIZATION> nor the names of its
22 * contributors may be used to endorse or promote products
23 * derived from this software without specific prior written
24 * permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
29 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
30 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
32 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
37 * OF THE POSSIBILITY OF SUCH DAMAGE.
38 */
39
40/* What encodings are enabled? */
41#include <uriparser/UriDefsConfig.h>
42#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
43/* Include SELF twice */
44# ifdef URI_ENABLE_ANSI
45# define URI_PASS_ANSI 1
46# include "UriShorten.c"
47# undef URI_PASS_ANSI
48# endif
49# ifdef URI_ENABLE_UNICODE
50# define URI_PASS_UNICODE 1
51# include "UriShorten.c"
52# undef URI_PASS_UNICODE
53# endif
54#else
55# ifdef URI_PASS_ANSI
56# include <uriparser/UriDefsAnsi.h>
57# else
58# include <uriparser/UriDefsUnicode.h>
59# include <wchar.h>
60# endif
61
62
63
64#ifndef URI_DOXYGEN
65# include <uriparser/Uri.h>
66# include "UriCommon.h"
67#endif
68
69
70
71static URI_INLINE UriBool URI_FUNC(AppendSegment)(URI_TYPE(Uri) * uri,
72 const URI_CHAR * first, const URI_CHAR * afterLast) {
73 /* Create segment */
74 URI_TYPE(PathSegment) * segment = malloc(1 * sizeof(URI_TYPE(PathSegment)));
75 if (segment == NULL) {
76 return URI_FALSE; /* Raises malloc error */
77 }
78 segment->next = NULL;
79 segment->text.first = first;
80 segment->text.afterLast = afterLast;
81
82 /* Put into chain */
83 if (uri->pathTail == NULL) {
84 uri->pathHead = segment;
85 } else {
86 uri->pathTail->next = segment;
87 }
88 uri->pathTail = segment;
89
90 return URI_TRUE;
91}
92
93
94
95static URI_INLINE UriBool URI_FUNC(EqualsAuthority)(const URI_TYPE(Uri) * first,
96 const URI_TYPE(Uri) * second) {
97 /* IPv4 */
98 if (first->hostData.ip4 != NULL) {
99 return ((second->hostData.ip4 != NULL)
100 && !memcmp(first->hostData.ip4->data,
101 second->hostData.ip4->data, 4)) ? URI_TRUE : URI_FALSE;
102 }
103
104 /* IPv6 */
105 if (first->hostData.ip6 != NULL) {
106 return ((second->hostData.ip6 != NULL)
107 && !memcmp(first->hostData.ip6->data,
108 second->hostData.ip6->data, 16)) ? URI_TRUE : URI_FALSE;
109 }
110
111 /* IPvFuture */
112 if (first->hostData.ipFuture.first != NULL) {
113 return ((second->hostData.ipFuture.first != NULL)
114 && !URI_STRNCMP(first->hostData.ipFuture.first,
115 second->hostData.ipFuture.first,
116 first->hostData.ipFuture.afterLast
117 - first->hostData.ipFuture.first))
118 ? URI_TRUE : URI_FALSE;
119 }
120
121 if (first->hostText.first != NULL) {
122 return ((second->hostText.first != NULL)
123 && !URI_STRNCMP(first->hostText.first,
124 second->hostText.first,
125 first->hostText.afterLast
126 - first->hostText.first)) ? URI_TRUE : URI_FALSE;
127 }
128
129 return (second->hostText.first == NULL);
130}
131
132
133
134int URI_FUNC(RemoveBaseUriImpl)(URI_TYPE(Uri) * dest,
135 const URI_TYPE(Uri) * absSource,
136 const URI_TYPE(Uri) * absBase,
137 UriBool domainRootMode) {
138 if (dest == NULL) {
139 return URI_ERROR_NULL;
140 }
141 URI_FUNC(ResetUri)(dest);
142
143 if ((absSource == NULL) || (absBase == NULL)) {
144 return URI_ERROR_NULL;
145 }
146
147 /* absBase absolute? */
148 if (absBase->scheme.first == NULL) {
149 return URI_ERROR_REMOVEBASE_REL_BASE;
150 }
151
152 /* absSource absolute? */
153 if (absSource->scheme.first == NULL) {
154 return URI_ERROR_REMOVEBASE_REL_SOURCE;
155 }
156
157 /* [01/50] if (A.scheme != Base.scheme) then */
158 if (URI_STRNCMP(absSource->scheme.first, absBase->scheme.first,
159 absSource->scheme.afterLast - absSource->scheme.first)) {
160 /* [02/50] T.scheme = A.scheme; */
161 dest->scheme = absSource->scheme;
162 /* [03/50] T.authority = A.authority; */
163 if (!URI_FUNC(CopyAuthority)(dest, absSource)) {
164 return URI_ERROR_MALLOC;
165 }
166 /* [04/50] T.path = A.path; */
167 if (!URI_FUNC(CopyPath)(dest, absSource)) {
168 return URI_ERROR_MALLOC;
169 }
170 /* [05/50] else */
171 } else {
172 /* [06/50] undef(T.scheme); */
173 /* NOOP */
174 /* [07/50] if (A.authority != Base.authority) then */
175 if (!URI_FUNC(EqualsAuthority)(absSource, absBase)) {
176 /* [08/50] T.authority = A.authority; */
177 if (!URI_FUNC(CopyAuthority)(dest, absSource)) {
178 return URI_ERROR_MALLOC;
179 }
180 /* [09/50] T.path = A.path; */
181 if (!URI_FUNC(CopyPath)(dest, absSource)) {
182 return URI_ERROR_MALLOC;
183 }
184 /* [10/50] else */
185 } else {
186 /* [11/50] if domainRootMode then */
187 if (domainRootMode == URI_TRUE) {
188 /* [12/50] undef(T.authority); */
189 /* NOOP */
190 /* [13/50] if (first(A.path) == "") then */
191 /* GROUPED */
192 /* [14/50] T.path = "/." + A.path; */
193 /* GROUPED */
194 /* [15/50] else */
195 /* GROUPED */
196 /* [16/50] T.path = A.path; */
197 /* GROUPED */
198 /* [17/50] endif; */
199 if (!URI_FUNC(CopyPath)(dest, absSource)) {
200 return URI_ERROR_MALLOC;
201 }
202 dest->absolutePath = URI_TRUE;
203
204 if (!URI_FUNC(FixAmbiguity)(dest)) {
205 return URI_ERROR_MALLOC;
206 }
207 /* [18/50] else */
208 } else {
209 const URI_TYPE(PathSegment) * sourceSeg = absSource->pathHead;
210 const URI_TYPE(PathSegment) * baseSeg = absBase->pathHead;
211 /* [19/50] bool pathNaked = true; */
212 UriBool pathNaked = URI_TRUE;
213 /* [20/50] undef(last(Base.path)); */
214 /* NOOP */
215 /* [21/50] T.path = ""; */
216 dest->absolutePath = URI_FALSE;
217 /* [22/50] while (first(A.path) == first(Base.path)) do */
218 while ((sourceSeg != NULL) && (baseSeg != NULL)
219 && !URI_STRNCMP(sourceSeg->text.first, baseSeg->text.first,
220 sourceSeg->text.afterLast - sourceSeg->text.first)
221 && !((sourceSeg->text.first == sourceSeg->text.afterLast)
222 && ((sourceSeg->next == NULL) != (baseSeg->next == NULL)))) {
223 /* [23/50] A.path++; */
224 sourceSeg = sourceSeg->next;
225 /* [24/50] Base.path++; */
226 baseSeg = baseSeg->next;
227 /* [25/50] endwhile; */
228 }
229 /* [26/50] while defined(first(Base.path)) do */
230 while ((baseSeg != NULL) && (baseSeg->next != NULL)) {
231 /* [27/50] Base.path++; */
232 baseSeg = baseSeg->next;
233 /* [28/50] T.path += "../"; */
234 if (!URI_FUNC(AppendSegment)(dest, URI_FUNC(ConstParent),
235 URI_FUNC(ConstParent) + 2)) {
236 return URI_ERROR_MALLOC;
237 }
238 /* [29/50] pathNaked = false; */
239 pathNaked = URI_FALSE;
240 /* [30/50] endwhile; */
241 }
242 /* [31/50] while defined(first(A.path)) do */
243 while (sourceSeg != NULL) {
244 /* [32/50] if pathNaked then */
245 if (pathNaked == URI_TRUE) {
246 /* [33/50] if (first(A.path) contains ":") then */
247 UriBool containsColon = URI_FALSE;
248 const URI_CHAR * ch = sourceSeg->text.first;
249 for (; ch < sourceSeg->text.afterLast; ch++) {
250 if (*ch == _UT(':')) {
251 containsColon = URI_TRUE;
252 break;
253 }
254 }
255
256 if (containsColon) {
257 /* [34/50] T.path += "./"; */
258 if (!URI_FUNC(AppendSegment)(dest, URI_FUNC(ConstPwd),
259 URI_FUNC(ConstPwd) + 1)) {
260 return URI_ERROR_MALLOC;
261 }
262 /* [35/50] elseif (first(A.path) == "") then */
263 } else if (sourceSeg->text.first == sourceSeg->text.afterLast) {
264 /* [36/50] T.path += "/."; */
265 if (!URI_FUNC(AppendSegment)(dest, URI_FUNC(ConstPwd),
266 URI_FUNC(ConstPwd) + 1)) {
267 return URI_ERROR_MALLOC;
268 }
269 /* [37/50] endif; */
270 }
271 /* [38/50] endif; */
272 }
273 /* [39/50] T.path += first(A.path); */
274 if (!URI_FUNC(AppendSegment)(dest, sourceSeg->text.first,
275 sourceSeg->text.afterLast)) {
276 return URI_ERROR_MALLOC;
277 }
278 /* [40/50] pathNaked = false; */
279 pathNaked = URI_FALSE;
280 /* [41/50] A.path++; */
281 sourceSeg = sourceSeg->next;
282 /* [42/50] if defined(first(A.path)) then */
283 /* NOOP */
284 /* [43/50] T.path += + "/"; */
285 /* NOOP */
286 /* [44/50] endif; */
287 /* NOOP */
288 /* [45/50] endwhile; */
289 }
290 /* [46/50] endif; */
291 }
292 /* [47/50] endif; */
293 }
294 /* [48/50] endif; */
295 }
296 /* [49/50] T.query = A.query; */
297 dest->query = absSource->query;
298 /* [50/50] T.fragment = A.fragment; */
299 dest->fragment = absSource->fragment;
300
301 return URI_SUCCESS;
302}
303
304
305
306int URI_FUNC(RemoveBaseUri)(URI_TYPE(Uri) * dest,
307 const URI_TYPE(Uri) * absSource,
308 const URI_TYPE(Uri) * absBase,
309 UriBool domainRootMode) {
310 const int res = URI_FUNC(RemoveBaseUriImpl)(dest, absSource,
311 absBase, domainRootMode);
312 if ((res != URI_SUCCESS) && (dest != NULL)) {
313 URI_FUNC(FreeUriMembers)(dest);
314 }
315 return res;
316}
317
318
319
320#endif