File Coverage

third_party/modest/source/myhtml/tokenizer_doctype.c
Criterion Covered Total %
statement 149 233 63.9
branch 118 228 51.7
condition n/a
subroutine n/a
pod n/a
total 267 461 57.9


line stmt bran cond sub pod time code
1             /*
2             Copyright (C) 2015-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 "myhtml/tokenizer_doctype.h"
22              
23             /////////////////////////////////////////////////////////
24             //// BEFORE DOCTYPE NAME
25             ////
26             /////////////////////////////////////////////////////////
27 36           size_t myhtml_tokenizer_state_doctype(myhtml_tree_t* tree, myhtml_token_node_t* token_node, const char* html, size_t html_offset, size_t html_size)
28             {
29             //myhtml_t* myhtml = tree->myhtml;
30            
31 36           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_BEFORE_DOCTYPE_NAME;
32            
33 36           return html_offset;
34             }
35              
36             /////////////////////////////////////////////////////////
37             //// BEFORE DOCTYPE NAME
38             ////
39             /////////////////////////////////////////////////////////
40 36           size_t myhtml_tokenizer_state_before_doctype_name(myhtml_tree_t* tree, myhtml_token_node_t* token_node, const char* html, size_t html_offset, size_t html_size)
41             {
42 69 100         myhtml_parser_skip_whitespace()
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
43            
44 36 50         if(html_offset >= html_size)
45 0           return html_offset;
46            
47 36 100         if(html[html_offset] == '>')
48             {
49 3           tree->compat_mode = MyHTML_TREE_COMPAT_MODE_QUIRKS;
50            
51 3           html_offset++;
52            
53 3           token_node->element_length = (tree->global_offset + html_offset) - token_node->element_begin;
54            
55 3 50         if(myhtml_queue_add(tree, html_offset, token_node) != MyHTML_STATUS_OK) {
56 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_PARSE_ERROR_STOP;
57 0           return 0;
58             }
59            
60 3           tree->attr_current = myhtml_token_attr_create(tree->token, tree->token->mcasync_attr_id);
61 3 50         if(tree->attr_current == NULL) {
62 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_PARSE_ERROR_STOP;
63 0           return 0;
64             }
65            
66 3           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_DATA;
67             }
68             else {
69 33 50         myhtml_parser_queue_set_attr(tree, token_node);
70 33           tree->attr_current->raw_key_begin = (html_offset + tree->global_offset);
71            
72 33           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_DOCTYPE_NAME;
73             }
74            
75 36           return html_offset;
76             }
77              
78             /////////////////////////////////////////////////////////
79             //// DOCTYPE NAME
80             ////
81             /////////////////////////////////////////////////////////
82 33           size_t myhtml_tokenizer_state_doctype_name(myhtml_tree_t* tree, myhtml_token_node_t* token_node, const char* html, size_t html_offset, size_t html_size)
83             {
84 170 50         while(html_offset < html_size)
85             {
86 170 100         if(html[html_offset] == '>')
87             {
88 9           tree->attr_current->raw_key_length = (html_offset + tree->global_offset) - tree->attr_current->raw_key_begin;
89            
90 9           html_offset++;
91            
92 9           token_node->element_length = (tree->global_offset + html_offset) - token_node->element_begin;
93            
94 9 50         if(myhtml_queue_add(tree, html_offset, token_node) != MyHTML_STATUS_OK) {
95 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_PARSE_ERROR_STOP;
96 0           return 0;
97             }
98            
99 9           tree->attr_current = myhtml_token_attr_create(tree->token, tree->token->mcasync_attr_id);
100 9 50         if(tree->attr_current == NULL) {
101 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_PARSE_ERROR_STOP;
102 0           return 0;
103             }
104            
105 9           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_DATA;
106            
107 9           break;
108             }
109 161 100         else if(myhtml_whithspace(html[html_offset], ==, ||))
    50          
    50          
    50          
    50          
110             {
111 24           tree->attr_current->raw_key_length = (html_offset + tree->global_offset) - tree->attr_current->raw_key_begin;
112            
113 24           tree->attr_current = myhtml_token_attr_create(tree->token, tree->token->mcasync_attr_id);
114 24 50         if(tree->attr_current == NULL) {
115 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_PARSE_ERROR_STOP;
116 0           return 0;
117             }
118            
119 24           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_AFTER_DOCTYPE_NAME;
120            
121 24           html_offset++;
122 24           break;
123             }
124            
125 137           html_offset++;
126             }
127            
128 33           return html_offset;
129             }
130              
131             /////////////////////////////////////////////////////////
132             //// AFTER DOCTYPE NAME
133             ////
134             /////////////////////////////////////////////////////////
135 24           size_t myhtml_tokenizer_state_after_doctype_name(myhtml_tree_t* tree, myhtml_token_node_t* token_node, const char* html, size_t html_offset, size_t html_size)
136             {
137 24 50         myhtml_parser_skip_whitespace()
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
138            
139 24 50         if(html_offset >= html_size)
140 0           return html_offset;
141            
142 24 50         if(html[html_offset] == '>')
143             {
144 0           html_offset++;
145            
146 0           token_node->element_length = (tree->global_offset + html_offset) - token_node->element_begin;
147            
148 0 0         if(myhtml_queue_add(tree, html_offset, token_node) != MyHTML_STATUS_OK) {
149 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_PARSE_ERROR_STOP;
150 0           return 0;
151             }
152            
153 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_DATA;
154 0           return html_offset;
155             }
156            
157             /* temporarily */
158 24           token_node->str.length = (html_offset + tree->global_offset);
159 24           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_CUSTOM_AFTER_DOCTYPE_NAME_A_Z;
160            
161 24           return html_offset;
162             }
163              
164 24           size_t myhtml_tokenizer_state_custom_after_doctype_name_a_z(myhtml_tree_t* tree, myhtml_token_node_t* token_node, const char* html, size_t html_offset, size_t html_size)
165             {
166 24 50         if((token_node->str.length + 6) > (html_size + tree->global_offset)) {
167 0           return html_size;
168             }
169            
170 24           const char *param = myhtml_tree_incomming_buffer_make_data(tree, token_node->str.length, 6);
171            
172 24 100         if(mycore_strncasecmp(param, "PUBLIC", 6) == 0) {
173 16 50         myhtml_parser_queue_set_attr(tree, token_node);
174            
175 16           tree->attr_current->raw_value_begin = token_node->str.length;
176 16           tree->attr_current->raw_value_length = 6;
177            
178 16           tree->attr_current = myhtml_token_attr_create(tree->token, tree->token->mcasync_attr_id);
179 16 50         if(tree->attr_current == NULL) {
180 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_PARSE_ERROR_STOP;
181 0           return 0;
182             }
183            
184 16           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER;
185            
186 16           html_offset = (token_node->str.length + 6) - tree->incoming_buf->offset;
187             }
188 8 100         else if(mycore_strncasecmp(param, "SYSTEM", 6) == 0) {
189 6 50         myhtml_parser_queue_set_attr(tree, token_node);
190            
191 6           tree->attr_current->raw_value_begin = token_node->str.length;
192 6           tree->attr_current->raw_value_length = 6;
193            
194 6           tree->attr_current = myhtml_token_attr_create(tree->token, tree->token->mcasync_attr_id);
195 6 50         if(tree->attr_current == NULL) {
196 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_PARSE_ERROR_STOP;
197 0           return 0;
198             }
199            
200 6           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_AFTER_DOCTYPE_PUBLIC_IDENTIFIER;
201            
202 6           html_offset = (token_node->str.length + 6) - tree->incoming_buf->offset;
203             }
204             else {
205 2           tree->compat_mode = MyHTML_TREE_COMPAT_MODE_QUIRKS;
206 2           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_BOGUS_DOCTYPE;
207             }
208            
209 24           return html_offset;
210             }
211              
212             /////////////////////////////////////////////////////////
213             //// BEFORE DOCTYPE PUBLIC IDENTIFIER
214             ////
215             /////////////////////////////////////////////////////////
216 16           size_t myhtml_tokenizer_state_before_doctype_public_identifier(myhtml_tree_t* tree, myhtml_token_node_t* token_node, const char* html, size_t html_offset, size_t html_size)
217             {
218 31 100         myhtml_parser_skip_whitespace()
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
219            
220 16 50         if(html_offset >= html_size)
221 0           return html_offset;
222            
223 16 100         if(html[html_offset] == '"') {
224 15           tree->attr_current->raw_value_begin = (html_offset + tree->global_offset) + 1;
225 15           tree->attr_current->raw_value_length = 0;
226            
227 15           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED;
228             }
229 1 50         else if(html[html_offset] == '\'') {
230 0           tree->attr_current->raw_value_begin = (html_offset + tree->global_offset) + 1;
231 0           tree->attr_current->raw_value_length = 0;
232            
233 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED;
234             }
235 1 50         else if(html[html_offset] == '>')
236             {
237 1           tree->compat_mode = MyHTML_TREE_COMPAT_MODE_QUIRKS;
238            
239 1           html_offset++;
240            
241 1           token_node->element_length = (tree->global_offset + html_offset) - token_node->element_begin;
242            
243 1 50         if(myhtml_queue_add(tree, html_offset, token_node) != MyHTML_STATUS_OK) {
244 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_PARSE_ERROR_STOP;
245 0           return 0;
246             }
247            
248 1           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_DATA;
249 1           return html_offset;
250             }
251             else {
252 0           tree->compat_mode = MyHTML_TREE_COMPAT_MODE_QUIRKS;
253 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_BOGUS_DOCTYPE;
254             }
255            
256 15           return (html_offset + 1);
257             }
258              
259             /////////////////////////////////////////////////////////
260             //// DOCTYPE PUBLIC IDENTIFIER DOUBLE or SINGLE QUOTED
261             ////
262             /////////////////////////////////////////////////////////
263 15           size_t myhtml_tokenizer_doctype_public_identifier_dsq(myhtml_tree_t* tree, myhtml_token_node_t* token_node, const char* html, size_t html_offset, size_t html_size, char quote)
264             {
265 292 50         while(html_offset < html_size)
266             {
267 292 100         if(html[html_offset] == quote)
268             {
269 15           tree->attr_current->raw_value_length = (html_offset + tree->global_offset) - tree->attr_current->raw_value_begin;
270            
271 15 50         myhtml_parser_queue_set_attr(tree, token_node);
272            
273 15           tree->attr_current = myhtml_token_attr_create(tree->token, tree->token->mcasync_attr_id);
274 15 50         if(tree->attr_current == NULL) {
275 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_PARSE_ERROR_STOP;
276 0           return 0;
277             }
278            
279 15           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_AFTER_DOCTYPE_PUBLIC_IDENTIFIER;
280            
281 15           html_offset++;
282 15           break;
283             }
284 277 50         else if(html[html_offset] == '>')
285             {
286 0           tree->compat_mode = MyHTML_TREE_COMPAT_MODE_QUIRKS;
287            
288 0 0         if(tree->attr_current->raw_value_begin < (html_offset + tree->global_offset)) {
289 0           tree->attr_current->raw_value_length = (html_offset + tree->global_offset) - tree->attr_current->raw_value_begin;
290            
291 0 0         myhtml_parser_queue_set_attr(tree, token_node);
292            
293 0           tree->attr_current = myhtml_token_attr_create(tree->token, tree->token->mcasync_attr_id);
294 0 0         if(tree->attr_current == NULL) {
295 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_PARSE_ERROR_STOP;
296 0           return 0;
297             }
298             }
299            
300 0           html_offset++;
301            
302 0           token_node->element_length = (tree->global_offset + html_offset) - token_node->element_begin;
303            
304 0 0         if(myhtml_queue_add(tree, html_offset, token_node) != MyHTML_STATUS_OK) {
305 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_PARSE_ERROR_STOP;
306 0           return 0;
307             }
308            
309 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_DATA;
310 0           break;
311             }
312            
313 277           html_offset++;
314             }
315            
316 15           return html_offset;
317             }
318              
319 15           size_t myhtml_tokenizer_state_doctype_public_identifier_double_quoted(myhtml_tree_t* tree, myhtml_token_node_t* token_node, const char* html, size_t html_offset, size_t html_size)
320             {
321 15           return myhtml_tokenizer_doctype_public_identifier_dsq(tree, token_node, html, html_offset, html_size, '"');
322             }
323              
324 0           size_t myhtml_tokenizer_state_doctype_public_identifier_single_quoted(myhtml_tree_t* tree, myhtml_token_node_t* token_node, const char* html, size_t html_offset, size_t html_size)
325             {
326 0           return myhtml_tokenizer_doctype_public_identifier_dsq(tree, token_node, html, html_offset, html_size, '\'');
327             }
328              
329             /////////////////////////////////////////////////////////
330             //// AFTER DOCTYPE PUBLIC IDENTIFIER
331             ////
332             /////////////////////////////////////////////////////////
333 21           size_t myhtml_tokenizer_state_after_doctype_public_identifier(myhtml_tree_t* tree, myhtml_token_node_t* token_node, const char* html, size_t html_offset, size_t html_size)
334             {
335 36 100         myhtml_parser_skip_whitespace()
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
336            
337 21 50         if(html_offset >= html_size)
338 0           return html_offset;
339            
340 21 100         if(html[html_offset] == '"')
341             {
342 15           tree->attr_current->raw_value_begin = (html_offset + tree->global_offset) + 1;
343 15           tree->attr_current->raw_value_length = 0;
344            
345 15           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
346             }
347 6 50         else if(html[html_offset] == '\'')
348             {
349 0           tree->attr_current->raw_value_begin = (html_offset + tree->global_offset) + 1;
350 0           tree->attr_current->raw_value_length = 0;
351            
352 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
353             }
354 6 50         else if(html[html_offset] == '>')
355             {
356 6           html_offset++;
357            
358 6           token_node->element_length = (tree->global_offset + html_offset) - token_node->element_begin;
359            
360 6 50         if(myhtml_queue_add(tree, html_offset, token_node) != MyHTML_STATUS_OK) {
361 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_PARSE_ERROR_STOP;
362 0           return 0;
363             }
364            
365 6           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_DATA;
366 6           return html_offset;
367             }
368             else {
369 0           tree->compat_mode = MyHTML_TREE_COMPAT_MODE_QUIRKS;
370            
371 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_BOGUS_DOCTYPE;
372 0           return html_offset;
373             }
374            
375 15           html_offset++;
376            
377 15           return html_offset;
378             }
379              
380             /////////////////////////////////////////////////////////
381             //// DOCTYPE SYSTEM IDENTIFIER DOUBLE or SINGLE QUOTED
382             ////
383             /////////////////////////////////////////////////////////
384 15           size_t myhtml_tokenizer_doctype_system_identifier_dsq(myhtml_tree_t* tree, myhtml_token_node_t* token_node, const char* html, size_t html_offset, size_t html_size, char quote)
385             {
386 387 50         while(html_offset < html_size)
387             {
388 387 100         if(html[html_offset] == quote)
389             {
390 15           tree->attr_current->raw_value_length = (html_offset + tree->global_offset) - tree->attr_current->raw_value_begin;
391            
392 15 50         myhtml_parser_queue_set_attr(tree, token_node);
393            
394 15           tree->attr_current = myhtml_token_attr_create(tree->token, tree->token->mcasync_attr_id);
395 15 50         if(tree->attr_current == NULL) {
396 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_PARSE_ERROR_STOP;
397 0           return 0;
398             }
399            
400 15           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_AFTER_DOCTYPE_SYSTEM_IDENTIFIER;
401            
402 15           html_offset++;
403 15           break;
404             }
405 372 50         else if(html[html_offset] == '>')
406             {
407 0           tree->compat_mode = MyHTML_TREE_COMPAT_MODE_QUIRKS;
408            
409 0 0         if(tree->attr_current->raw_value_begin < (html_offset + tree->global_offset)) {
410 0           tree->attr_current->raw_value_length = (html_offset + tree->global_offset) - tree->attr_current->raw_value_begin;
411            
412 0 0         myhtml_parser_queue_set_attr(tree, token_node);
413            
414 0           tree->attr_current = myhtml_token_attr_create(tree->token, tree->token->mcasync_attr_id);
415 0 0         if(tree->attr_current == NULL) {
416 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_PARSE_ERROR_STOP;
417 0           return 0;
418             }
419             }
420            
421 0           html_offset++;
422            
423 0           token_node->element_length = (tree->global_offset + html_offset) - token_node->element_begin;
424            
425 0 0         if(myhtml_queue_add(tree, html_offset, token_node) != MyHTML_STATUS_OK) {
426 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_PARSE_ERROR_STOP;
427 0           return 0;
428             }
429            
430 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_DATA;
431 0           break;
432             }
433            
434 372           html_offset++;
435             }
436            
437 15           return html_offset;
438             }
439              
440 15           size_t myhtml_tokenizer_state_doctype_system_identifier_double_quoted(myhtml_tree_t* tree, myhtml_token_node_t* token_node, const char* html, size_t html_offset, size_t html_size)
441             {
442 15           return myhtml_tokenizer_doctype_system_identifier_dsq(tree, token_node, html, html_offset, html_size, '"');
443             }
444              
445 0           size_t myhtml_tokenizer_state_doctype_system_identifier_single_quoted(myhtml_tree_t* tree, myhtml_token_node_t* token_node, const char* html, size_t html_offset, size_t html_size)
446             {
447 0           return myhtml_tokenizer_doctype_system_identifier_dsq(tree, token_node, html, html_offset, html_size, '\'');
448             }
449              
450             /////////////////////////////////////////////////////////
451             //// AFTER DOCTYPE SYSTEM IDENTIFIER
452             ////
453             /////////////////////////////////////////////////////////
454 15           size_t myhtml_tokenizer_state_after_doctype_system_identifier(myhtml_tree_t* tree, myhtml_token_node_t* token_node, const char* html, size_t html_offset, size_t html_size)
455             {
456 16 100         myhtml_parser_skip_whitespace();
    50          
    50          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    50          
457            
458 15 50         if(html_offset >= html_size)
459 0           return html_offset;
460            
461 15 100         if(html[html_offset] == '>')
462             {
463 14           html_offset++;
464            
465 14           token_node->element_length = (tree->global_offset + html_offset) - token_node->element_begin;
466            
467 14 50         if(myhtml_queue_add(tree, html_offset, token_node) != MyHTML_STATUS_OK) {
468 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_PARSE_ERROR_STOP;
469 0           return 0;
470             }
471            
472 14           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_DATA;
473             }
474             else {
475 1           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_BOGUS_DOCTYPE;
476             }
477            
478 15           return html_offset;
479             }
480              
481             /////////////////////////////////////////////////////////
482             //// BOGUS DOCTYPE
483             //// find >
484             /////////////////////////////////////////////////////////
485 3           size_t myhtml_tokenizer_state_bogus_doctype(myhtml_tree_t* tree, myhtml_token_node_t* token_node, const char* html, size_t html_offset, size_t html_size)
486             {
487 63 50         while(html_offset < html_size)
488             {
489 63 100         if(html[html_offset] == '>')
490             {
491 3           html_offset++;
492            
493 3           token_node->element_length = (tree->global_offset + html_offset) - token_node->element_begin;
494            
495 3 50         if(myhtml_queue_add(tree, html_offset, token_node) != MyHTML_STATUS_OK) {
496 0           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_PARSE_ERROR_STOP;
497 0           return 0;
498             }
499            
500 3           myhtml_tokenizer_state_set(tree) = MyHTML_TOKENIZER_STATE_DATA;
501 3           break;
502             }
503            
504 60           html_offset++;
505             }
506            
507 3           return html_offset;
508             }
509              
510