/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 | } |