From b54bed506105bef2af9c1bb03cb0f709d0acdb3d Mon Sep 17 00:00:00 2001 From: Aleksey Veresov Date: Tue, 17 Mar 2020 23:57:32 +0300 Subject: [magi] Cookies parse rewritten. --- src/cookies.c | 158 ++++++++++++++++++++-------------------------------------- 1 file changed, 53 insertions(+), 105 deletions(-) (limited to 'src/cookies.c') diff --git a/src/cookies.c b/src/cookies.c index f5b030e..88ed67a 100644 --- a/src/cookies.c +++ b/src/cookies.c @@ -1,4 +1,3 @@ -/* * * TODO * * */ #include "cookies.h" #include "tools.h" @@ -6,19 +5,12 @@ #include -typedef enum st { - st_error = 0, - st_pre_name, - st_name, - st_post_name, - st_pre_data, - st_data, - st_post_data -} st; - typedef enum dt { dt_plain = 0, dt_version, dt_path, dt_domain } dt; -typedef struct automata { +typedef struct automata automata; +typedef void (*state)(automata *a, char c); +struct automata { + state s; magi_cookies **list; magi_cookie cookie; char *buf; @@ -28,7 +20,7 @@ typedef struct automata { int is_advanced; int is_quoted; dt datatype; -} automata; +}; static void nulify_cookie(automata *a) @@ -91,139 +83,104 @@ static int end_data(automata *a) return 1; } - -static st parse_pre_name(automata *a, char c) +static void state_name(automata *a, char c); +static void state_pre_name(automata *a, char c) { - st state; - if (c == ' ' || c == '\t') { - state = st_name; - } else if (32 <= c && c <= 126 && !strchr("()<>@,;:\\\"/[]?={}", c)) { - state = st_name; + if (32 <= c && c <= 126 && !strchr("()<>@,;:\\\"/[]?={}", c)) { + a->s = state_name; magi_str_add(&a->buf, &a->buf_len, &a->buf_size, c); - } else { - state = st_error; + } else if (c != ' ' && c != '\t'){ + a->s = 0; } - return state; } -static st parse_name(automata *a, char c) +static void state_pre_data(automata *a, char c); +static void state_post_name(automata *a, char c); +static void state_name(automata *a, char c) { - st state; if (c == '=') { - state = st_pre_data; + a->s = state_pre_data; end_name(a); } else if (c == ' ' || c == '\t') { - state = st_post_name; + a->s = state_post_name; end_name(a); } else if (32 <= c && c <= 126 && !strchr("()<>@,;:\\\"/[]?={}", c)) { - state = st_name; magi_str_add(&a->buf, &a->buf_len, &a->buf_size, c); } else { - state = st_error; + a->s = 0; } - return state; } -static st parse_post_name(char c) +static void state_post_name(automata *a, char c) { - st state; if (c == '=') { - state = st_pre_data; - } else if (c == ' ' || c == '\t') { - state = st_post_name; - } else { - state = st_error; + a->s = state_pre_data; + } else if (c != ' ' && c != '\t') { + a->s = 0; } - return state; } -static st parse_pre_data(automata *a, char c) +static void state_data(automata *a, char c); +static void state_data_quoted(automata *a, char c); +static void state_pre_data(automata *a, char c) { - st state; - if (c == ' ' || c == '\t') { - state = st_pre_data; - } else if (c == '"') { - state = st_data; - a->is_quoted = 1; + if (c == '"') { + a->s = state_data_quoted; } else if (32 <= c && c <= 126 && !strchr("()<>@,;:\\\"/[]?={}", c)) { - state = st_data; + a->s = state_data; magi_str_add(&a->buf, &a->buf_len, &a->buf_size, c); - } else { - state = st_error; + } else if (c != ' ' && c != '\t') { + a->s = 0; } - return state; } -static st parse_not_quoted_data(automata *a, char c) +static void state_post_data(automata *a, char c); +static void state_data(automata *a, char c) { - st state; if (c == ';' || (c == ',' && a->is_first)) { - state = st_pre_name; a->is_first = 0; - if (!end_data(a)) { - state = st_error; - } + a->s = end_data(a) ? state_pre_name : 0; } else if (c == ' ' || c == '\t') { - state = st_post_data; - if (!end_data(a)) { - state = st_error; - } + a->s = end_data(a) ? state_post_data : 0; } else if (32 <= c && c <= 126 && !strchr("()<>@,;:\\\"/[]?={}", c)) { - state = st_data; magi_str_add(&a->buf, &a->buf_len, &a->buf_size, c); } else { - state = st_error; + a->s = 0; } - return state; } -static st parse_data(automata *a, char c) +static void state_data_quoted(automata *a, char c) { - st state; - if (a->is_quoted) { - if (c == '"') { - state = st_post_data; - a->is_quoted = 0; - if (!end_data(a)) { - state = st_error; - } - } else { - state = st_data; - } - } else { - state = parse_not_quoted_data(a, c); + if (c == '"') { + a->s = end_data(a) ? state_post_data : 0; } - return state; } -static st parse_post_data(automata *a, char c) +static void state_post_data(automata *a, char c) { - st state; if (c == ';' || (c == ',' && a->is_first)) { - state = st_pre_name; - } else if (c == ' ' || c == '\t') { - state = st_post_data; - } else { - state = st_error; + a->is_first = 0; + a->s = state_pre_name; + } else if (c != ' ' && c != '\t') { + a->s = 0; } - return state; } -static void parse_end(magi_error *e, automata *a, st s) +static void parse_end(magi_error *e, automata *a) { - if (s == st_data) { - if (a->is_quoted || !a->cookie.name) { + if (a->s == state_data_quoted) { + *e = magi_error_cookies; + } else if (a->s == state_data) { + if (!a->cookie.name) { *e = magi_error_cookies; - return; - } - if (end_data(a)) { + } else if (end_data(a)) { magi_cookies_add(a->list, &a->cookie); nulify_cookie(a); } else { *e = magi_error_cookies; } - } else if (s != st_post_data) { + } else if (a->s != state_post_data) { *e = magi_error_cookies; } } @@ -231,22 +188,13 @@ static void parse_end(magi_error *e, automata *a, st s) void magi_parse_cookies(magi_request *request, const char *data) { - st state; - automata a = { 0, { 0, 0, 0, 0, 0 }, 0, 0, 0, 1, 0, 0, 0 }; + automata a = { 0, 0, { 0, 0, 0, 0, 0 }, 0, 0, 0, 1, 0, 0, 0 }; a.list = &request->cookies; request->cookies = 0; - for (state = st_pre_name; state && *data; ++data) { - switch (state) { - case st_pre_name: state = parse_pre_name(&a, *data); break; - case st_name: state = parse_name(&a, *data); break; - case st_post_name: state = parse_post_name(*data); break; - case st_pre_data: state = parse_pre_data(&a, *data); break; - case st_data: state = parse_data(&a, *data); break; - case st_post_data: state = parse_post_data(&a, *data); break; - default: break; - } + for (a.s = state_pre_name; a.s && *data; ++data) { + a.s(&a, *data); } - parse_end(&request->error, &a, state); + parse_end(&request->error, &a); free(a.cookie.name); free(a.cookie.data); free(a.cookie.path); -- cgit v1.2.3