diff options
author | Gavin Howard <gavin@yzena.com> | 2021-07-26 13:34:19 -0600 |
---|---|---|
committer | Gavin Howard <gavin@yzena.com> | 2021-07-26 13:34:19 -0600 |
commit | 769e980b03f247d7c6ceadaa2eb9048cc9e91653 (patch) | |
tree | c7e4eb613c06a5ebe78f749defeeb6f4f2472500 /src | |
parent | e81b1f4389f3d7276741180cda02b8cf0aa99a04 (diff) | |
download | platform_external_bc-769e980b03f247d7c6ceadaa2eb9048cc9e91653.tar.gz platform_external_bc-769e980b03f247d7c6ceadaa2eb9048cc9e91653.tar.bz2 platform_external_bc-769e980b03f247d7c6ceadaa2eb9048cc9e91653.zip |
Fix a crash found by AFL++
After so many crashes in bc_slabvec_undo(), I decided to rip it out,
especially since it it only used in one place.
Signed-off-by: Gavin Howard <gavin@yzena.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/bc_parse.c | 4 | ||||
-rw-r--r-- | src/parse.c | 2 | ||||
-rw-r--r-- | src/vector.c | 80 |
3 files changed, 24 insertions, 62 deletions
diff --git a/src/bc_parse.c b/src/bc_parse.c index 5d9359af..a2bd7324 100644 --- a/src/bc_parse.c +++ b/src/bc_parse.c @@ -364,7 +364,7 @@ static void bc_parse_name(BcParse *p, BcInst *type, // We want a copy of the name since the lexer might overwrite its copy. len = p->l.str.len; - name = bc_slabvec_strdup(&p->slab, p->l.str.v); + name = bc_vm_strdup(p->l.str.v); BC_SETJMP_LOCKED(err); @@ -434,7 +434,7 @@ static void bc_parse_name(BcParse *p, BcInst *type, err: // Need to make sure to unallocate the name. BC_SIG_MAYLOCK; - bc_slabvec_undo(&p->slab, len); + free(name); BC_LONGJMP_CONT; } diff --git a/src/parse.c b/src/parse.c index 229c2e59..ea4c25e8 100644 --- a/src/parse.c +++ b/src/parse.c @@ -210,7 +210,6 @@ void bc_parse_free(BcParse *p) { bc_vec_free(&p->conds); bc_vec_free(&p->ops); bc_vec_free(&p->buf); - bc_slabvec_free(&p->slab); } #endif // BC_ENABLED @@ -240,7 +239,6 @@ void bc_parse_init(BcParse *p, BcProgram *prog, size_t func) { bc_vec_init(&p->ops, sizeof(BcLexType), BC_DTOR_NONE); bc_vec_init(&p->buf, sizeof(char), BC_DTOR_NONE); - bc_slabvec_init(&p->slab); p->auto_part = false; } #endif // BC_ENABLED diff --git a/src/vector.c b/src/vector.c index 3405354f..7b695d5e 100644 --- a/src/vector.c +++ b/src/vector.c @@ -509,11 +509,7 @@ char* bc_slabvec_strdup(BcVec *v, const char *str) { slab.s = bc_vm_strdup(str); // Push the standalone slab. - bc_vec_push(v, &slab); - - // Create a new real slab. - slab_ptr = bc_vec_pushEmpty(v); - bc_slab_init(slab_ptr); + bc_vec_pushAt(v, &slab, v->len - 1); return slab.s; } @@ -536,59 +532,6 @@ char* bc_slabvec_strdup(BcVec *v, const char *str) { return s; } -#if BC_ENABLED - -void bc_slabvec_undo(BcVec *v, size_t len) { - - BcSlab *s; - - assert(v != NULL && v->len); - - s = bc_vec_top(v); - - // If this is true, there are no allocations in this slab, so we need to - // discard it. Well, maybe... - if (s->len == 0) { - - // The reason this is true is because while undo can *empty* a slab - // vector, it should *never* go beyond that. If it does, then the - // calling code screwed up. - assert(v->len > 1); - - // Get the second to last slab. - s = bc_vec_item_rev(v, 1); - - // If it is a lone allocation, destroy it instead of the last (empty) - // slab. - if (s->len == SIZE_MAX) { - bc_vec_npopAt(v, 1, v->len - 2); - return; - } - - // If we reach this point, we know the second-to-last slab is a valid - // slab, so we can discard the last slab. - bc_vec_pop(v); - - // Get the new top of the stack. - s = bc_vec_top(v); - - // If this is true, then some standalone slab was allocated after this - // slab when it had nothing in it. We already popped a slab, so we want - // to leave this one alone. To do that, we return early. - if (!s->len) return; - } - - assert(s->len >= len); - - // Remove the string. The reason we can do this even with the if statement - // is that s was updated to the second-to-last slab (now last slab). - s->len -= len; - - assert(s->len == 0 || !s->s[s->len - 1]); -} - -#endif // BC_ENABLED - void bc_slabvec_clear(BcVec *v) { BcSlab *s; @@ -621,3 +564,24 @@ void bc_slabvec_clear(BcVec *v) { s->len = 0; } #endif // !BC_ENABLE_LIBRARY + +#if BC_DEBUG_CODE + +void bc_slabvec_print(BcVec *v, const char *func) { + + size_t i; + BcSlab *s; + + bc_file_printf(&vm.ferr, "%s\n", func); + + for (i = 0; i < v->len; ++i) { + s = bc_vec_item(v, i); + bc_file_printf(&vm.ferr, "%zu { s = %zu, len = %zu }\n", + i, (uintptr_t) s->s, s->len); + } + + bc_file_puts(&vm.ferr, bc_flush_none, "\n"); + bc_file_flush(&vm.ferr, bc_flush_none); +} + +#endif // BC_DEBUG_CODE |