Line data Source code
1 : /*
2 : * lwan - web server
3 : * Copyright (c) 2017 L. A. F. Pereira <l@tia.mat.br>
4 : *
5 : * This program is free software; you can redistribute it and/or
6 : * modify it under the terms of the GNU General Public License
7 : * as published by the Free Software Foundation; either version 2
8 : * of the License, or any later version.
9 : *
10 : * This program is distributed in the hope that it will be useful,
11 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : * GNU General Public License for more details.
14 : *
15 : * You should have received a copy of the GNU General Public License
16 : * along with this program; if not, write to the Free Software
17 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 : */
19 :
20 : #define _GNU_SOURCE
21 :
22 : #include <ctype.h>
23 : #include <errno.h>
24 : #include <fcntl.h>
25 : #include <stdarg.h>
26 : #include <stdbool.h>
27 : #include <stdio.h>
28 : #include <stdlib.h>
29 : #include <string.h>
30 : #include <sys/mman.h>
31 : #include <sys/stat.h>
32 : #include <sys/types.h>
33 : #include <unistd.h>
34 :
35 : #include "lwan-private.h"
36 : #include "lwan-status.h"
37 : #include "lwan-config.h"
38 : #include "lwan-strbuf.h"
39 :
40 : #include "ringbuffer.h"
41 :
42 : #define LEX_ERROR(lexer, fmt, ...) \
43 : ({ \
44 : config_error(config_from_lexer(lexer), "%s" fmt, \
45 : "Syntax error: ", ##__VA_ARGS__); \
46 : NULL; \
47 : })
48 :
49 : #define PARSER_ERROR(parser, fmt, ...) \
50 : ({ \
51 : config_error(config_from_parser(parser), "%s" fmt, \
52 : "Parsing error: ", ##__VA_ARGS__); \
53 : NULL; \
54 : })
55 :
56 : #define INTERNAL_ERROR(parser, fmt, ...) \
57 : ({ \
58 : config_error(config_from_parser(parser), "%s" fmt, \
59 : "Internal error: ", ##__VA_ARGS__); \
60 : NULL; \
61 : })
62 :
63 : #define FOR_EACH_LEXEME(X) \
64 : X(STRING) X(EQUAL) X(OPEN_BRACKET) X(CLOSE_BRACKET) X(LINEFEED) X(VARIABLE) \
65 : X(VARIABLE_DEFAULT) X(EOF)
66 :
67 : #define GENERATE_ENUM(id) LEXEME_ ## id,
68 :
69 : enum lexeme_type {
70 : FOR_EACH_LEXEME(GENERATE_ENUM)
71 : TOTAL_LEXEMES
72 : };
73 :
74 : #undef GENERATE_ENUM
75 :
76 : struct lexeme {
77 : enum lexeme_type type;
78 : struct {
79 : const char *value;
80 : size_t len;
81 : } value;
82 : };
83 :
84 1054704 : DEFINE_RING_BUFFER_TYPE(lexeme_ring_buffer, struct lexeme, 4)
85 315038 : DEFINE_RING_BUFFER_TYPE(config_ring_buffer, struct config_line, 4)
86 :
87 : struct lexer {
88 : void *(*state)(struct lexer *);
89 : const char *start, *pos, *end;
90 : struct lexeme_ring_buffer buffer;
91 : int cur_line;
92 : };
93 :
94 : struct parser {
95 : void *(*state)(struct parser *);
96 : struct lexer lexer;
97 : struct lexeme_ring_buffer buffer;
98 : struct config_ring_buffer items;
99 : struct lwan_strbuf strbuf;
100 : };
101 :
102 : struct config {
103 : struct parser parser;
104 : char *error_message;
105 : struct {
106 : void *addr;
107 : size_t sz;
108 : } mapped;
109 : int opened_brackets;
110 : };
111 :
112 440 : unsigned int parse_time_period(const char *str, unsigned int default_value)
113 : {
114 440 : unsigned int total = 0;
115 : unsigned int period;
116 440 : int ignored_spaces = 0;
117 : char multiplier;
118 :
119 440 : if (!str)
120 87 : return default_value;
121 :
122 89707 : while (*str) {
123 : /* This check is necessary to avoid making sscanf() take an incredible
124 : * amount of time while trying to scan the input for a number. Fix for
125 : * https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=44910 */
126 89528 : if (isspace(*str)) {
127 89175 : ignored_spaces++;
128 :
129 89175 : if (ignored_spaces > 1024)
130 87 : break;
131 :
132 89088 : continue;
133 : }
134 :
135 353 : if (sscanf(str, "%u%c", &period, &multiplier) != 2)
136 87 : break;
137 :
138 266 : switch (multiplier) {
139 174 : case 's': total += period; break;
140 0 : case 'm': total += period * ONE_MINUTE; break;
141 5 : case 'h': total += period * ONE_HOUR; break;
142 0 : case 'd': total += period * ONE_DAY; break;
143 0 : case 'w': total += period * ONE_WEEK; break;
144 87 : case 'M': total += period * ONE_MONTH; break;
145 0 : case 'y': total += period * ONE_YEAR; break;
146 0 : default:
147 0 : lwan_status_warning("Ignoring unknown multiplier: %c",
148 : multiplier);
149 : }
150 :
151 266 : str = strchr(str, multiplier) + 1;
152 : }
153 :
154 353 : return total ? total : default_value;
155 : }
156 :
157 628 : long long parse_long_long(const char *value, long long default_value)
158 : {
159 : char *endptr;
160 : long long parsed;
161 :
162 628 : if (!value)
163 87 : return default_value;
164 :
165 541 : errno = 0;
166 541 : parsed = strtoll(value, &endptr, 0);
167 :
168 541 : if (errno != 0)
169 0 : return default_value;
170 :
171 541 : if (*endptr != '\0' || value == endptr)
172 0 : return default_value;
173 :
174 541 : return parsed;
175 : }
176 :
177 621 : long parse_long(const char *value, long default_value)
178 : {
179 621 : long long long_long_value = parse_long_long(value, default_value);
180 :
181 : if ((long long)(long)long_long_value != long_long_value)
182 : return default_value;
183 :
184 621 : return (long)long_long_value;
185 : }
186 :
187 265 : int parse_int(const char *value, int default_value)
188 : {
189 265 : long long_value = parse_long(value, default_value);
190 :
191 265 : if ((long)(int)long_value != long_value)
192 0 : return default_value;
193 :
194 265 : return (int)long_value;
195 : }
196 :
197 696 : bool parse_bool(const char *value, bool default_value)
198 : {
199 696 : if (!value)
200 174 : return default_value;
201 :
202 522 : if (streq(value, "true") || streq(value, "on") || streq(value, "yes"))
203 435 : return true;
204 :
205 87 : if (streq(value, "false") || streq(value, "off") || streq(value, "no"))
206 87 : return false;
207 :
208 0 : return parse_int(value, default_value);
209 : }
210 :
211 0 : bool config_error(struct config *conf, const char *fmt, ...)
212 : {
213 : va_list values;
214 : int len;
215 : char *output;
216 :
217 0 : if (conf->error_message)
218 0 : return false;
219 :
220 0 : va_start(values, fmt);
221 0 : len = vasprintf(&output, fmt, values);
222 0 : va_end(values);
223 :
224 0 : if (len >= 0) {
225 0 : conf->error_message = output;
226 0 : return true;
227 : }
228 :
229 0 : conf->error_message = NULL;
230 0 : return false;
231 : }
232 :
233 82630 : static void emit_lexeme(struct lexer *lexer, struct lexeme *lexeme)
234 : {
235 82630 : if (lexeme_ring_buffer_try_put(&lexer->buffer, lexeme))
236 82630 : lexer->start = lexer->pos;
237 82630 : }
238 :
239 83152 : static size_t current_len(struct lexer *lexer)
240 : {
241 83152 : return (size_t)(lexer->pos - lexer->start);
242 : }
243 :
244 82630 : static void emit(struct lexer *lexer, enum lexeme_type type)
245 : {
246 165260 : struct lexeme lexeme = {
247 : .type = type,
248 82630 : .value = {.value = lexer->start, .len = current_len(lexer)},
249 : };
250 82630 : emit_lexeme(lexer, &lexeme);
251 82630 : }
252 :
253 832990 : static int next(struct lexer *lexer)
254 : {
255 832990 : if (lexer->pos >= lexer->end) {
256 356 : lexer->pos = lexer->end + 1;
257 356 : return '\0';
258 : }
259 :
260 832634 : int r = *lexer->pos;
261 832634 : lexer->pos++;
262 :
263 832634 : if (r == '\n')
264 34155 : lexer->cur_line++;
265 :
266 832634 : return r;
267 : }
268 :
269 224537 : static void ignore(struct lexer *lexer)
270 : {
271 224537 : lexer->start = lexer->pos;
272 224537 : }
273 :
274 2446 : static void advance_n(struct lexer *lexer, size_t n)
275 : {
276 2446 : lexer->pos += n;
277 2446 : ignore(lexer);
278 2446 : }
279 :
280 36046 : static void backup(struct lexer *lexer)
281 : {
282 36046 : lexer->pos--;
283 :
284 36046 : if (*lexer->pos == '\n')
285 8177 : lexer->cur_line--;
286 36046 : }
287 :
288 1663 : static int peek(struct lexer *lexer)
289 : {
290 1663 : int chr = next(lexer);
291 :
292 1663 : backup(lexer);
293 :
294 1663 : return chr;
295 : }
296 :
297 202796 : static size_t remaining(struct lexer *lexer)
298 : {
299 202796 : return (size_t)(lexer->end - lexer->pos);
300 : }
301 :
302 : static void *lex_config(struct lexer *lexer);
303 : static void *lex_variable(struct lexer *lexer);
304 :
305 275156 : static bool is_string(int chr)
306 : {
307 275156 : return chr && !isspace(chr) && chr != '=' && chr != '#' && chr != '{' && chr != '}';
308 : }
309 :
310 32019 : static void *lex_string(struct lexer *lexer)
311 : {
312 : int chr;
313 :
314 : do {
315 243137 : chr = next(lexer);
316 :
317 243137 : if (chr == '$' && peek(lexer) == '{') {
318 0 : backup(lexer);
319 0 : emit(lexer, LEXEME_STRING);
320 :
321 0 : advance_n(lexer, strlen("{"));
322 :
323 0 : return lex_variable;
324 : }
325 243137 : } while (is_string(chr));
326 :
327 32019 : backup(lexer);
328 32019 : emit(lexer, LEXEME_STRING);
329 :
330 32019 : return lex_config;
331 : }
332 :
333 10995 : static struct config *config_from_parser(struct parser *parser)
334 : {
335 10995 : return container_of(parser, struct config, parser);
336 : }
337 :
338 0 : static struct config *config_from_lexer(struct lexer *lexer)
339 : {
340 0 : struct parser *parser = container_of(lexer, struct parser, lexer);
341 :
342 0 : return config_from_parser(parser);
343 : }
344 :
345 202796 : static bool lex_streq(struct lexer *lexer, const char *str, size_t s)
346 : {
347 202796 : if (remaining(lexer) < s)
348 0 : return false;
349 :
350 202796 : return !strncmp(lexer->pos, str, s);
351 : }
352 :
353 1141 : static void *lex_multiline_string(struct lexer *lexer)
354 : {
355 1141 : const char *end = (peek(lexer) == '"') ? "\"\"\"" : "'''";
356 :
357 1141 : advance_n(lexer, strlen("'''") - 1);
358 :
359 : do {
360 201655 : if (lex_streq(lexer, end, 3)) {
361 1141 : emit(lexer, LEXEME_STRING);
362 1141 : lexer->pos += 3;
363 :
364 1141 : return lex_config;
365 : }
366 200514 : } while (next(lexer) != '\0');
367 :
368 0 : return LEX_ERROR(lexer, "EOF while scanning multiline string");
369 : }
370 :
371 4176 : static bool is_variable(int chr)
372 : {
373 4176 : return isalpha(chr) || chr == '_';
374 : }
375 :
376 261 : static void *lex_variable_default(struct lexer *lexer)
377 : {
378 : int chr;
379 :
380 : do {
381 609 : chr = next(lexer);
382 :
383 609 : if (chr == '}') {
384 261 : backup(lexer);
385 261 : emit(lexer, LEXEME_STRING);
386 :
387 261 : advance_n(lexer, strlen("}"));
388 :
389 261 : return lex_config;
390 : }
391 348 : } while (chr != '\0');
392 :
393 0 : return LEX_ERROR(lexer, "EOF while scanning for default value for variable");
394 : }
395 :
396 522 : static void *lex_variable(struct lexer *lexer)
397 : {
398 : int chr;
399 :
400 522 : advance_n(lexer, strlen("${") - 1);
401 :
402 : do {
403 4698 : chr = next(lexer);
404 :
405 4698 : if (chr == ':') {
406 261 : backup(lexer);
407 :
408 261 : if (!current_len(lexer))
409 0 : return LEX_ERROR(lexer, "Expecting environment variable name");
410 :
411 261 : emit(lexer, LEXEME_VARIABLE_DEFAULT);
412 261 : advance_n(lexer, strlen(":"));
413 261 : return lex_variable_default;
414 : }
415 :
416 4437 : if (chr == '}') {
417 261 : backup(lexer);
418 :
419 261 : if (!current_len(lexer))
420 0 : return LEX_ERROR(lexer, "Expecting environment variable name");
421 :
422 261 : emit(lexer, LEXEME_VARIABLE);
423 261 : advance_n(lexer, strlen("}"));
424 :
425 261 : return lex_config;
426 : }
427 4176 : } while (is_variable(chr));
428 :
429 0 : return LEX_ERROR(lexer, "EOF while scanning for end of variable");
430 : }
431 :
432 82615 : static bool is_comment(int chr)
433 : {
434 82615 : return chr != '\0' && chr != '\n';
435 : }
436 :
437 1581 : static void *lex_comment(struct lexer *lexer)
438 : {
439 82615 : while (is_comment(next(lexer)))
440 : ;
441 1581 : backup(lexer);
442 1581 : return lex_config;
443 : }
444 :
445 77663 : static void *lex_config(struct lexer *lexer)
446 : {
447 222091 : while (true) {
448 299754 : int chr = next(lexer);
449 :
450 299754 : if (chr == '\0')
451 356 : break;
452 :
453 299398 : if (chr == '\n') {
454 21625 : emit(lexer, LEXEME_LINEFEED);
455 21625 : return lex_config;
456 : }
457 :
458 277773 : if (isspace(chr)) {
459 222091 : ignore(lexer);
460 222091 : continue;
461 : }
462 :
463 55682 : if (chr == '{') {
464 4708 : emit(lexer, LEXEME_OPEN_BRACKET);
465 4708 : return lex_config;
466 : }
467 :
468 50974 : if (chr == '}') {
469 : /* Emitting a linefeed lexeme before a close bracket lexeme
470 : * simplifies the parser and allows for situations where a
471 : * section is closed when declaring a key/value pair
472 : * (e.g. "section{key=value}" all in a single line).
473 : */
474 5931 : emit(lexer, LEXEME_LINEFEED);
475 5931 : emit(lexer, LEXEME_CLOSE_BRACKET);
476 5931 : return lex_config;
477 : }
478 :
479 45043 : if (chr == '=') {
480 9780 : emit(lexer, LEXEME_EQUAL);
481 9780 : return lex_config;
482 : }
483 :
484 35263 : if (chr == '#')
485 1581 : return lex_comment;
486 :
487 33682 : if (chr == '\'' && lex_streq(lexer, "''", 2))
488 880 : return lex_multiline_string;
489 32802 : if (chr == '"' && lex_streq(lexer, "\"\"", 2))
490 261 : return lex_multiline_string;
491 :
492 32541 : if (chr == '$' && peek(lexer) == '{')
493 522 : return lex_variable;
494 :
495 32019 : if (is_string(chr))
496 32019 : return lex_string;
497 :
498 0 : return LEX_ERROR(lexer, "Invalid character: '%c'", chr);
499 : }
500 :
501 356 : emit(lexer, LEXEME_LINEFEED);
502 356 : emit(lexer, LEXEME_EOF);
503 :
504 356 : return NULL;
505 : }
506 :
507 82630 : static const struct lexeme *lex_next(struct lexer *lexer)
508 : {
509 195817 : while (lexer->state) {
510 : const struct lexeme *lexeme;
511 :
512 195105 : if ((lexeme = lexeme_ring_buffer_get_ptr_or_null(&lexer->buffer)))
513 81918 : return lexeme;
514 :
515 113187 : lexer->state = lexer->state(lexer);
516 : }
517 :
518 712 : return lexeme_ring_buffer_get_ptr_or_null(&lexer->buffer);
519 : }
520 :
521 : static void *parse_config(struct parser *parser);
522 : static void *parse_section_end(struct parser *parser);
523 :
524 : #define ENV_VAR_NAME_LEN_MAX 64
525 :
526 : static __attribute__((noinline)) const char *
527 522 : secure_getenv_len(struct parser *parser, const char *key, size_t len)
528 : {
529 522 : if (UNLIKELY(len > ENV_VAR_NAME_LEN_MAX)) {
530 0 : return PARSER_ERROR(parser, "Variable name \"%.*s\" exceeds %d bytes",
531 : (int)len, key, ENV_VAR_NAME_LEN_MAX);
532 : }
533 :
534 522 : return secure_getenv(strndupa(key, len));
535 : }
536 :
537 7953 : static void *parse_key_value(struct parser *parser)
538 : {
539 7953 : struct config_line line = {.type = CONFIG_LINE_TYPE_LINE};
540 : const struct lexeme *lexeme;
541 7953 : enum lexeme_type last_lexeme = TOTAL_LEXEMES;
542 : size_t key_size;
543 :
544 28045 : while ((lexeme = lexeme_ring_buffer_get_ptr_or_null(&parser->buffer))) {
545 12139 : if (lexeme->type != LEXEME_STRING)
546 0 : return PARSER_ERROR(parser, "Expecting string");
547 :
548 12139 : lwan_strbuf_append_str(&parser->strbuf, lexeme->value.value,
549 12139 : lexeme->value.len);
550 :
551 12139 : if (!lexeme_ring_buffer_empty(&parser->buffer))
552 4186 : lwan_strbuf_append_char(&parser->strbuf, '_');
553 : }
554 7953 : key_size = lwan_strbuf_get_length(&parser->strbuf);
555 7953 : lwan_strbuf_append_char(&parser->strbuf, '\0');
556 :
557 19821 : while ((lexeme = lex_next(&parser->lexer))) {
558 19821 : switch (lexeme->type) {
559 261 : case LEXEME_VARIABLE: {
560 261 : const char *value = secure_getenv_len(parser, lexeme->value.value,
561 261 : lexeme->value.len);
562 261 : if (!value) {
563 0 : return PARSER_ERROR(
564 : parser, "Variable '$%.*s' not defined in environment",
565 : (int)lexeme->value.len, lexeme->value.value);
566 : }
567 :
568 261 : lwan_strbuf_append_strz(&parser->strbuf, value);
569 :
570 261 : break;
571 : }
572 :
573 261 : case LEXEME_VARIABLE_DEFAULT: {
574 261 : const char *value = secure_getenv_len(parser, lexeme->value.value,
575 261 : lexeme->value.len);
576 261 : const struct lexeme *var_name = lexeme;
577 :
578 261 : if (!(lexeme = lex_next(&parser->lexer))) {
579 0 : return PARSER_ERROR(
580 : parser, "Default value for variable '$%.*s' not given",
581 : (int)var_name->value.len, var_name->value.value);
582 : }
583 :
584 261 : if (lexeme->type != LEXEME_STRING)
585 0 : return PARSER_ERROR(parser, "Wrong format for default value");
586 :
587 261 : if (!value) {
588 234 : lwan_status_debug(
589 : "Using default value of '%.*s' for variable '${%.*s}'",
590 : (int)lexeme->value.len, lexeme->value.value,
591 : (int)var_name->value.len, var_name->value.value);
592 234 : lwan_strbuf_append_str(&parser->strbuf, lexeme->value.value,
593 234 : lexeme->value.len);
594 : } else {
595 27 : lwan_strbuf_append_strz(&parser->strbuf, value);
596 : }
597 :
598 261 : break;
599 : }
600 :
601 1827 : case LEXEME_EQUAL:
602 1827 : lwan_strbuf_append_char(&parser->strbuf, '=');
603 1827 : break;
604 :
605 9519 : case LEXEME_STRING:
606 9519 : if (last_lexeme == LEXEME_STRING)
607 261 : lwan_strbuf_append_char(&parser->strbuf, ' ');
608 :
609 9519 : lwan_strbuf_append_str(&parser->strbuf, lexeme->value.value,
610 9519 : lexeme->value.len);
611 :
612 9519 : break;
613 :
614 7953 : case LEXEME_LINEFEED:
615 7953 : line.key = lwan_strbuf_get_buffer(&parser->strbuf);
616 7953 : line.value = line.key + key_size + 1;
617 :
618 7953 : if (config_ring_buffer_try_put(&parser->items, &line))
619 7953 : return parse_config;
620 :
621 0 : return PARSER_ERROR(parser,
622 : "Could not add key/value to ring buffer");
623 :
624 0 : case LEXEME_OPEN_BRACKET:
625 0 : return PARSER_ERROR(parser, "Open bracket not expected here");
626 :
627 0 : case LEXEME_CLOSE_BRACKET:
628 0 : return INTERNAL_ERROR(
629 : parser, "Close bracket found while parsing key/value");
630 :
631 0 : case LEXEME_EOF:
632 0 : return INTERNAL_ERROR(
633 : parser, "EOF found while parsing key/value");
634 :
635 : case TOTAL_LEXEMES:
636 : __builtin_unreachable();
637 : }
638 :
639 11868 : last_lexeme = lexeme->type;
640 : }
641 :
642 0 : return PARSER_ERROR(parser, "EOF while parsing key-value");
643 : }
644 :
645 5884 : static void *parse_section(struct parser *parser)
646 : {
647 : const struct lexeme *lexeme;
648 : size_t name_len;
649 :
650 5884 : lexeme = lexeme_ring_buffer_get_ptr_or_null(&parser->buffer);
651 5884 : if (!lexeme || lexeme->type != LEXEME_STRING)
652 0 : return PARSER_ERROR(parser, "Expecting a string");
653 :
654 5884 : lwan_strbuf_append_str(&parser->strbuf, lexeme->value.value,
655 5884 : lexeme->value.len);
656 5884 : name_len = lexeme->value.len;
657 5884 : lwan_strbuf_append_char(&parser->strbuf, '\0');
658 :
659 17386 : while ((lexeme = lexeme_ring_buffer_get_ptr_or_null(&parser->buffer))) {
660 5618 : if (lexeme->type != LEXEME_STRING)
661 0 : return PARSER_ERROR(parser, "Expecting a string");
662 :
663 5618 : lwan_strbuf_append_str(&parser->strbuf, lexeme->value.value,
664 5618 : lexeme->value.len);
665 :
666 5618 : if (!lexeme_ring_buffer_empty(&parser->buffer))
667 0 : lwan_strbuf_append_char(&parser->strbuf, ' ');
668 : }
669 :
670 11768 : struct config_line line = {
671 : .type = CONFIG_LINE_TYPE_SECTION,
672 5884 : .key = lwan_strbuf_get_buffer(&parser->strbuf),
673 5884 : .value = lwan_strbuf_get_buffer(&parser->strbuf) + name_len + 1,
674 : };
675 5884 : return config_ring_buffer_try_put(&parser->items, &line) ? parse_config
676 5884 : : NULL;
677 : }
678 :
679 1176 : static void *parse_section_shorthand(struct parser *parser)
680 : {
681 1176 : void *next_state = parse_section(parser);
682 :
683 1176 : if (next_state) {
684 1176 : struct config_line line = {.type = CONFIG_LINE_TYPE_SECTION_END};
685 :
686 1176 : if (config_ring_buffer_try_put(&parser->items, &line))
687 1176 : return next_state;
688 :
689 0 : return INTERNAL_ERROR(parser, "couldn't append line to internal ring buffer");
690 : }
691 :
692 0 : return NULL;
693 : }
694 :
695 5931 : static void *parse_section_end(struct parser *parser)
696 : {
697 5931 : struct config_line line = {.type = CONFIG_LINE_TYPE_SECTION_END};
698 5931 : struct config *config = config_from_parser(parser);
699 :
700 5931 : if (!config->opened_brackets)
701 0 : return PARSER_ERROR(parser, "Section closed before it opened");
702 :
703 5931 : if (!lexeme_ring_buffer_empty(&parser->buffer))
704 0 : return PARSER_ERROR(parser, "Not expecting a close bracket here");
705 :
706 5931 : if (!config_ring_buffer_try_put(&parser->items, &line)) {
707 0 : return INTERNAL_ERROR(parser,
708 : "could not store section end in ring buffer");
709 : }
710 :
711 5931 : config->opened_brackets--;
712 :
713 5931 : return parse_config;
714 : }
715 :
716 62548 : static void *parse_config(struct parser *parser)
717 : {
718 62548 : const struct lexeme *lexeme = lex_next(&parser->lexer);
719 :
720 62548 : if (!lexeme) {
721 : /* EOF is signaled by a LEXEME_EOF from the parser, so
722 : * this should never happen. */
723 0 : return INTERNAL_ERROR(parser, "could not obtain lexeme");
724 : }
725 :
726 62548 : switch (lexeme->type) {
727 7953 : case LEXEME_EQUAL:
728 7953 : if (lexeme_ring_buffer_empty(&parser->buffer))
729 0 : return PARSER_ERROR(parser, "Keys can´t be empty");
730 :
731 7953 : return parse_key_value;
732 :
733 4708 : case LEXEME_OPEN_BRACKET:
734 4708 : if (lexeme_ring_buffer_empty(&parser->buffer))
735 0 : return PARSER_ERROR(parser, "Section names can´t be empty");
736 :
737 4708 : config_from_parser(parser)->opened_brackets++;
738 :
739 4708 : return parse_section;
740 :
741 19959 : case LEXEME_LINEFEED:
742 19959 : if (!lexeme_ring_buffer_empty(&parser->buffer))
743 1176 : return parse_section_shorthand;
744 :
745 18783 : return parse_config;
746 :
747 23641 : case LEXEME_STRING:
748 23641 : if (!lexeme_ring_buffer_try_put(&parser->buffer, lexeme))
749 0 : return INTERNAL_ERROR(parser, "could not store string in ring buffer");
750 :
751 23641 : return parse_config;
752 :
753 5931 : case LEXEME_CLOSE_BRACKET:
754 5931 : return parse_section_end;
755 :
756 356 : case LEXEME_EOF:
757 356 : if (config_from_parser(parser)->opened_brackets)
758 0 : return PARSER_ERROR(parser, "EOF while looking for a close bracket");
759 :
760 356 : if (!lexeme_ring_buffer_empty(&parser->buffer))
761 0 : return INTERNAL_ERROR(parser, "premature EOF");
762 :
763 356 : break;
764 :
765 0 : case LEXEME_VARIABLE:
766 : case LEXEME_VARIABLE_DEFAULT:
767 0 : return PARSER_ERROR(parser, "Variable '%.*s' can't be used here",
768 : (int)lexeme->value.len, lexeme->value.value);
769 :
770 : case TOTAL_LEXEMES:
771 : __builtin_unreachable();
772 : }
773 :
774 356 : return NULL;
775 : }
776 :
777 22297 : static const struct config_line *parser_next(struct parser *parser)
778 : {
779 104613 : while (parser->state) {
780 : const struct config_line *line;
781 :
782 104257 : if ((line = config_ring_buffer_get_ptr_or_null(&parser->items)))
783 21941 : return line;
784 :
785 82316 : lwan_strbuf_reset(&parser->strbuf);
786 :
787 82316 : parser->state = parser->state(parser);
788 : }
789 :
790 356 : return config_ring_buffer_get_ptr_or_null(&parser->items);
791 : }
792 :
793 : static struct config *
794 95 : config_open_path(const char *path, void **data, size_t *size)
795 : {
796 : struct config *config;
797 : struct stat st;
798 : void *mapped;
799 : int fd;
800 :
801 95 : fd = open(path, O_RDONLY | O_CLOEXEC);
802 95 : if (fd < 0) {
803 0 : lwan_status_perror("Could not open configuration file: %s", path);
804 0 : return NULL;
805 : }
806 :
807 95 : if (fstat(fd, &st) < 0) {
808 0 : close(fd);
809 0 : return NULL;
810 : }
811 :
812 95 : mapped = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
813 95 : close(fd);
814 95 : if (mapped == MAP_FAILED)
815 0 : return NULL;
816 :
817 95 : config = malloc(sizeof(*config));
818 95 : if (!config) {
819 0 : munmap(mapped, (size_t)st.st_size);
820 0 : return NULL;
821 : }
822 :
823 95 : *data = config->mapped.addr = mapped;
824 95 : *size = config->mapped.sz = (size_t)st.st_size;
825 :
826 95 : return config;
827 : }
828 :
829 : static struct config *
830 95 : config_init_data(struct config *config, const void *data, size_t len)
831 : {
832 95 : config->parser = (struct parser){
833 : .state = parse_config,
834 : .lexer =
835 : {
836 : .state = lex_config,
837 : .pos = data,
838 : .start = data,
839 95 : .end = (char *)data + len,
840 : .cur_line = 1,
841 : },
842 : };
843 :
844 95 : config->error_message = NULL;
845 95 : config->opened_brackets = 0;
846 :
847 95 : lwan_strbuf_init(&config->parser.strbuf);
848 95 : config_ring_buffer_init(&config->parser.items);
849 95 : lexeme_ring_buffer_init(&config->parser.buffer);
850 :
851 95 : return config;
852 : }
853 :
854 95 : struct config *config_open(const char *path)
855 : {
856 : struct config *config;
857 : void *data;
858 : size_t len;
859 :
860 95 : config = config_open_path(path, &data, &len);
861 95 : return config ? config_init_data(config, data, len) : NULL;
862 : }
863 :
864 : #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
865 : struct config *config_open_for_fuzzing(const uint8_t *data, size_t len)
866 : {
867 : struct config *config = malloc(sizeof(*config));
868 :
869 : if (config) {
870 : config->mapped.addr = NULL;
871 : config->mapped.sz = 0;
872 :
873 : return config_init_data(config, data, len - 1);
874 : }
875 :
876 : return NULL;
877 : }
878 : #endif
879 :
880 2054 : void config_close(struct config *config)
881 : {
882 2054 : if (!config)
883 0 : return;
884 :
885 : #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
886 2054 : if (config->mapped.addr)
887 95 : munmap(config->mapped.addr, config->mapped.sz);
888 : #endif
889 :
890 2054 : free(config->error_message);
891 2054 : lwan_strbuf_free(&config->parser.strbuf);
892 2054 : free(config);
893 : }
894 :
895 12058 : const struct config_line *config_read_line(struct config *conf)
896 : {
897 12058 : return conf->error_message ? NULL : parser_next(&conf->parser);
898 : }
899 :
900 2742 : static bool find_section_end(struct config *config)
901 : {
902 : const struct config_line *line;
903 2742 : int cur_level = 1;
904 :
905 2742 : if (config->error_message)
906 0 : return false;
907 :
908 10239 : while ((line = parser_next(&config->parser))) {
909 10239 : if (line->type == CONFIG_LINE_TYPE_SECTION) {
910 1566 : cur_level++;
911 8673 : } else if (line->type == CONFIG_LINE_TYPE_SECTION_END) {
912 4308 : cur_level--;
913 :
914 4308 : if (!cur_level)
915 2742 : return true;
916 : }
917 : }
918 :
919 0 : return false;
920 : }
921 :
922 1959 : struct config *config_isolate_section(struct config *current_conf,
923 : const struct config_line *current_line)
924 : {
925 : struct lexer *lexer;
926 : struct config *isolated;
927 : const char *pos;
928 :
929 1959 : if (current_line->type != CONFIG_LINE_TYPE_SECTION)
930 0 : return NULL;
931 :
932 1959 : isolated = malloc(sizeof(*isolated));
933 1959 : if (!isolated)
934 0 : return NULL;
935 :
936 1959 : memcpy(isolated, current_conf, sizeof(*isolated));
937 1959 : lwan_strbuf_init(&isolated->parser.strbuf);
938 :
939 1959 : isolated->mapped.addr = NULL;
940 1959 : isolated->mapped.sz = 0;
941 : /* Keep opened_brackets from the original */
942 :
943 1959 : lexer = &isolated->parser.lexer;
944 1959 : lexer->start = lexer->pos;
945 :
946 1959 : pos = isolated->parser.lexer.pos;
947 1959 : if (!find_section_end(isolated)) {
948 0 : lwan_strbuf_free(&isolated->parser.strbuf);
949 0 : free(isolated);
950 :
951 0 : config_error(current_conf,
952 : "Could not find section end while trying to isolate");
953 :
954 0 : return NULL;
955 : }
956 :
957 1959 : lexer->end = lexer->pos;
958 1959 : lexer->start = lexer->pos = pos;
959 :
960 1959 : return isolated;
961 : }
962 :
963 783 : bool config_skip_section(struct config *conf, const struct config_line *line)
964 : {
965 783 : if (line->type != CONFIG_LINE_TYPE_SECTION)
966 0 : return false;
967 :
968 783 : return find_section_end(conf);
969 : }
970 :
971 356 : const char *config_last_error(struct config *conf)
972 : {
973 356 : return conf->error_message;
974 : }
975 :
976 0 : int config_cur_line(struct config *conf)
977 : {
978 0 : return conf->parser.lexer.cur_line;
979 : }
|