fix: heap overflow when memcpy() in scf_vector.h, it is a common memory BUG of C... master
authoryu.dongliang <18588496441@163.com>
Tue, 23 Jun 2026 07:44:21 +0000 (15:44 +0800)
committeryu.dongliang <18588496441@163.com>
Tue, 23 Jun 2026 07:44:21 +0000 (15:44 +0800)
parse/scf_dfa_class.c
util/scf_vector.h

index 105203711f17e92e500b1e56ff30403403e9ce3b..a3764d2be4aff49a8c1f0d4a09358aa3ff7f485a 100644 (file)
@@ -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)
 {
 
 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];
        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;
                        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);
                }
 
                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;
 
                if (!t)
                        return SCF_DFA_ERROR;
 
+               ast->nb_structs++;
+
                t->node.anon_flag = 1;
        }
 
                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);
                t->scope = scf_scope_alloc();
 
        scf_scope_push_type(ast->current_block->scope, t);
-       ast->nb_structs++;
 
        switch (key->type)
        {
 
        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);
 
                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;
 
                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;
 
                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];
 
                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;
                }
 
                        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;
                        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];
 
                        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;
 
                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 (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;
 
        }
        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;
 }
 
        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) {
        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_stack_pop(s);
                free(cd);
-
-               scf_logi("ok\n");
                return SCF_DFA_OK;
        }
 
                return SCF_DFA_OK;
        }
 
index 95592f0acf31e85b37ec0dc26c591110a1d7f37e..78f1de445644ee17b075cac07a37f8125c12c94f 100644 (file)
@@ -48,6 +48,25 @@ static inline scf_vector_t* scf_vector_clone(scf_vector_t* src)
        return dst;
 }
 
        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)
 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;
        }
 
                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;
 }
        dst->size += src->size;
        return 0;
 }
@@ -209,4 +232,3 @@ static inline void scf_vector_free(scf_vector_t* v)
 }
 
 #endif
 }
 
 #endif
-