1 /*
2  * uriparser - RFC 3986 URI parsing library
3  *
4  * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>
5  * Copyright (C) 2007, Sebastian Pipping <sebastian@pipping.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 /**
41  * @file UriIp4.c
42  * Holds the IPv4 parser implementation.
43  * NOTE: This source file includes itself twice.
44  */
45 
46 /* What encodings are enabled? */
47 #include "UriDefsConfig.h"
48 #if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
49 /* Include SELF twice */
50 # ifdef URI_ENABLE_ANSI
51 #  define URI_PASS_ANSI 1
52 #  include "UriIp4.c"
53 #  undef URI_PASS_ANSI
54 # endif
55 # ifdef URI_ENABLE_UNICODE
56 #  define URI_PASS_UNICODE 1
57 #  include "UriIp4.c"
58 #  undef URI_PASS_UNICODE
59 # endif
60 #else
61 # ifdef URI_PASS_ANSI
62 #  include "UriDefsAnsi.h"
63 # else
64 #  include "UriDefsUnicode.h"
65 # endif
66 
67 
68 
69 #ifndef URI_DOXYGEN
70 # include "UriIp4.h"
71 # include "UriIp4Base.h"
72 # include "UriBase.h"
73 #endif
74 
75 
76 
77 /* Prototypes */
78 static const URI_CHAR * URI_FUNC(ParseDecOctet)(UriIp4Parser * parser,
79 		const URI_CHAR * first, const URI_CHAR * afterLast);
80 static const URI_CHAR * URI_FUNC(ParseDecOctetOne)(UriIp4Parser * parser,
81 		const URI_CHAR * first, const URI_CHAR * afterLast);
82 static const URI_CHAR * URI_FUNC(ParseDecOctetTwo)(UriIp4Parser * parser,
83 		const URI_CHAR * first, const URI_CHAR * afterLast);
84 static const URI_CHAR * URI_FUNC(ParseDecOctetThree)(UriIp4Parser * parser,
85 		const URI_CHAR * first, const URI_CHAR * afterLast);
86 static const URI_CHAR * URI_FUNC(ParseDecOctetFour)(UriIp4Parser * parser,
87 		const URI_CHAR * first, const URI_CHAR * afterLast);
88 
89 
90 
91 /*
92  * [ipFourAddress]->[decOctet]<.>[decOctet]<.>[decOctet]<.>[decOctet]
93  */
URI_FUNC(ParseIpFourAddress)94 int URI_FUNC(ParseIpFourAddress)(unsigned char * octetOutput,
95 		const URI_CHAR * first, const URI_CHAR * afterLast) {
96 	const URI_CHAR * after;
97 	UriIp4Parser parser;
98 
99 	/* Essential checks */
100 	if ((octetOutput == NULL) || (first == NULL)
101 			|| (afterLast <= first)) {
102 		return URI_ERROR_SYNTAX;
103 	}
104 
105 	/* Reset parser */
106 	parser.stackCount = 0;
107 
108 	/* Octet #1 */
109 	after = URI_FUNC(ParseDecOctet)(&parser, first, afterLast);
110 	if ((after == NULL) || (after >= afterLast) || (*after != _UT('.'))) {
111 		return URI_ERROR_SYNTAX;
112 	}
113 	uriStackToOctet(&parser, octetOutput);
114 
115 	/* Octet #2 */
116 	after = URI_FUNC(ParseDecOctet)(&parser, after + 1, afterLast);
117 	if ((after == NULL) || (after >= afterLast) || (*after != _UT('.'))) {
118 		return URI_ERROR_SYNTAX;
119 	}
120 	uriStackToOctet(&parser, octetOutput + 1);
121 
122 	/* Octet #3 */
123 	after = URI_FUNC(ParseDecOctet)(&parser, after + 1, afterLast);
124 	if ((after == NULL) || (after >= afterLast) || (*after != _UT('.'))) {
125 		return URI_ERROR_SYNTAX;
126 	}
127 	uriStackToOctet(&parser, octetOutput + 2);
128 
129 	/* Octet #4 */
130 	after = URI_FUNC(ParseDecOctet)(&parser, after + 1, afterLast);
131 	if (after != afterLast) {
132 		return URI_ERROR_SYNTAX;
133 	}
134 	uriStackToOctet(&parser, octetOutput + 3);
135 
136 	return URI_SUCCESS;
137 }
138 
139 
140 
141 /*
142  * [decOctet]-><0>
143  * [decOctet]-><1>[decOctetOne]
144  * [decOctet]-><2>[decOctetTwo]
145  * [decOctet]-><3>[decOctetThree]
146  * [decOctet]-><4>[decOctetThree]
147  * [decOctet]-><5>[decOctetThree]
148  * [decOctet]-><6>[decOctetThree]
149  * [decOctet]-><7>[decOctetThree]
150  * [decOctet]-><8>[decOctetThree]
151  * [decOctet]-><9>[decOctetThree]
152  */
URI_FUNC(ParseDecOctet)153 static URI_INLINE const URI_CHAR * URI_FUNC(ParseDecOctet)(UriIp4Parser * parser,
154 		const URI_CHAR * first, const URI_CHAR * afterLast) {
155 	if (first >= afterLast) {
156 		return NULL;
157 	}
158 
159 	switch (*first) {
160 	case _UT('0'):
161 		uriPushToStack(parser, 0);
162 		return first + 1;
163 
164 	case _UT('1'):
165 		uriPushToStack(parser, 1);
166 		return (const URI_CHAR *)URI_FUNC(ParseDecOctetOne)(parser, first + 1, afterLast);
167 
168 	case _UT('2'):
169 		uriPushToStack(parser, 2);
170 		return (const URI_CHAR *)URI_FUNC(ParseDecOctetTwo)(parser, first + 1, afterLast);
171 
172 	case _UT('3'):
173 	case _UT('4'):
174 	case _UT('5'):
175 	case _UT('6'):
176 	case _UT('7'):
177 	case _UT('8'):
178 	case _UT('9'):
179 		uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
180 		return (const URI_CHAR *)URI_FUNC(ParseDecOctetThree)(parser, first + 1, afterLast);
181 
182 	default:
183 		return NULL;
184 	}
185 }
186 
187 
188 
189 /*
190  * [decOctetOne]-><NULL>
191  * [decOctetOne]->[DIGIT][decOctetThree]
192  */
URI_FUNC(ParseDecOctetOne)193 static URI_INLINE const URI_CHAR * URI_FUNC(ParseDecOctetOne)(UriIp4Parser * parser,
194 		const URI_CHAR * first, const URI_CHAR * afterLast) {
195 	if (first >= afterLast) {
196 		return afterLast;
197 	}
198 
199 	switch (*first) {
200 	case _UT('0'):
201 	case _UT('1'):
202 	case _UT('2'):
203 	case _UT('3'):
204 	case _UT('4'):
205 	case _UT('5'):
206 	case _UT('6'):
207 	case _UT('7'):
208 	case _UT('8'):
209 	case _UT('9'):
210 		uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
211 		return (const URI_CHAR *)URI_FUNC(ParseDecOctetThree)(parser, first + 1, afterLast);
212 
213 	default:
214 		return first;
215 	}
216 }
217 
218 
219 
220 /*
221  * [decOctetTwo]-><NULL>
222  * [decOctetTwo]-><0>[decOctetThree]
223  * [decOctetTwo]-><1>[decOctetThree]
224  * [decOctetTwo]-><2>[decOctetThree]
225  * [decOctetTwo]-><3>[decOctetThree]
226  * [decOctetTwo]-><4>[decOctetThree]
227  * [decOctetTwo]-><5>[decOctetFour]
228  * [decOctetTwo]-><6>
229  * [decOctetTwo]-><7>
230  * [decOctetTwo]-><8>
231  * [decOctetTwo]-><9>
232 */
URI_FUNC(ParseDecOctetTwo)233 static URI_INLINE const URI_CHAR * URI_FUNC(ParseDecOctetTwo)(UriIp4Parser * parser,
234 		const URI_CHAR * first, const URI_CHAR * afterLast) {
235 	if (first >= afterLast) {
236 		return afterLast;
237 	}
238 
239 	switch (*first) {
240 	case _UT('0'):
241 	case _UT('1'):
242 	case _UT('2'):
243 	case _UT('3'):
244 	case _UT('4'):
245 		uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
246 		return (const URI_CHAR *)URI_FUNC(ParseDecOctetThree)(parser, first + 1, afterLast);
247 
248 	case _UT('5'):
249 		uriPushToStack(parser, 5);
250 		return (const URI_CHAR *)URI_FUNC(ParseDecOctetFour)(parser, first + 1, afterLast);
251 
252 	case _UT('6'):
253 	case _UT('7'):
254 	case _UT('8'):
255 	case _UT('9'):
256 		uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
257 		return first + 1;
258 
259 	default:
260 		return first;
261 	}
262 }
263 
264 
265 
266 /*
267  * [decOctetThree]-><NULL>
268  * [decOctetThree]->[DIGIT]
269  */
URI_FUNC(ParseDecOctetThree)270 static URI_INLINE const URI_CHAR * URI_FUNC(ParseDecOctetThree)(UriIp4Parser * parser,
271 		const URI_CHAR * first, const URI_CHAR * afterLast) {
272 	if (first >= afterLast) {
273 		return afterLast;
274 	}
275 
276 	switch (*first) {
277 	case _UT('0'):
278 	case _UT('1'):
279 	case _UT('2'):
280 	case _UT('3'):
281 	case _UT('4'):
282 	case _UT('5'):
283 	case _UT('6'):
284 	case _UT('7'):
285 	case _UT('8'):
286 	case _UT('9'):
287 		uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
288 		return first + 1;
289 
290 	default:
291 		return first;
292 	}
293 }
294 
295 
296 
297 /*
298  * [decOctetFour]-><NULL>
299  * [decOctetFour]-><0>
300  * [decOctetFour]-><1>
301  * [decOctetFour]-><2>
302  * [decOctetFour]-><3>
303  * [decOctetFour]-><4>
304  * [decOctetFour]-><5>
305  */
URI_FUNC(ParseDecOctetFour)306 static URI_INLINE const URI_CHAR * URI_FUNC(ParseDecOctetFour)(UriIp4Parser * parser,
307 		const URI_CHAR * first, const URI_CHAR * afterLast) {
308 	if (first >= afterLast) {
309 		return afterLast;
310 	}
311 
312 	switch (*first) {
313 	case _UT('0'):
314 	case _UT('1'):
315 	case _UT('2'):
316 	case _UT('3'):
317 	case _UT('4'):
318 	case _UT('5'):
319 		uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
320 		return first + 1;
321 
322 	default:
323 		return first;
324 	}
325 }
326 
327 
328 
329 #endif
330