From 7b8bb91e2f89268e839624ad2df0bc4b1853abea Mon Sep 17 00:00:00 2001 From: 0xdeadbeer Date: Tue, 3 Sep 2024 21:07:52 +0200 Subject: [PATCH] fix: remove cluttered state machine code --- Makefile | 2 +- README | 1 - streecmp | 2 +- headers.c => strings.c | 10 ++ tinyparser | Bin 77032 -> 75528 bytes tinyparser.c | 212 ++++++++++++++--------------------------- tinyparser.h | 48 ++-------- 7 files changed, 90 insertions(+), 185 deletions(-) rename headers.c => strings.c (93%) diff --git a/Makefile b/Makefile index 1d7bc82..0cd406a 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC=gcc CFLAGS=-g3 -CFILES=tinyparser.c headers.c +CFILES=tinyparser.c strings.c CFILES_STREECMP=streecmp/streecmp.c OUTPUT=tinyparser diff --git a/README b/README index c316e63..b2199d8 100644 --- a/README +++ b/README @@ -20,7 +20,6 @@ TODO * headers table needs length fields * refactor header parsing - * refactor state machine * implement tests * integrations with tinyproxy..? diff --git a/streecmp b/streecmp index 42ed963..ca1293a 160000 --- a/streecmp +++ b/streecmp @@ -1 +1 @@ -Subproject commit 42ed96353d186078e34e4c541e7c92d433cda138 +Subproject commit ca1293aa8f123adb91d80f687933ea5c596c114a diff --git a/headers.c b/strings.c similarity index 93% rename from headers.c rename to strings.c index ccb1e79..673cd6a 100644 --- a/headers.c +++ b/strings.c @@ -1,3 +1,13 @@ +char *methods = "GET\n" + "HEAD\n" + "POST\n" + "PUT\n" + "DELETE\n" + "CONNECT\n" + "OPTIONS\n" + "TRACE\n" + "PATCH\n"; + char *headers = "A-IM\n" "Accept\n" "Accept-Charset\n" diff --git a/tinyparser b/tinyparser index 27b4e40a8cd2741ba199a9dcc164abd982048dab..87609c2dde0f925cf9b2671bef775382bad68c3b 100755 GIT binary patch delta 22523 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 delta 24551 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 '0' && *ch <= '9') continue; - if (*ch >= 'A' && *ch <= 'Z') continue; - if (*ch >= 'a' && *ch <= 'z') continue; - if (*ch >= '#' && *ch <= '/') continue; - if (*ch == '!') continue; - if (*ch == ':') continue; - if (*ch == ';') continue; - if (*ch == '=') continue; - if (*ch == '?') continue; - if (*ch == '@') continue; - if (*ch == '[') continue; - if (*ch == ']') continue; - if (*ch == '_') continue; - if (*ch == '~') continue; - - return -1; - } - - return diff; -} - int parse_header(char *offset, int len) { int cursor = 0; int ret = 0; @@ -94,108 +61,55 @@ int parse_header(char *offset, int len) { } int parse_title(char *offset, int len) { - int cursor = 0; + int ret = 0; + int diff = 0; + char *cursor = offset; + char *cursor_lim = cursor+len; - while (state != state_title_ok && state != state_title_err) { - if (cursor >= len) { - state = state_title_err; - err = err_parse_title; - } - - int ret = 0; - char *ch = offset+cursor; - char *lim = offset+len-1; - - switch (state) { - case state_init: - state = state_title_method; - break; - case state_title_method: - if ((ret = cmp_orig(ch, "GET", lim))) { - cursor += ret; - state = state_title_after_method; - method = method_get; - break; - } - if ((ret = cmp_orig(ch, "POST", lim))) { - cursor += ret; - state = state_title_after_method; - method = method_post; - break; - } - if ((ret = cmp_orig(ch, "HEAD", lim))) { - cursor += ret; - state = state_title_after_method; - method = method_head; - break; - } - - state = state_title_err; - err = err_parse_title_method; - break; - case state_title_after_method: - cursor++; - state = state_title_uri; - break; - case state_title_uri: - if ((ret = cmp_ascii(ch, lim)) <= 0) { - state = state_title_err; - err = err_parse_title_uri; - break; - } - - if (!(uri = strndup(ch, ret))) { - state = state_title_err; - err = err_memory; - break; - } - - uri_len = ret; - cursor += ret; - state = state_title_after_uri; - break; - case state_title_after_uri: - cursor++; - state = state_title_version; - break; - case state_title_version: - if ((ret = cmp_ascii(ch, lim)) <= 0) { - state = state_title_err; - err = err_parse_title_version; - break; - } - - if (!(ver = strndup(ch, ret))) { - state = state_title_err; - err = err_memory; - break; - } - - ver_len = ret; - cursor += ret; - state = state_title_ok; - break; - case state_title_ok: - for (;ch < lim;ch++) { - if (*ch == ' ') continue; - if (*ch == '\t') continue; - if (*ch == '\0') continue; - if (*ch == '\r') continue; - - state = state_title_err; - err = err_parse_title; - break; - } - break; - case state_title_err: - fprintf(stderr, "failed\n"); - return -1; - break; - default: - break; - } + // method + char *method_lim = strchr(offset, ' '); + if (!method_lim) { + return -1; } + diff = method_lim-cursor; + ret = streencmp(method_tree, cursor, diff); + if (ret == 0) { + return -1; + } + + method = ret; + cursor += diff; + + // white space + while (*cursor == ' ') { + cursor++; + } + + // uri + char *uri_lim = strchr(cursor, ' '); + if (!uri_lim) { + return -1; + } + + diff = uri_lim-cursor; + uri = cursor; + uri_len = diff; + + cursor += diff; + + // white space + while (*cursor == ' ') { + cursor++; + } + + // ver + diff = cursor_lim-cursor; + ver = cursor; + ver_len = diff; + + cursor += diff; + return 0; } @@ -217,7 +131,6 @@ int parse_request(char *buffer) { // IF END OF MESSAGE if (!header_len) { - state = state_fin; break; } @@ -227,9 +140,6 @@ int parse_request(char *buffer) { } } - free(uri); - free(ver); - return 0; } @@ -249,8 +159,20 @@ int main(void) { return -1; } + method_tree = allocnod(); + if (!method_tree) { + fprintf(stderr, "Not enough dynamic memory\n"); + return -1; + } + ret = gentree(header_tree, headers, NULL); - if (gentree < 0) { + if (ret < 0) { + fprintf(stderr, "Failed generating the header comparison tree\n"); + return -1; + } + + ret = gentree(method_tree, methods, NULL); + if (ret < 0) { fprintf(stderr, "Failed generating the header comparison tree\n"); return -1; } @@ -261,8 +183,14 @@ int main(void) { return -1; } - fprintf(stderr, "Finished parsing request\n"); + fprintf(stderr, "[+] Finished parsing request\n" + " method: %d\n" + " uri : %.*s\n" + " ver : %.*s\n", + method, uri_len, uri, ver_len, ver + ); + frenod(method_tree); frenod(header_tree); free(header_table); free(str); diff --git a/tinyparser.h b/tinyparser.h index b6d3002..0e54d21 100644 --- a/tinyparser.h +++ b/tinyparser.h @@ -13,49 +13,17 @@ // ENUMS -// SRC:https://datatracker.ietf.org/doc/html/rfc2616 -enum errs { - err_init = 0, - err_generic, - err_memory, - err_parse_title, - err_parse_title_method, - err_parse_title_uri, - err_parse_title_version, - err_parse_header_not_found -}; - -// SRC:https://datatracker.ietf.org/doc/html/rfc2616 -enum states { - state_init = 0, - state_title_method, - state_title_after_method, - state_title_uri, - state_title_after_uri, - state_title_version, - state_title_ok, - state_title_err, - - state_header_init, - state_header_alloc, - state_header_parse, - state_header_not_found, - state_header_ok, - state_header_err, - - state_body_init, - state_body_ok, - state_body_err, - - state_fin, -}; - // SRC:https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods enum methods { - method_init = 0, - method_get, + method_get = 1, + method_head, method_post, - method_head + method_put, + method_delete, + method_connect, + method_options, + method_trace, + method_patch }; // SRC:https://en.wikipedia.org/wiki/List_of_HTTP_header_fields