From: yu.dongliang <18588496441@163.com> Date: Tue, 23 Jun 2026 07:44:21 +0000 (+0800) Subject: fix: heap overflow when memcpy() in scf_vector.h, it is a common memory BUG of C... X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=132a092cfe81f3df00eab7827d087265d716b2ca;p=scf.git fix: heap overflow when memcpy() in scf_vector.h, it is a common memory BUG of C language. --- diff --git a/parse/scf_dfa_class.c b/parse/scf_dfa_class.c index 1052037..a3764d2 100644 --- a/parse/scf_dfa_class.c +++ b/parse/scf_dfa_class.c @@ -23,6 +23,8 @@ static int _class_is_class(scf_dfa_t* dfa, void* word) static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data) { + assert(words->size >= 2); + scf_parse_t* parse = dfa->priv; scf_ast_t* ast = parse->ast; scf_lex_word_t* w = words->data[words->size - 1]; @@ -38,6 +40,8 @@ static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data) t = scf_type_alloc(key, key->text->data, SCF_STRUCT + ast->nb_structs, 0); if (!t) return SCF_DFA_ERROR; + + ast->nb_structs++; } assert(words->size >= 3); @@ -52,6 +56,8 @@ static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data) if (!t) return SCF_DFA_ERROR; + ast->nb_structs++; + t->node.anon_flag = 1; } @@ -59,7 +65,6 @@ static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data) t->scope = scf_scope_alloc(); scf_scope_push_type(ast->current_block->scope, t); - ast->nb_structs++; switch (key->type) { @@ -118,15 +123,19 @@ static int _class_flat_anon_var(scf_type_t* s) t = scf_scope_find_type_type(s->scope, v->type); assert(t); + if (t->scope->vars->size <= 0) { + assert(0 == scf_vector_del(s->scope->vars, v)); + scf_variable_free(v); + v = NULL; + continue; + } + int offset = v->offset; - assert(0 == scf_vector_del(s->scope->vars, v)); + s->scope->vars->data[i] = NULL; scf_variable_free(v); v = NULL; - if (t->scope->vars->size <= 0) - continue; - for (j = 0; j < t->scope->vars->size; j++) { v2 = t->scope->vars->data[j]; @@ -135,24 +144,21 @@ static int _class_flat_anon_var(scf_type_t* s) v2->offset += offset; } - int n = s->scope->vars->size; + // 'position i' is empty, so extends one less than. + int exts = t->scope->vars->size - 1; + int olds = s->scope->vars->size; - int ret = scf_vector_cat(s->scope->vars, t->scope->vars); - if (ret < 0) { - scf_loge("\n"); + int ret = scf_vector_extend(s->scope->vars, exts); + if (ret < 0) return ret; - } - for (j = n - 1; j >= i; j--) - s->scope->vars->data[j + t->scope->vars->size] = s->scope->vars->data[j]; + for (j = olds - 1; j > i; j--) + s->scope->vars->data[j + exts] = s->scope->vars->data[j]; - for (j = 0; j < t->scope->vars->size; j++) + for (j = 0; j < exts + 1; j++) s->scope->vars->data[i + j] = t->scope->vars->data[j]; - scf_loge("i: %d, s->size: %d, t->size: %d\n", i, s->scope->vars->size, t->scope->vars->size); - - n = t->scope->vars->size; - i += n; + i += exts + 1; scf_vector_free(t->scope->vars); t->scope->vars = NULL; @@ -301,19 +307,12 @@ static int _union_calculate_size(scf_dfa_t* dfa, scf_type_t* s) if (max_size < size) max_size = size; - if (s->node.class_flag) - scf_logi("class '%s', member: '%s', size: %d, v->dim: %d, v->capacity: %d\n", - s->name->data, v->w->text->data, v->size, v->nb_dimentions, v->capacity); - else - scf_logi("union '%s', member: '%s', size: %d, v->dim: %d, v->capacity: %d\n", - s->name->data, v->w->text->data, v->size, v->nb_dimentions, v->capacity); + scf_logi("union '%s', member: '%s', size: %d, v->dim: %d, v->capacity: %d\n", + s->name->data, v->w->text->data, v->size, v->nb_dimentions, v->capacity); } s->size = max_size; - if (s->node.class_flag) - scf_logi("class '%s', size: %d\n", s->name->data, s->size); - else - scf_logi("union '%s', size: %d\n", s->name->data, s->size); + scf_logi("union '%s', size: %d\n", s->name->data, s->size); return 0; } @@ -430,11 +429,10 @@ static int _class_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data) dfa_class_data_t* cd = scf_stack_top(s); if (cd->nb_rbs == cd->nb_lbs) { + scf_logi("ok\n"); scf_stack_pop(s); free(cd); - - scf_logi("ok\n"); return SCF_DFA_OK; } diff --git a/util/scf_vector.h b/util/scf_vector.h index 95592f0..78f1de4 100644 --- a/util/scf_vector.h +++ b/util/scf_vector.h @@ -48,6 +48,25 @@ static inline scf_vector_t* scf_vector_clone(scf_vector_t* src) return dst; } +static inline int scf_vector_extend(scf_vector_t* v, int size) +{ + if (!v || size <= 0) + return -EINVAL; + + size += v->size; + + if (size > v->capacity) { + void* p = realloc(v->data, sizeof(void*) * size); + if (!p) + return -ENOMEM; + + v->data = p; + v->capacity = size; + } + + return 0; +} + static inline int scf_vector_cat(scf_vector_t* dst, scf_vector_t* src) { if (!dst || !src) @@ -64,7 +83,11 @@ static inline int scf_vector_cat(scf_vector_t* dst, scf_vector_t* src) dst->capacity = size + NB_MEMBER_INC; } - memcpy(dst->data + dst->size * sizeof(void*), src->data, src->size * sizeof(void*)); + // dst->data + dst->size == &(dst->data[dst->size]). + + // dst->data is 'void**', do NOT mul sizeof(void*)!! + // src->size is 'int', needs to mul sizeof(void*). + memcpy(dst->data + dst->size, src->data, src->size * sizeof(void*)); dst->size += src->size; return 0; } @@ -209,4 +232,3 @@ static inline void scf_vector_free(scf_vector_t* v) } #endif -