aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGavin Howard <gavin@yzena.com>2021-07-26 13:34:19 -0600
committerGavin Howard <gavin@yzena.com>2021-07-26 13:34:19 -0600
commit769e980b03f247d7c6ceadaa2eb9048cc9e91653 (patch)
treec7e4eb613c06a5ebe78f749defeeb6f4f2472500 /src
parente81b1f4389f3d7276741180cda02b8cf0aa99a04 (diff)
downloadplatform_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.c4
-rw-r--r--src/parse.c2
-rw-r--r--src/vector.c80
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