Coverage Report

Created: 2025-12-31 07:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/php-src/ext/uri/uriparser/src/UriIp4.c
Line
Count
Source
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
 *     1. Redistributions  of  source  code   must  retain  the  above
13
 *        copyright notice, this list  of conditions and the following
14
 *        disclaimer.
15
 *
16
 *     2. 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
 *     3. Neither the  name of the  copyright holder nor the  names of
22
 *        its 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
30
 * THE  COPYRIGHT HOLDER  OR CONTRIBUTORS  BE LIABLE  FOR ANY  DIRECT,
31
 * INDIRECT, 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 <uriparser/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 <uriparser/UriDefsAnsi.h>
63
#  else
64
#    include <uriparser/UriDefsUnicode.h>
65
#  endif
66
67
#  ifndef URI_DOXYGEN
68
#    include <uriparser/UriIp4.h>
69
#    include "UriIp4Base.h"
70
#    include <uriparser/UriBase.h>
71
#    include "UriSets.h"
72
#  endif
73
74
/* Prototypes */
75
static const URI_CHAR * URI_FUNC(ParseDecOctet)(UriIp4Parser * parser,
76
                                                const URI_CHAR * first,
77
                                                const URI_CHAR * afterLast);
78
static const URI_CHAR * URI_FUNC(ParseDecOctetOne)(UriIp4Parser * parser,
79
                                                   const URI_CHAR * first,
80
                                                   const URI_CHAR * afterLast);
81
static const URI_CHAR * URI_FUNC(ParseDecOctetTwo)(UriIp4Parser * parser,
82
                                                   const URI_CHAR * first,
83
                                                   const URI_CHAR * afterLast);
84
static const URI_CHAR * URI_FUNC(ParseDecOctetThree)(UriIp4Parser * parser,
85
                                                     const URI_CHAR * first,
86
                                                     const URI_CHAR * afterLast);
87
static const URI_CHAR * URI_FUNC(ParseDecOctetFour)(UriIp4Parser * parser,
88
                                                    const URI_CHAR * first,
89
                                                    const URI_CHAR * afterLast);
90
91
/*
92
 * [ipFourAddress]->[decOctet]<.>[decOctet]<.>[decOctet]<.>[decOctet]
93
 */
94
int URI_FUNC(ParseIpFourAddress)(unsigned char * octetOutput, const URI_CHAR * first,
95
0
                                 const URI_CHAR * afterLast) {
96
0
    const URI_CHAR * after;
97
0
    UriIp4Parser parser;
98
99
    /* Essential checks */
100
0
    if ((octetOutput == NULL) || (first == NULL) || (afterLast <= first)) {
101
0
        return URI_ERROR_SYNTAX;
102
0
    }
103
104
    /* Reset parser */
105
0
    parser.stackCount = 0;
106
107
    /* Octet #1 */
108
0
    after = URI_FUNC(ParseDecOctet)(&parser, first, afterLast);
109
0
    if ((after == NULL) || (after >= afterLast) || (*after != _UT('.'))) {
110
0
        return URI_ERROR_SYNTAX;
111
0
    }
112
0
    uriStackToOctet(&parser, octetOutput);
113
114
    /* Octet #2 */
115
0
    after = URI_FUNC(ParseDecOctet)(&parser, after + 1, afterLast);
116
0
    if ((after == NULL) || (after >= afterLast) || (*after != _UT('.'))) {
117
0
        return URI_ERROR_SYNTAX;
118
0
    }
119
0
    uriStackToOctet(&parser, octetOutput + 1);
120
121
    /* Octet #3 */
122
0
    after = URI_FUNC(ParseDecOctet)(&parser, after + 1, afterLast);
123
0
    if ((after == NULL) || (after >= afterLast) || (*after != _UT('.'))) {
124
0
        return URI_ERROR_SYNTAX;
125
0
    }
126
0
    uriStackToOctet(&parser, octetOutput + 2);
127
128
    /* Octet #4 */
129
0
    after = URI_FUNC(ParseDecOctet)(&parser, after + 1, afterLast);
130
0
    if (after != afterLast) {
131
0
        return URI_ERROR_SYNTAX;
132
0
    }
133
0
    uriStackToOctet(&parser, octetOutput + 3);
134
135
0
    return URI_SUCCESS;
136
0
}
Unexecuted instantiation: uriParseIpFourAddressA
Unexecuted instantiation: uriParseIpFourAddressW
137
138
/*
139
 * [decOctet]-><0>
140
 * [decOctet]-><1>[decOctetOne]
141
 * [decOctet]-><2>[decOctetTwo]
142
 * [decOctet]-><3>[decOctetThree]
143
 * [decOctet]-><4>[decOctetThree]
144
 * [decOctet]-><5>[decOctetThree]
145
 * [decOctet]-><6>[decOctetThree]
146
 * [decOctet]-><7>[decOctetThree]
147
 * [decOctet]-><8>[decOctetThree]
148
 * [decOctet]-><9>[decOctetThree]
149
 */
150
static URI_INLINE const URI_CHAR * URI_FUNC(ParseDecOctet)(UriIp4Parser * parser,
151
                                                           const URI_CHAR * first,
152
0
                                                           const URI_CHAR * afterLast) {
153
0
    if (first >= afterLast) {
154
0
        return NULL;
155
0
    }
156
157
0
    switch (*first) {
158
0
    case _UT('0'):
159
0
        uriPushToStack(parser, 0);
160
0
        return first + 1;
161
162
0
    case _UT('1'):
163
0
        uriPushToStack(parser, 1);
164
0
        return (const URI_CHAR *)URI_FUNC(ParseDecOctetOne)(parser, first + 1, afterLast);
165
166
0
    case _UT('2'):
167
0
        uriPushToStack(parser, 2);
168
0
        return (const URI_CHAR *)URI_FUNC(ParseDecOctetTwo)(parser, first + 1, afterLast);
169
170
0
    case _UT('3'):
171
0
    case _UT('4'):
172
0
    case _UT('5'):
173
0
    case _UT('6'):
174
0
    case _UT('7'):
175
0
    case _UT('8'):
176
0
    case _UT('9'):
177
0
        uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
178
0
        return (const URI_CHAR *)URI_FUNC(ParseDecOctetThree)(parser, first + 1,
179
0
                                                              afterLast);
180
181
0
    default:
182
0
        return NULL;
183
0
    }
184
0
}
Unexecuted instantiation: UriIp4.c:uriParseDecOctetA
Unexecuted instantiation: UriIp4.c:uriParseDecOctetW
185
186
/*
187
 * [decOctetOne]-><NULL>
188
 * [decOctetOne]->[DIGIT][decOctetThree]
189
 */
190
static URI_INLINE const URI_CHAR *
191
URI_FUNC(ParseDecOctetOne)(UriIp4Parser * parser, const URI_CHAR * first,
192
0
                           const URI_CHAR * afterLast) {
193
0
    if (first >= afterLast) {
194
0
        return afterLast;
195
0
    }
196
197
0
    switch (*first) {
198
0
    case URI_SET_DIGIT(_UT):
199
0
        uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
200
0
        return (const URI_CHAR *)URI_FUNC(ParseDecOctetThree)(parser, first + 1,
201
0
                                                              afterLast);
202
203
0
    default:
204
0
        return first;
205
0
    }
206
0
}
Unexecuted instantiation: UriIp4.c:uriParseDecOctetOneA
Unexecuted instantiation: UriIp4.c:uriParseDecOctetOneW
207
208
/*
209
 * [decOctetTwo]-><NULL>
210
 * [decOctetTwo]-><0>[decOctetThree]
211
 * [decOctetTwo]-><1>[decOctetThree]
212
 * [decOctetTwo]-><2>[decOctetThree]
213
 * [decOctetTwo]-><3>[decOctetThree]
214
 * [decOctetTwo]-><4>[decOctetThree]
215
 * [decOctetTwo]-><5>[decOctetFour]
216
 * [decOctetTwo]-><6>
217
 * [decOctetTwo]-><7>
218
 * [decOctetTwo]-><8>
219
 * [decOctetTwo]-><9>
220
 */
221
static URI_INLINE const URI_CHAR *
222
URI_FUNC(ParseDecOctetTwo)(UriIp4Parser * parser, const URI_CHAR * first,
223
0
                           const URI_CHAR * afterLast) {
224
0
    if (first >= afterLast) {
225
0
        return afterLast;
226
0
    }
227
228
0
    switch (*first) {
229
0
    case _UT('0'):
230
0
    case _UT('1'):
231
0
    case _UT('2'):
232
0
    case _UT('3'):
233
0
    case _UT('4'):
234
0
        uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
235
0
        return (const URI_CHAR *)URI_FUNC(ParseDecOctetThree)(parser, first + 1,
236
0
                                                              afterLast);
237
238
0
    case _UT('5'):
239
0
        uriPushToStack(parser, 5);
240
0
        return (const URI_CHAR *)URI_FUNC(ParseDecOctetFour)(parser, first + 1,
241
0
                                                             afterLast);
242
243
0
    case _UT('6'):
244
0
    case _UT('7'):
245
0
    case _UT('8'):
246
0
    case _UT('9'):
247
0
        uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
248
0
        return first + 1;
249
250
0
    default:
251
0
        return first;
252
0
    }
253
0
}
Unexecuted instantiation: UriIp4.c:uriParseDecOctetTwoA
Unexecuted instantiation: UriIp4.c:uriParseDecOctetTwoW
254
255
/*
256
 * [decOctetThree]-><NULL>
257
 * [decOctetThree]->[DIGIT]
258
 */
259
static URI_INLINE const URI_CHAR *
260
URI_FUNC(ParseDecOctetThree)(UriIp4Parser * parser, const URI_CHAR * first,
261
0
                             const URI_CHAR * afterLast) {
262
0
    if (first >= afterLast) {
263
0
        return afterLast;
264
0
    }
265
266
0
    switch (*first) {
267
0
    case URI_SET_DIGIT(_UT):
268
0
        uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
269
0
        return first + 1;
270
271
0
    default:
272
0
        return first;
273
0
    }
274
0
}
Unexecuted instantiation: UriIp4.c:uriParseDecOctetThreeA
Unexecuted instantiation: UriIp4.c:uriParseDecOctetThreeW
275
276
/*
277
 * [decOctetFour]-><NULL>
278
 * [decOctetFour]-><0>
279
 * [decOctetFour]-><1>
280
 * [decOctetFour]-><2>
281
 * [decOctetFour]-><3>
282
 * [decOctetFour]-><4>
283
 * [decOctetFour]-><5>
284
 */
285
static URI_INLINE const URI_CHAR *
286
URI_FUNC(ParseDecOctetFour)(UriIp4Parser * parser, const URI_CHAR * first,
287
0
                            const URI_CHAR * afterLast) {
288
0
    if (first >= afterLast) {
289
0
        return afterLast;
290
0
    }
291
292
0
    switch (*first) {
293
0
    case _UT('0'):
294
0
    case _UT('1'):
295
0
    case _UT('2'):
296
0
    case _UT('3'):
297
0
    case _UT('4'):
298
0
    case _UT('5'):
299
0
        uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
300
0
        return first + 1;
301
302
0
    default:
303
0
        return first;
304
0
    }
305
0
}
Unexecuted instantiation: UriIp4.c:uriParseDecOctetFourA
Unexecuted instantiation: UriIp4.c:uriParseDecOctetFourW
306
307
#endif