Coverage Report

Created: 2024-05-03 06:05

/builds/xfbs/passgen/src/passgen.c
Line
Count
Source
1
#include "passgen/parser/parser.h"
2
#include "passgen/parser/token.h"
3
#include "passgen/pattern/pattern.h"
4
#include "passgen/util/random.h"
5
#include "passgen/util/utf8.h"
6
#include <assert.h>
7
#include <passgen/passgen.h>
8
#include <string.h>
9
10
int passgen_parse(
11
    passgen_pattern *output,
12
    passgen_error *error,
13
20.1k
    const char *string) {
14
20.1k
    passgen_parser parser;
15
20.1k
    passgen_token_parser token_parser = {0};
16
20.1k
    passgen_token token = {0};
17
20.1k
    passgen_parser_init(&parser, output);
18
20.1k
19
20.1k
    const uint8_t *pattern_raw = (const uint8_t *) string;
20
20.1k
    size_t pattern_len = 256;
21
20.1k
    uint32_t pattern[pattern_len];
22
20.1k
    uint8_t pattern_widths[pattern_len];
23
20.1k
    size_t pattern_pos = 0;
24
20.1k
    size_t pattern_pos_total = 0;
25
20.1k
    size_t pattern_raw_pos = 0;
26
20.1k
    size_t pattern_raw_len = strlen(string);
27
20.1k
28
20.1k
    int decode_ret = 0;
29
20.1k
30
20.1k
    do {
31
20.1k
        uint32_t *pattern_cur = &pattern[0];
32
20.1k
        const uint8_t *pattern_raw_cur = &pattern_raw[pattern_raw_pos];
33
20.1k
34
20.1k
        // decode input utf8 into unicode codepoints
35
20.1k
        decode_ret = passgen_utf8_decode(
36
20.1k
            &pattern_cur,
37
20.1k
            pattern_len,
38
20.1k
            pattern_widths,
39
20.1k
            &pattern_raw_cur,
40
20.1k
            pattern_raw_len - pattern_raw_pos);
41
20.1k
42
20.1k
        pattern_raw_pos += pattern_raw_cur - &pattern_raw[pattern_raw_pos];
43
20.1k
        pattern_pos = pattern_cur - &pattern[0];
44
20.1k
        pattern_pos_total += pattern_pos;
45
20.1k
46
20.1k
        // make sure utf8 decoding was successful
47
20.1k
        if(decode_ret < PASSGEN_UTF8_SUCCESS) {
48
8
            passgen_error_init(error, passgen_utf8_error(decode_ret));
49
8
            passgen_error_offset_set(error, pattern_pos_total, pattern_raw_pos);
50
8
            passgen_parser_free(&parser);
51
8
            return -1;
52
8
        }
53
20.0k
54
20.0k
        // parse tokens and pattern
55
206k
        
for(size_t i = 0; 20.0k
i < pattern_pos;
i++186k
) {
56
192k
            int ret = passgen_token_parse(
57
192k
                &token_parser,
58
192k
                &token,
59
192k
                pattern_widths[i],
60
192k
                pattern[i]);
61
192k
62
192k
            // make sure parsing the token was successful
63
192k
            if(ret < 0) {
64
42
                passgen_error_init(error, passgen_token_parse_error_str(ret));
65
42
                passgen_error_offset_set(error, token.offset, token.byte_offset);
66
42
                passgen_parser_free(&parser);
67
42
                return -1;
68
42
            }
69
192k
70
192k
            // if we have a token, feed it to the parser
71
192k
            if(ret == PASSGEN_TOKEN_INIT) {
72
190k
                ret = passgen_parse_token(&parser, &token);
73
190k
                // make sure that the parser accepts the token
74
190k
                if(ret != 0) {
75
6.38k
                    passgen_error_init(error, "invalid token");
76
6.38k
                    passgen_error_offset_set(error, token.offset, token.byte_offset);
77
6.38k
                    passgen_parser_free(&parser);
78
6.38k
                    return -1;
79
6.38k
                }
80
183k
                assert(ret == 0);
81
183k
            }
82
192k
        }
83
20.0k
    } while(
decode_ret > 13.6k
PASSGEN_UTF8_SUCCESS13.6k
);
84
20.1k
85
20.1k
    // make sure we aren't still parsing tokens
86
20.1k
    
if(13.6k
token_parser.state != PASSGEN_TOKEN_INIT13.6k
) {
87
212
        passgen_error_init(error, passgen_token_parse_error_str(token_parser.state));
88
212
        passgen_error_offset_set(error, pattern_pos_total, pattern_raw_pos);
89
212
        passgen_parser_free(&parser);
90
212
        return -1;
91
212
    }
92
13.4k
93
13.4k
    // make sure we are done parsing
94
13.4k
    if(0 != passgen_parse_finish(&parser)) {
95
4.03k
        passgen_error_init(error, "parsing not finished");
96
4.03k
        passgen_error_offset_set(error, pattern_pos_total, pattern_raw_pos);
97
4.03k
        passgen_parser_free(&parser);
98
4.03k
        return -1;
99
4.03k
    }
100
9.42k
101
9.42k
    passgen_parser_free(&parser);
102
9.42k
103
9.42k
    return 0;
104
9.42k
}