aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Veresov <aleksey@veresov.pro>2020-03-17 23:57:32 +0300
committerAleksey Veresov <aleksey@veresov.pro>2020-03-17 23:57:32 +0300
commitb54bed506105bef2af9c1bb03cb0f709d0acdb3d (patch)
tree23d0f3ca371b1f9472affab6b20a996558778b92
parent1d8e7d8ef36de7bae2c62f63bec0e9914f18e77d (diff)
downloadmagi-b54bed506105bef2af9c1bb03cb0f709d0acdb3d.tar
magi-b54bed506105bef2af9c1bb03cb0f709d0acdb3d.tar.xz
magi-b54bed506105bef2af9c1bb03cb0f709d0acdb3d.zip
[magi] Cookies parse rewritten.
-rw-r--r--src/cookies.c158
-rw-r--r--src/urlencoded.c30
2 files changed, 64 insertions, 124 deletions
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 <string.h>
-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);
diff --git a/src/urlencoded.c b/src/urlencoded.c
index b0891dc..755b059 100644
--- a/src/urlencoded.c
+++ b/src/urlencoded.c
@@ -79,17 +79,11 @@ static void state_parse_name(automata *a, char c)
{
if (c == '&' || c == ';') {
a->s = 0;
- return;
- }
- if (c == '=') {
- if (!deurl(&a->name)) {
- a->s = 0;
- return;
- }
- a->s = state_parse_data;
- return;
+ } else if (c == '=') {
+ a->s = deurl(&a->name) ? state_parse_data : 0;
+ } else {
+ magi_str_add(&a->name, &a->nlen, &a->nsize, c);
}
- magi_str_add(&a->name, &a->nlen, &a->nsize, c);
}
static void add_to_list(automata *a)
@@ -106,18 +100,16 @@ static void state_parse_data(automata *a, char c)
{
if (c == '=') {
a->s = 0;
- return;
- }
- if (c == '&' || c == ';') {
- if (!deurl(&a->data)) {
+ } else if (c == '&' || c == ';') {
+ if (deurl(&a->data)) {
+ a->s = state_parse_name;
+ add_to_list(a);
+ } else {
a->s = 0;
- return;
}
- add_to_list(a);
- a->s = state_parse_name;
- return;
+ } else {
+ magi_str_add(&a->data, &a->dlen, &a->dsize, c);
}
- magi_str_add(&a->data, &a->dlen, &a->dsize, c);
}
magi_error magi_parse_urlencoded(magi_params **list, const char *encoded)