/src/cmark/fuzz/cmark-fuzz.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* for fmemopen */ |
2 | | #define _POSIX_C_SOURCE 200809L |
3 | | |
4 | | #include <stdint.h> |
5 | | #include <stdio.h> |
6 | | #include <stdlib.h> |
7 | | #include <string.h> |
8 | | #include "cmark.h" |
9 | | |
10 | 32.5k | int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
11 | 32.5k | struct __attribute__((packed)) { |
12 | 32.5k | int options; |
13 | 32.5k | int width; |
14 | 32.5k | } fuzz_config; |
15 | | |
16 | 32.5k | if (size >= sizeof(fuzz_config)) { |
17 | | /* The beginning of `data` is treated as fuzzer configuration */ |
18 | 32.5k | memcpy(&fuzz_config, data, sizeof(fuzz_config)); |
19 | 32.5k | int options = fuzz_config.options; |
20 | | |
21 | | /* Mask off valid option bits */ |
22 | 32.5k | options &= (CMARK_OPT_SOURCEPOS | CMARK_OPT_HARDBREAKS | CMARK_OPT_UNSAFE | CMARK_OPT_NOBREAKS | CMARK_OPT_NORMALIZE | CMARK_OPT_VALIDATE_UTF8 | CMARK_OPT_SMART); |
23 | | |
24 | | /* Remainder of input is the markdown */ |
25 | 32.5k | const char *markdown = (const char *)(data + sizeof(fuzz_config)); |
26 | 32.5k | size_t markdown_size = size - sizeof(fuzz_config); |
27 | 32.5k | cmark_node *doc = NULL; |
28 | | |
29 | | /* Use upper bits of options to select parsing mode */ |
30 | 32.5k | switch (((unsigned) fuzz_config.options >> 30) & 3) { |
31 | 16.1k | case 0: |
32 | 16.1k | doc = cmark_parse_document(markdown, markdown_size, options); |
33 | 16.1k | break; |
34 | | |
35 | 9.54k | case 1: |
36 | 9.54k | if (markdown_size > 0) { |
37 | 9.54k | FILE *file = fmemopen((void *) markdown, markdown_size, "r"); |
38 | 9.54k | doc = cmark_parse_file(file, options); |
39 | 9.54k | fclose(file); |
40 | 9.54k | } |
41 | 9.54k | break; |
42 | | |
43 | 4.03k | case 2: { |
44 | 4.03k | size_t block_max = 20; |
45 | 4.03k | cmark_parser *parser = cmark_parser_new(options); |
46 | | |
47 | 1.31M | while (markdown_size > 0) { |
48 | 1.30M | size_t block_size = markdown_size > block_max ? block_max : markdown_size; |
49 | 1.30M | cmark_parser_feed(parser, markdown, block_size); |
50 | 1.30M | markdown += block_size; |
51 | 1.30M | markdown_size -= block_size; |
52 | 1.30M | } |
53 | | |
54 | 4.03k | doc = cmark_parser_finish(parser); |
55 | 4.03k | cmark_parser_free(parser); |
56 | 4.03k | break; |
57 | 0 | } |
58 | | |
59 | 2.89k | case 3: |
60 | 2.89k | free(cmark_markdown_to_html(markdown, markdown_size, options)); |
61 | 2.89k | break; |
62 | 32.5k | } |
63 | | |
64 | 32.5k | if (doc != NULL) { |
65 | 29.6k | free(cmark_render_commonmark(doc, options, fuzz_config.width)); |
66 | 29.6k | free(cmark_render_html(doc, options)); |
67 | 29.6k | free(cmark_render_latex(doc, options, fuzz_config.width)); |
68 | 29.6k | free(cmark_render_man(doc, options, fuzz_config.width)); |
69 | 29.6k | free(cmark_render_xml(doc, options)); |
70 | | |
71 | 29.6k | cmark_node_free(doc); |
72 | 29.6k | } |
73 | 32.5k | } |
74 | 32.5k | return 0; |
75 | 32.5k | } |