diff options
| author | Louis Burda <quent.burda@gmail.com> | 2021-05-10 15:05:25 +0200 |
|---|---|---|
| committer | Louis Burda <quent.burda@gmail.com> | 2021-05-10 15:05:25 +0200 |
| commit | 2a8416eaa85af6348fe34859859a7fb39db2003d (patch) | |
| tree | aa05283f66bf509d75352dbddc8380ab56a27a46 /service/src/stlfile.c | |
| parent | 65a1a51121278e54e40e2a04ae096053d5a3c47d (diff) | |
| download | enowars5-service-stldoctor-2a8416eaa85af6348fe34859859a7fb39db2003d.tar.gz enowars5-service-stldoctor-2a8416eaa85af6348fe34859859a7fb39db2003d.zip | |
save scan info and model, added vuln in load info, small tweaks
create result directory with serialized info struct and model file after successful scan, dont modify the stl file contents during parsing, EOF getc vuln to truncate loaded hash added in load_info
Diffstat (limited to 'service/src/stlfile.c')
| -rw-r--r-- | service/src/stlfile.c | 108 |
1 files changed, 78 insertions, 30 deletions
diff --git a/service/src/stlfile.c b/service/src/stlfile.c index 6a59dd1..4f6d0e1 100644 --- a/service/src/stlfile.c +++ b/service/src/stlfile.c @@ -68,16 +68,16 @@ skip_set(char *p, const char *set) } char* -consume_arg(char **start) +consume_arg(char **start, char **end) { char *p, *tmp; p = skip_set(*start, wsset); for (; !strchr(wsset, *p); p++); if (!*p) return NULL; - *p = '\0'; tmp = *start; *start = p + 1; + *end = p; return tmp; } @@ -107,7 +107,7 @@ consume_keyword(char **start) int parse_file_ascii(struct parseinfo *info, char *buf, size_t len) { - char *bp, *arg, *prev, *tmp; + char *bp, *arg, *prev, *tmp, *end; struct stack states; float farg; int i, kw; @@ -117,6 +117,8 @@ parse_file_ascii(struct parseinfo *info, char *buf, size_t len) info->type = TYPE_ASCII; info->loopcount = 0; + memset(info->header, 0, 80); + for (i = 0; i < 3; i++) { info->bbmin[i] = INFINITY; info->bbmax[i] = -INFINITY; @@ -130,8 +132,8 @@ parse_file_ascii(struct parseinfo *info, char *buf, size_t len) if (stack_ind(&states, KW_SOLID_BEGIN) != -1) PARSE_FAIL("Multiple nested solids!\n"); tmp = bp; - if (!consume_keyword(&bp) && (arg = consume_arg(&bp))) { - strncpy(info->extra, arg, sizeof(info->extra)); + if (!consume_keyword(&bp) && (arg = consume_arg(&bp, &end))) { + info->modelname = strndup(arg, end - arg); } else { bp = tmp; } @@ -140,9 +142,9 @@ parse_file_ascii(struct parseinfo *info, char *buf, size_t len) if ((kw = stack_pop(&states)) != STATE_SOLID) PARSE_FAIL("Improper nesting, parent: %s\n", kwmap[kw].str); tmp = bp; - if (*info->extra && !consume_keyword(&bp) - && (arg = consume_arg(&bp))) { - if (strncmp(info->extra, arg, sizeof(info->extra))) + if (info->modelname && !consume_keyword(&bp) + && (arg = consume_arg(&bp, &end))) { + if (strncmp(info->modelname, arg, end - arg)) PARSE_FAIL("Solid end/begin names do not match!\n"); } else { bp = tmp; @@ -163,10 +165,10 @@ parse_file_ascii(struct parseinfo *info, char *buf, size_t len) if (stack_ind(&states, KW_LOOP_BEGIN) != -1) PARSE_FAIL("Multiple nested facets!\n"); for (i = 0; i < 3; i++) { - if (!(arg = consume_arg(&bp))) + if (!(arg = consume_arg(&bp, &end))) PARSE_FAIL("Facet with less than 3 args!\n"); farg = strtof(arg, &tmp); - if (*tmp) + if (!strchr(wsset, *tmp)) PARSE_FAIL("Facet with invalid arg '%s'!\n", arg); } break; @@ -176,10 +178,10 @@ parse_file_ascii(struct parseinfo *info, char *buf, size_t len) break; case KW_VERTEX: for (i = 0; i < 3; i++) { - if (!(arg = consume_arg(&bp))) + if (!(arg = consume_arg(&bp, &end))) PARSE_FAIL("Vertex with less than 3 args!\n"); farg = strtof(arg, &tmp); - if (*tmp) + if (!strchr(wsset, *tmp)) PARSE_FAIL("Vertex with invalid arg '%s'!\n", arg); info->bbmin[i] = MIN(info->bbmin[i], farg); info->bbmax[i] = MAX(info->bbmax[i], farg); @@ -215,7 +217,7 @@ parse_file_bin(struct parseinfo *info, char *buf, size_t len) if (len < 84) PARSE_FAIL("Truncated data! (header missing)\n"); - memcpy(info->extra, buf, 80); + memcpy(info->header, buf, 80); bp = buf + 80; info->loopcount = le32toh(*(uint32_t*)bp); @@ -249,33 +251,79 @@ int parse_file(struct parseinfo *info, char *buf, size_t len) { int status; + const char *tmp; char *bp; if (info->valid) free_info(info); - /* check bin vs ascii */ for (bp = buf; strchr(wsset, *bp); bp++); + /* check bin vs ascii with first keyword */ status = !strncmp("solid ", bp, 6) ? parse_file_ascii(info, buf, len) : parse_file_bin(info, buf, len); if (status == FAIL) return FAIL; - /* create model hash */ - strncpy(info->hash, mhash(info->extra, sizeof(info->extra)), MHASHLEN); + if (!info->modelname) { + tmp = ask("Please enter your model name:\n"); + if (strlen(tmp) < 4) { + fprintf(stderr, "Model name is too short!\n"); + return FAIL; + } + info->modelname = checkp(strdup(tmp)); + } + + info->hash = checkp(strdup(mhash(info->modelname, -1))); return OK; } int -save_info(struct parseinfo *info, const char *resultdir) +save_info(struct parseinfo *info, FILE *f) { - /* <HASH>: - * - info : binary file info - * - model : original stl file - */ + size_t nwrote = 0; + int i; - return FAIL; + nwrote += fwrite(&info->type, sizeof(int), 1, f); + nwrote += fwrite(&info->loopcount, sizeof(int), 1, f); + + for (i = 0; i < 3; i++) { + nwrote += fwrite(&info->bbmin[i], sizeof(float), 1, f); + nwrote += fwrite(&info->bbmax[i], sizeof(float), 1, f); + } + + nwrote += fwrite(info->header, 80, 1, f); + + if (nwrote != 9) return FAIL; + + fputstr(f, info->modelname); + fputstr(f, info->hash); + + return OK; +} + +int +load_info(struct parseinfo *info, FILE *f) +{ + size_t nread = 0; + int i; + + nread += fread(&info->type, sizeof(int), 1, f); + nread += fread(&info->loopcount, sizeof(int), 1, f); + + for (i = 0; i < 3; i++) { + nread += fwrite(&info->bbmin[i], sizeof(float), 1, f); + nread += fwrite(&info->bbmax[i], sizeof(float), 1, f); + } + + nread += fread(info->header, 80, 1, f); + + if (nread != 9) return FAIL; + + freadstr(f, &info->modelname); + freadstr(f, &info->hash); + + return OK; } void @@ -285,16 +333,16 @@ print_info(struct parseinfo *info) #define FILTERCHAR(c) ((c) >= 32 ? (c) : ' ') - if (info->type == TYPE_ASCII) { - printf("Modelname: %s\n", info->extra); - } else { - printf("Model Header:\n"); + printf("Name: %s\n", info->modelname); + + if (info->type == TYPE_BIN) { + printf("Header:\n"); for (i = 0; i < 80; i += k) { for (k = 0; k < MIN(80 - i, 20); k++) - printf(" %02x", (uint8_t) info->extra[i+k]); + printf(" %02x", (uint8_t) info->header[i+k]); printf(" | "); for (k = 0; k < MIN(80 - i, 20); k++) - printf("%c", FILTERCHAR(info->extra[i+k])); + printf("%c", FILTERCHAR(info->header[i+k])); printf("\n"); } } @@ -310,7 +358,7 @@ print_info(struct parseinfo *info) void free_info(struct parseinfo *info) { - NULLFREE(info->stlpath); - NULLFREE(info->infopath); + NULLFREE(info->hash); + NULLFREE(info->modelname); info->valid = 0; } |
