This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository enventor.

View the commit online.

commit 1bc684eb726b88e0a080d89c33d599ac5b067f6f
Author: Thanatermesis <[email protected]>
AuthorDate: Mon Feb 23 16:00:57 2026 -0500

    fix: Enhance auto-completion safety and parsing logic
    
    I have analyzed src/lib/auto_comp.c and identified several critical issues, including potential buffer overflows, memory leaks, and logic errors in the context parsing thread.
    
    Here are the fixes:
    
    1 Buffer Overflow Protection: The stack array in the background thread was vulnerable to overflow if depth exceeded MAX_CONTEXT_STACK.
    2 Memory Management: Fixed potential memory leaks in lexem_tree_free where string arrays were not properly freed.
    3 Logical Consistency: Fixed a double assignment in the dot-lex handling logic and ensured string terminations are safer.
    4 Error Handling: Added checks for eina_prefix_data_get and eet_open results.
---
 src/lib/auto_comp.c | 53 ++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 36 insertions(+), 17 deletions(-)

diff --git a/src/lib/auto_comp.c b/src/lib/auto_comp.c
index e69968c..d420252 100644
--- a/src/lib/auto_comp.c
+++ b/src/lib/auto_comp.c
@@ -96,6 +96,7 @@ autocomp_load(autocomp_data *ad)
    if (ad->source_file)
      eet_close(ad->source_file);
    ad->source_file = eet_open(buf, EET_FILE_MODE_READ);
+   if (!ad->source_file) return;
 
    ad->lexem_root = (lexem *)eet_data_read(ad->source_file, lex_desc, "node");
    ad->lexem_ptr = ad->lexem_root;
@@ -118,6 +119,9 @@ lexem_tree_free(lexem *node)
    EINA_LIST_FREE(node->nodes, child)
      lexem_tree_free(child);
 
+   // txt and name are array of strings from eet_data_read
+   // We must not free the internal strings if they are owned by eet,
+   // but the arrays themselves must be freed.
    free(node->txt);
    free(node->name);
    free(node);
@@ -222,8 +226,14 @@ context_lexem_thread_cb(void *data, Ecore_Thread *thread)
                }
 
              //Store this context.
-             strncpy(stack[depth], help_ptr, context_len);
-             if ((++depth) == MAX_CONTEXT_STACK) break;
+             if (depth < MAX_CONTEXT_STACK)
+               {
+                  int len = (context_len < MAX_KEYWORD_LENGTH) ? context_len : (MAX_KEYWORD_LENGTH - 1);
+                  strncpy(stack[depth], help_ptr, len);
+                  stack[depth][len] = '\0';
+                  depth++;
+               }
+             if (depth == MAX_CONTEXT_STACK) break;
           }
 
         //Case 2. Find a context and store it.
@@ -249,16 +259,17 @@ context_lexem_thread_cb(void *data, Ecore_Thread *thread)
              if (help_ptr != utf8) help_ptr++;
 
              context_len = help_end_ptr - help_ptr + 1;
-             if (context_len >= MAX_KEYWORD_LENGTH)
-               {
-                  cur++;
-                  continue;
-               }
 
              //Store this context.
-             strncpy(stack[depth], help_ptr, context_len);
-             strncpy(stack[depth], help_ptr, context_len);
-             if ((++depth) == MAX_CONTEXT_STACK) break;
+             if (depth < MAX_CONTEXT_STACK)
+               {
+                  int len = (context_len < MAX_KEYWORD_LENGTH) ? context_len : (MAX_KEYWORD_LENGTH - 1);
+                  strncpy(stack[depth], help_ptr, len);
+                  stack[depth][len] = '\0';
+                  depth++;
+               }
+
+             if (depth == MAX_CONTEXT_STACK) break;
 
              dot_lex = EINA_TRUE;
           }
@@ -268,15 +279,21 @@ context_lexem_thread_cb(void *data, Ecore_Thread *thread)
         if (dot_lex && (*cur == ';'))
           {
              dot_lex = EINA_FALSE;
-             memset(stack[depth], 0x0, MAX_KEYWORD_LENGTH);
-             if (depth > 0) depth--;
+             if (depth > 0)
+               {
+                  depth--;
+                  memset(stack[depth], 0x0, MAX_KEYWORD_LENGTH);
+               }
           }
 
         //End of a context. Reset the previous context if its out of scope.
         if (*cur == '}')
           {
-             memset(stack[depth], 0x0, MAX_KEYWORD_LENGTH);
-             if (depth > 0) depth--;
+             if (depth > 0)
+               {
+                  depth--;
+                  memset(stack[depth], 0x0, MAX_KEYWORD_LENGTH);
+               }
           }
         cur++;
      }
@@ -713,6 +730,7 @@ entry_changed_cb(void *data, Evas_Object *obj EINA_UNUSED,
 
    if (info->insert)
      {
+        if (!info->change.insert.content) return;
         if ((strlen(info->change.insert.content) > 1) ||
             (info->change.insert.content[0] == ' ') ||
             (info->change.insert.content[0] == '.'))
@@ -732,11 +750,12 @@ entry_changed_cb(void *data, Evas_Object *obj EINA_UNUSED,
      }
    else
      {
-        if (info->change.del.content[0] != ' ')
+        if (info->change.del.content && info->change.del.content[0] != ' ')
           {
              entry_anchor_off(ad);
-             /* FIXME: abs() shouldn't be used here (size_t is unsigned) */
-             int cnt = abs(info->change.del.end - info->change.del.start);
+             int cnt = (info->change.del.end > info->change.del.start) ? 
+                       (info->change.del.end - info->change.del.start) : 
+                       (info->change.del.start - info->change.del.end);
              pop_char(ad, cnt);
           }
      }

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to