File Coverage

third_party/modest/source/myurl/parser_end.c
Criterion Covered Total %
statement 0 146 0.0
branch 0 116 0.0
condition n/a
subroutine n/a
pod n/a
total 0 262 0.0


line stmt bran cond sub pod time code
1             /*
2             Copyright (C) 2016-2017 Alexander Borisov
3            
4             This library is free software; you can redistribute it and/or
5             modify it under the terms of the GNU Lesser General Public
6             License as published by the Free Software Foundation; either
7             version 2.1 of the License, or (at your option) any later version.
8            
9             This library is distributed in the hope that it will be useful,
10             but WITHOUT ANY WARRANTY; without even the implied warranty of
11             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12             Lesser General Public License for more details.
13            
14             You should have received a copy of the GNU Lesser General Public
15             License along with this library; if not, write to the Free Software
16             Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17            
18             Author: lex.borisov@gmail.com (Alexander Borisov)
19             */
20              
21             #include "myurl/url.h"
22             #include "myurl/parser.h"
23             #include "myurl/resources.h"
24             #include "mycore/utils/resources.h"
25              
26 0           size_t myurl_parser_state_relative_end(myurl_t* url, myurl_entry_t* url_entry, myurl_entry_t* url_base, const char* data, size_t data_length, size_t data_size)
27             {
28 0           if(myurl_parser_copy_attr(url, url_base, url_entry, username) != MyURL_STATUS_OK ||
29 0 0         myurl_parser_copy_attr(url, url_base, url_entry, password) != MyURL_STATUS_OK ||
30 0 0         myurl_parser_copy_attr(url, url_base, url_entry, query) != MyURL_STATUS_OK ||
31 0 0         myurl_host_copy(url, &url_base->host, &url_entry->host) != MyURL_STATUS_OK ||
32 0           myurl_path_copy(url, &url_base->path, &url_entry->path) != MyURL_STATUS_OK)
33             {
34 0           url_entry->status = MyURL_STATUS_ERROR_MEMORY_ALLOCATION;
35 0           return (data_size + 1);
36             }
37            
38 0           url_entry->port = url_base->port;
39 0           url_entry->port_is_set = url_base->port_is_set;
40            
41 0           return data_size;
42             }
43              
44 0           size_t myurl_parser_state_authority_end(myurl_t* url, myurl_entry_t* url_entry, myurl_entry_t* url_base, const char* data, size_t data_length, size_t data_size)
45             {
46 0 0         if((url_entry->flags & MyURL_FLAGS_AT) && (data_length - url->begin) == 0) {
    0          
47             // parse error
48 0           url_entry->status = MyURL_STATUS_FAILURE_AUTHORITY_HOST_AFTER_AUTH;
49 0           return (data_size + 1);
50             }
51            
52 0           data_length -= (data_length - url->begin);
53            
54 0           url->state = myurl_parser_state_host_hostname;
55 0           url->begin = 0;
56            
57 0           return data_length;
58             }
59              
60 0           size_t myurl_parser_state_host_hostname_end(myurl_t* url, myurl_entry_t* url_entry, myurl_entry_t* url_base, const char* data, size_t data_length, size_t data_size)
61             {
62             /* 3.1 */
63 0 0         if((url_entry->scheme.type & MyURL_SCHEME_TYPE_SPECIAL) && (data_length - url->begin) == 0) {
    0          
64             // parse error
65 0           url_entry->status = MyURL_STATUS_FAILURE_UNEXPECTED_ENDING;
66 0           return (data_size + 1);
67             }
68            
69             /* 3.2 */
70 0 0         if(url->state_override && (data_length - url->begin) == 0 &&
    0          
    0          
71 0 0         (myurl_parser_is_includes_credentials(url_entry) || url_entry->port_is_set))
    0          
72             {
73             // parse error
74 0           return (data_size + 1);
75             }
76            
77             /* 3.3 and 3.4 */
78 0 0         if(myurl_host_parser(url, &url_entry->host, &data[url->begin], (data_length - url->begin),
79 0           (url_entry->scheme.type & MyURL_SCHEME_TYPE_SPECIAL)))
80             {
81 0           url_entry->status = MyURL_STATUS_FAILURE_BAD_HOSTNAME;
82 0           return (data_size + 1);
83             }
84            
85             /* 3.6 */
86 0 0         if(url->state_override)
87 0           return (data_size + 1);
88            
89             /* 3.5 */
90 0           url->state = myurl_parser_state_port;
91 0           url->begin = 0;
92            
93 0           return data_length;
94             }
95              
96 0           size_t myurl_parser_state_port_end(myurl_t* url, myurl_entry_t* url_entry, myurl_entry_t* url_base, const char* data, size_t data_length, size_t data_size)
97             {
98             /* 2.1 */
99 0 0         if((data_length - url->begin))
100             {
101 0           size_t len = url->begin;
102 0           unsigned int port = 0;
103            
104             /* 2.1.1 */
105 0 0         while(len < data_length)
106             {
107 0 0         if(port > 65535) {
108 0           url_entry->status = MyURL_STATUS_FAILURE_BAD_PORT;
109 0           return (data_size + 1);
110             }
111            
112 0           port = mycore_string_chars_num_map[ (unsigned char)data[len] ] + port * 10;
113 0           len++;
114             }
115            
116             /* 2.1.3 */
117 0 0         if(url_entry->scheme.port != port) {
118 0           url_entry->port = port;
119 0           url_entry->port_is_set = true;
120             }
121             }
122            
123             /* for all 2.1.4 */
124 0           url->begin = 0;
125            
126             /* 2.2 */
127 0 0         if(url->state_override)
128 0           return (data_size + 1);
129            
130             /* 2.3 */
131 0           url->state = myurl_parser_state_path_start;
132            
133 0           return data_length;
134             }
135              
136 0           size_t myurl_parser_state_file_end(myurl_t* url, myurl_entry_t* url_entry, myurl_entry_t* url_base, const char* data, size_t data_length, size_t data_size)
137             {
138 0           if(myurl_host_copy(url, &url_base->host, &url_entry->host) != MyURL_STATUS_OK ||
139 0 0         myurl_path_copy(url, &url_base->path, &url_entry->path) != MyURL_STATUS_OK ||
140 0           myurl_parser_copy_attr(url, url_base, url_entry, query) != MyURL_STATUS_OK)
141             {
142 0           url_entry->status = MyURL_STATUS_ERROR_MEMORY_ALLOCATION;
143 0           return (data_size + 1);
144             }
145            
146 0           return data_size;
147             }
148              
149 0           size_t myurl_parser_state_file_host_end(myurl_t* url, myurl_entry_t* url_entry, myurl_entry_t* url_base, const char* data, size_t data_length, size_t data_size)
150             {
151             /* 1.1 */
152 0 0         if(url->state_override == NULL && myurl_utils_is_windows_drive_letter(data, url->begin, data_size)) {
    0          
153 0           url->state = myurl_parser_state_path;
154 0           return data_length;
155             }
156            
157             /* 1.2 */
158 0 0         if((data_length <= url->begin)) {
159             /* 1.2.1 */
160 0           myurl_host_clean(url, &url_entry->host);
161            
162             /* 1.2.2 */
163 0 0         if(url->state_override)
164 0           return (data_size + 1);
165            
166             /* 1.2.3 */
167 0           url->state = myurl_parser_state_path_start;
168 0           return data_length;
169             }
170            
171             /* 1.3 */
172 0 0         if(myurl_host_parser(url, &url_entry->host, &data[url->begin], (data_length - url->begin), (url_entry->scheme.type & MyURL_SCHEME_TYPE_SPECIAL))) {
173 0           url_entry->status = MyURL_STATUS_FAILURE_BAD_HOSTNAME;
174 0           return (data_size + 1);
175             }
176            
177             /* 1.3.3 */
178 0 0         if(url_entry->host.type == MyURL_HOST_TYPE_DOMAIN &&
    0          
179 0 0         url_entry->host.value.domain.length == 9 &&
180 0           mycore_strncasecmp("localhost", url_entry->host.value.domain.value, url_entry->host.value.domain.length) == 0)
181             {
182 0           myurl_host_clean(url, &url_entry->host);
183             }
184            
185             /* 1.3.5 */
186 0 0         if(url->state_override)
187 0           return (data_size + 1);
188            
189             /* 2.1.6 */
190 0           url->begin = 0;
191 0           url->state = myurl_parser_state_path_start;
192            
193 0           return data_length;
194             }
195              
196 0           size_t myurl_parser_state_path_start_end(myurl_t* url, myurl_entry_t* url_entry, myurl_entry_t* url_base, const char* data, size_t data_length, size_t data_size)
197             {
198 0           return data_size;
199             }
200              
201 0           size_t myurl_parser_state_path_end(myurl_t* url, myurl_entry_t* url_entry, myurl_entry_t* url_base, const char* data, size_t data_length, size_t data_size)
202             {
203             /* 1.1 */
204             //if(url_entry->scheme.type & MyURL_SCHEME_TYPE_SPECIAL && data[data_length] == '\\') {
205             // // parse error
206             //}
207            
208             /* 1.2 */
209 0 0         if(myurl_utils_is_double_dot_path_segment(&data[ url->begin ], (data_length - url->begin)))
210             {
211 0           myurl_path_shorten(&url_entry->path, url_entry->scheme.sid);
212            
213 0 0         if(data_length >= data_size || (data[data_length] != '/' &&
    0          
    0          
214 0 0         (url_entry->scheme.type & MyURL_SCHEME_TYPE_SPECIAL && data[data_length] == '\\') == 0))
    0          
215             {
216 0 0         if(myurl_path_push(url, &url_entry->path, NULL, 0) == NULL) {
217 0           url_entry->status = MyURL_STATUS_ERROR;
218 0           return (data_size + 1);
219             }
220             }
221             }
222            
223             /* 1.3 */
224 0 0         else if(myurl_utils_is_single_dot_path_segment(&data[ url->begin ], (data_length - url->begin)))
225             {
226 0 0         if(data_length >= data_size || (data[data_length] != '/' &&
    0          
    0          
227 0 0         (url_entry->scheme.type & MyURL_SCHEME_TYPE_SPECIAL && data[data_length] == '\\') == 0))
    0          
228             {
229 0 0         if(myurl_path_push(url, &url_entry->path, NULL, 0) == NULL) {
230 0           url_entry->status = MyURL_STATUS_ERROR;
231 0           return (data_size + 1);
232             }
233             }
234             }
235            
236             /* 1.4 */
237             else {
238 0           bool second_replace = false;
239             /* 1.4.1 */
240 0 0         if(url_entry->scheme.sid == MyURL_SCHEME_ID_FILE && url_entry->path.length == 0 &&
241 0           myurl_utils_is_windows_drive_letter(data, url->begin, data_length))
242             {
243             /* 1.4.1.1 */
244             //if(url_entry->host.type != MyURL_HOST_TYPE_UNDEF) {
245             // // parse error
246             //}
247            
248             /* 1.4.1.2 */
249 0           myurl_host_clean(url, &url_entry->host);
250 0           second_replace = true;
251             }
252            
253             /* 1.4.2 */
254             size_t buffer_length;
255 0           char *buffer = myurl_utils_percent_encode(url, &data[ url->begin ], (data_length - url->begin),
256             myurl_resources_static_map_path, &buffer_length);
257            
258 0 0         if(buffer == NULL) {
259 0           url_entry->status = MyURL_STATUS_ERROR_MEMORY_ALLOCATION;
260 0           return (data_size + 1);
261             }
262            
263 0 0         if(myurl_path_push(url, &url_entry->path, buffer, buffer_length) == NULL) {
264 0           url_entry->status = MyURL_STATUS_ERROR_MEMORY_ALLOCATION;
265 0           return (data_size + 1);
266             }
267            
268             /* 1.4.1.2 */
269 0 0         if(second_replace && buffer_length > 1) {
    0          
270 0           buffer[1] = ':';
271             }
272             }
273            
274             /* 1.5 */
275 0           url->begin = 0;
276            
277 0 0         if(data_length < data_size) {
278             /* 1.6 */
279 0 0         if(data[data_length] == '?') {
280 0           myurl_utils_data_set_null(url, &url_entry->query, &url_entry->query_length);
281 0           url->state = myurl_parser_state_query;
282             }
283             /* 1.7 */
284 0 0         if(data[data_length] == '#') {
285 0           myurl_utils_data_set_null(url, &url_entry->fragment, &url_entry->fragment_length);
286 0           url->state = myurl_parser_state_fragment;
287             }
288             }
289            
290 0           return (data_length + 1);
291             }
292              
293 0           size_t myurl_parser_state_cannot_be_a_base_URL_path_end(myurl_t* url, myurl_entry_t* url_entry, myurl_entry_t* url_base, const char* data, size_t data_length, size_t data_size)
294             {
295 0 0         if(url->begin < data_length) {
296             size_t buffer_length;
297 0           char *buffer = myurl_utils_percent_encode(url, &data[ url->begin ], (data_length - url->begin),
298             myurl_resources_static_map_C0, &buffer_length);
299            
300 0 0         if(buffer == NULL) {
301 0           url_entry->status = MyURL_STATUS_ERROR_MEMORY_ALLOCATION;
302 0           return (data_size + 1);
303             }
304            
305 0 0         if(myurl_path_push(url, &url_entry->path, buffer, buffer_length) == NULL) {
306 0           url_entry->status = MyURL_STATUS_ERROR_MEMORY_ALLOCATION;
307 0           return (data_size + 1);
308             }
309             }
310            
311 0           return (data_size + 1);
312             }
313              
314 0           size_t myurl_parser_state_query_end(myurl_t* url, myurl_entry_t* url_entry, myurl_entry_t* url_base, const char* data, size_t data_length, size_t data_size)
315             {
316             /* 1.1 */
317 0 0         if((url_entry->scheme.type & MyURL_SCHEME_TYPE_SPECIAL) == 0 ||
    0          
318 0 0         url_entry->scheme.sid == MyURL_SCHEME_ID_WS ||
319 0           url_entry->scheme.sid == MyURL_SCHEME_ID_WSS)
320             {
321 0           url->encoding = MyENCODING_UTF_8;
322             }
323            
324             /* 1.2, 1.3 */
325             size_t buffer_length;
326 0           char *buffer = myurl_utils_percent_encode(url, &data[ url->begin ], (data_length - url->begin),
327             myurl_resources_static_map_query_charset, &buffer_length);
328            
329 0 0         if(buffer == NULL) {
330 0           url_entry->status = MyURL_STATUS_ERROR_MEMORY_ALLOCATION;
331 0           return (data_size + 1);
332             }
333            
334 0           url_entry->query = buffer;
335 0           url_entry->query_length = buffer_length;
336            
337             /* 1.4 */
338 0           url->begin = 0;
339            
340             /* 1.5 */
341 0           myurl_utils_data_set_null(url, &url_entry->fragment, &url_entry->fragment_length);
342 0           url->state = myurl_parser_state_fragment;
343            
344 0           return (data_length + 1);
345             }
346              
347