From 84055b8c90806754091bbd7193dd1703898a1923 Mon Sep 17 00:00:00 2001 From: 0xdeadbeer Date: Wed, 4 Sep 2024 09:06:42 +0200 Subject: [PATCH] fix: edit docs and re-design struct use --- README | 17 ++++- tinyparser | Bin 75984 -> 0 bytes tinyparser.c | 182 ++++++++++++++++++++++----------------------------- tinyparser.h | 20 +++++- 4 files changed, 114 insertions(+), 105 deletions(-) delete mode 100755 tinyparser diff --git a/README b/README index e5f0d25..ed94734 100644 --- a/README +++ b/README @@ -8,6 +8,22 @@ RES: github.com/tinyproxy/tinyproxy RES: github.com/nginx/nginx +TECHNICALS + + int initres(void); + void fretres(void); + int readlin(char **buff, char **buff_lim); + int parshfield(char **offset, int len, /* out */ struct point *hentries); + int parstitle(char *offset, int len, /* out */ struct httitle *titl); + int parsme(char **buff, /* out */ struct httpars *pars); + + Library is designed to follow source input unaltering. + Which means, that it does not directly alter the input + data or strings while storing the information of all + parsed results on the stack or as pointers to specific + parts of the source data. This allows to provide it + with input that resides both within the stack or heap. + LEAKS LEAKS file contains the most recent valgrind memory leaks @@ -18,7 +34,6 @@ LEAKS TODO - * headers table needs length fields * implement tests * integrations with tinyproxy..? diff --git a/tinyparser b/tinyparser deleted file mode 100755 index 38dc33e62c552e17157649013d568b62336d002f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 75984 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

m0#x6TJ&Khq{qSREr)C241dtVtJwutkU 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

PlXJAi0i6?aoSu%vbRG-K%-MqLbGTgOVKU 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 KDtLHwUH=0g^RC1I diff --git a/tinyparser.c b/tinyparser.c index 09a0379..4ca407b 100644 --- a/tinyparser.c +++ b/tinyparser.c @@ -4,38 +4,83 @@ #include "tinyparser.h" #include "streecmp/streecmp.h" -extern char *headers; extern char *methods; +extern char *headers; -int method = 0; -char *uri = NULL; -char *ver = NULL; -int uri_len = 0; -int ver_len = 0; +static struct nod *method_tree = NULL; +static struct nod *header_tree = NULL; -struct nod *header_tree = NULL; -struct nod *method_tree = NULL; -struct point *header_table = NULL; +static void debug_stats(struct httpars *pars) { + fprintf(stderr, "\tstats:\n" + "\t\tmethod\t: %d\n" + "\t\turi\t: %.*s\n" + "\t\tver\t: %.*s\n", + pars->titl.method, + pars->titl.uri.len, pars->titl.uri.er, + pars->titl.ver.len, pars->titl.ver.er + ); -int read_line(char **buffer, char **buffer_limit) { + fprintf(stdout, "\theaders:\n"); + for (int i = 0; i < header_count; i++) { + struct point *pnt = &pars->hentries[i]; + if (!pnt->er) { + continue; + } + + fprintf(stdout, "\t\t%d\t: %.*s\n", i, pnt->len, pnt->er); + } +} + +int initres(void) { + int ret = 0; + + header_tree = allocnod(); + if (!header_tree) { + return -1; + } + + method_tree = allocnod(); + if (!method_tree) { + return -1; + } + + ret = gentree(header_tree, headers, NULL); + if (ret < 0) { + return -1; + } + + ret = gentree(method_tree, methods, NULL); + if (ret < 0) { + return -1; + } + + return 0; +} + +void fretres(void) { + free(method_tree); + free(header_tree); +} + +int read_line(char **buff, char **buff_lim) { int diff = 0; - if ((*buffer) >= (*buffer_limit)) { + if ((*buff) >= (*buff_lim)) { return diff; } int ret = 0; - char *match = strstr(*buffer, "\r\n"); + char *match = strstr(*buff, "\r\n"); if (match) { - ret = match-(*buffer); - *buffer += 2; + ret = match-(*buff); + *buff += 2; } else { - ret = (*buffer_limit)-(*buffer); + ret = (*buff_lim)-(*buff); } - *buffer += ret; + *buff += ret; return ret; } -int parse_header(char *offset, int len) { +int parshfield(char *offset, int len, struct point *hentries) { int key = 0; int ret = 0; int diff = 0; @@ -78,13 +123,13 @@ _loop: // header value diff = cursor_lim-cursor; - header_table[key].er = cursor; - header_table[key].len = diff; + hentries[key].er = cursor; + hentries[key].len = diff; return 0; } -int parse_title(char *offset, int len) { +int parstitle(char *offset, int len, struct httitle *titl) { int ret = 0; int diff = 0; char *cursor = offset; @@ -105,7 +150,7 @@ int parse_title(char *offset, int len) { return -1; } - method = ret; + titl->method = ret; cursor += diff; // white space @@ -128,8 +173,8 @@ _loop1: } diff = uri_lim-cursor; - uri = cursor; - uri_len = diff; + titl->uri.er = cursor; + titl->uri.len = diff; cursor += diff; @@ -145,28 +190,28 @@ _loop2: // ver diff = cursor_lim-cursor; - ver = cursor; - ver_len = diff; + titl->ver.er = cursor; + titl->ver.len = diff; cursor += diff; return 0; } -int parse_request(char *buffer) { +int parsme(char *buff, struct httpars *pars) { int ret; - char *buffer_limit = buffer+strlen(buffer); + char *buff_lim = buff+strlen(buff); - char *title_offset = buffer; - int title_len = read_line(&buffer, &buffer_limit); - if ((ret = parse_title(title_offset, title_len)) < 0) { + char *title_offset = buff; + int title_len = read_line(&buff, &buff_lim); + if ((ret = parstitle(title_offset, title_len, &pars->titl)) < 0) { fprintf(stderr, "Failed parsing title\n"); return -1; } for (int bound = 0; bound < MAX_BOUND; bound++) { - char *header_offset = buffer; - int header_len = read_line(&buffer, &buffer_limit); + char *header_offset = buff; + int header_len = read_line(&buff, &buff_lim); char *header_limit = header_offset+header_len; // IF END OF MESSAGE @@ -174,7 +219,9 @@ int parse_request(char *buffer) { break; } - if ((ret = parse_header(header_offset, header_len)) < 0) { + if ((ret = parshfield(header_offset, + header_len, + pars->hentries)) < 0) { fprintf(stderr, "Failed parsing header\n"); return -1; } @@ -183,72 +230,3 @@ int parse_request(char *buffer) { return 0; } -void debug_stats(void) { - fprintf(stderr, "\tstats:\n" - "\t\tmethod\t: %d\n" - "\t\turi\t: %.*s\n" - "\t\tver\t: %.*s\n", - method, uri_len, uri, ver_len, ver - ); - - fprintf(stdout, "\theaders:\n"); - for (int i = 0; i < header_count; i++) { - struct point *pnt = &header_table[i]; - if (!pnt->er) { - continue; - } - - fprintf(stdout, "\t\t%d\t: %.*s\n", i, pnt->len, pnt->er); - } -} - -int main(void) { - int ret; - char *str = strdup(TEST_ONE); - - header_table = (struct point *) calloc(header_count, sizeof(struct point)); - if (!header_table) { - fprintf(stderr, "Not enough dynamic memory\n"); - return -1; - } - - header_tree = allocnod(); - if (!header_tree) { - fprintf(stderr, "Not enough dynamic memory\n"); - return -1; - } - - method_tree = allocnod(); - if (!method_tree) { - fprintf(stderr, "Not enough dynamic memory\n"); - return -1; - } - - ret = gentree(header_tree, headers, NULL); - 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; - } - - ret = parse_request(str); - if (ret < 0) { - fprintf(stderr, "Failed parsing request\n"); - return -1; - } - - fprintf(stdout, "++Successfully parsed data++\n"); - debug_stats(); - - frenod(method_tree); - frenod(header_tree); - free(header_table); - free(str); - - return 0; -} diff --git a/tinyparser.h b/tinyparser.h index e8d157d..09e419a 100644 --- a/tinyparser.h +++ b/tinyparser.h @@ -11,8 +11,6 @@ "\r\n"\ "{\"key\": \"kefjoiawejfojgorgjbosejrgo\"}"\ -// ENUMS - // SRC:https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods enum methods { method_get = 1, @@ -145,4 +143,22 @@ struct point { int len; }; +struct httitle { + int method; + struct point uri; + struct point ver; +}; + +struct httpars { + struct httitle titl; + struct point hentries[header_count]; +}; + +int initres(void); +void fretres(void); +int readlin(char **buff, char **buff_lim); +int parshfield(char *offset, int len, /* out */ struct point *hentries); +int parstitle(char *offset, int len, /* out */ struct httitle *titl); +int parsme(char *buff, /* out */ struct httpars *pars); + #endif