Hello everyone,

since checking the code for possible holes appears to the theme of the month...

I had a go with clang's analyzer (on Cygwin) on current SVN source (r7649). It found about a dozen possible uninitalized reads, use-after-frees and null pointer dereferences, primarily in 'info':

(Reported "dead stores" snipped here)
Logic error     
Branch condition evaluates to a garbage value           2       
Called function pointer is null (null dereference)      1       
Dereference of null pointer                             6       
Result of operation is garbage or undefined             1       
Unix API (<-- NULL passed to string functions)               2       

Memory Error    
Memory leak                                             1       
Use-after-free                                          2       

(Reports list attached separately because lines are too long).

The full report is a bit big for sending via the list (1 MB zipped), so I've attached a preliminary set of patches for many of the above instead. With those patches applied, I got down to:

Logic error     
Dereference of null pointer     2       
Unix API                        1       

Memory Error    
Use-after-free                  1       
Index: display.c
===================================================================
--- display.c   (Revision 7649)
+++ display.c   (Arbeitskopie)
@@ -713,7 +713,7 @@
 
       /* If this line has text on it, or if we don't know what is on the line,
          clear this line. */
-      if (entry && entry->textlen || entry->inverse)
+      if (entry && (entry->textlen || entry->inverse))
         {
           entry->textlen = 0;
           entry->text[0] = '\0';
Index: echo-area.c
===================================================================
--- echo-area.c (Revision 7649)
+++ echo-area.c (Arbeitskopie)
@@ -125,11 +125,16 @@
 initialize_input_line (const char *prompt)
 {
   if (prompt)
-    strcpy (input_line, prompt);
+    {
+      strcpy (input_line, prompt);
+      input_line_point = strlen (prompt);
+    } 
   else
-    input_line[0] = '\0';
-
-  input_line_beg = input_line_end = input_line_point = strlen (prompt);
+    {
+      input_line[0] = '\0';
+      input_line_point = 0;
+    }
+  input_line_beg = input_line_end = input_line_point;
 }
 
 static char *
Index: indices.c
===================================================================
--- indices.c   (Revision 7649)
+++ indices.c   (Arbeitskopie)
@@ -829,7 +829,7 @@
   index_partial = 0;
   while (1)
     {
-      REFERENCE *result;
+      REFERENCE *result = 0;
       int match_offset;
 
       next_index_match (file_buffer, index_search, index_offset, 1, &result, 
Index: info.c
===================================================================
--- info.c      (Revision 7649)
+++ info.c      (Arbeitskopie)
@@ -432,7 +432,7 @@
 
   if (goto_invocation_p)
     {
-      NODE *top_node;
+      NODE *top_node = 0;
       REFERENCE *invoc_ref = 0;
 
       char *program;
Index: infodoc.c
===================================================================
--- infodoc.c   (Revision 7649)
+++ infodoc.c   (Arbeitskopie)
@@ -372,7 +372,7 @@
   /* If there is more than one window on the screen, check if the user typed 
      "H" for help message before typing "h" for tutorial.  If so, close help 
      message so the tutorial will not be in a small window. */
-  if (windows->next)
+  if (windows && windows->next)
     {
       WINDOW *help_window = get_internal_info_window (info_help_nodename);
       if (help_window && help_window == active_window)
@@ -661,7 +661,7 @@
   free (result);
   result = xmalloc (1 + reslen);
 
-  i = next = start = 0;
+  next = start = 0;
 
   /* Skip to the beginning of a replaceable function. */
   for (i = start; string[i]; i++)
Index: m-x.c
===================================================================
--- m-x.c       (Revision 7649)
+++ m-x.c       (Arbeitskopie)
@@ -138,15 +138,20 @@
       }
 
     command = named_function (line);
-    free (line);
 
     if (!command)
-      return;
+      {
+        free (line);
+        return;
+      }
 
     if (command->func)
       (*command->func) (active_window, count, 0);
     else
-      info_error (_("Undefined command: %s"), line);
+      {
+        info_error (_("Undefined command: %s"), line);
+      }
+    free (line);
   }
 }
 
Index: search.c
===================================================================
--- search.c    (Revision 7649)
+++ search.c    (Arbeitskopie)
@@ -518,21 +518,6 @@
   return i;
 }
 
-/* Return the number of characters from STRING to the start of
-   the next line. */
-int
-skip_line (char *string)
-{
-  register int i;
-
-  for (i = 0; string && string[i] && string[i] != '\n'; i++);
-
-  if (string[i] == '\n')
-    i++;
-
-  return i;
-}
-
 /* Return the absolute position of the beginning of a section in this file
    whose first line is LABEL, starting the search at binding->start. */
 long
Index: search.h
===================================================================
--- search.h    (Revision 7649)
+++ search.h    (Arbeitskopie)
@@ -78,7 +78,6 @@
 int skip_whitespace (char *string);
 int skip_non_whitespace (char *string);
 int skip_whitespace_and_newlines (char *string);
-int skip_line (char *string);
 int skip_node_separator (char *body);
 
 long find_node_separator (SEARCH_BINDING *binding);
Index: session.c
===================================================================
--- session.c   (Revision 7649)
+++ session.c   (Arbeitskopie)
@@ -3498,12 +3498,15 @@
         node2 = info_get_node (entry->filename, entry->nodename);
         free_history_node (node);
         if (!node2)
-          break;
+         {
+           node = NULL;
+           break;
+         }
         node = node2;
       }
     }
 
-  {
+  if (node) {
     char *n = node->nodename;
     node->nodename = 0;
     free_history_node (node);
@@ -4102,7 +4105,7 @@
   long start;
   enum search_result result;
   int search_other_nodes = 1;
-  int number_of_tags, starting_tag, current_tag = -1;
+  int number_of_tags = 0, starting_tag = -1, current_tag = -1;
   NODE *node = window->node; /* Node to search in. */
   char *subfile_name = 0;
   TAG *tag;
@@ -4990,7 +4993,7 @@
   else
     dir = 1;
 
-  last_search_result = search_result = search_success;
+  search_result = search_success;
 
   window_get_state (window, &orig_state);
 
Index: terminal.c
===================================================================
--- terminal.c  (Revision 7649)
+++ terminal.c  (Arbeitskopie)
@@ -454,7 +454,7 @@
 terminal_begin_blink (void)
 {
   if (terminal_begin_blink_hook)
-    (*terminal_begin_underline_hook) ();
+    (*terminal_begin_blink_hook) ();
   else
     {
       send_to_terminal (term_mb);
Index: tilde.c
===================================================================
--- tilde.c     (Revision 7649)
+++ tilde.c     (Arbeitskopie)
@@ -114,16 +114,13 @@
 char *
 tilde_expand (char *string)
 {
-  char *result;
-  int result_size, result_index;
+  char *result = NULL;
+  unsigned int result_size = 0, result_index = 0;
 
-  result_size = result_index = 0;
-  result = NULL;
-
   /* Scan through STRING expanding tildes as we come to them. */
   while (1)
     {
-      register int start, end;
+      unsigned int start, end;
       char *tilde_word, *expansion;
       int len;
 
@@ -132,7 +129,10 @@
 
       /* Copy the skipped text into the result. */
       if ((result_index + start + 1) > result_size)
-        result = xrealloc (result, 1 + (result_size += (start + 20)));
+        {
+          result_size += start + 20;
+          result = xrealloc (result, 1 + result_size);
+        }
 
       strncpy (result + result_index, string, start);
       result_index += start;
Index: window.c
===================================================================
--- window.c    (Revision 7649)
+++ window.c    (Arbeitskopie)
@@ -317,8 +317,10 @@
 #define grow_me_shrinking_next(me, next, diff) \
   do { \
     me->height += diff; \
-    next->height -= diff; \
-    next->first_row += diff; \
+    if (next) { \
+      next->height -= diff; \
+      next->first_row += diff; \
+    } \
   } while (0)
 
 #define grow_me_shrinking_prev(me, prev, diff) \
@@ -331,8 +333,10 @@
 #define shrink_me_growing_next(me, next, diff) \
   do { \
     me->height -= diff; \
-    next->height += diff; \
-    next->first_row -= diff; \
+    if (next) { \
+      next->height += diff; \
+      next->first_row -= diff; \
+    } \
   } while (0)
 
 #define shrink_me_growing_prev(me, prev, diff) \
Bug Group       Bug Type                                                File ▾  
                                Function/Method                 Line    Path 
Length     
Logic error     Dereference of null pointer                             
info/display.c                          display_update_one_window       716     
11
Logic error     Unix API                                                
info/echo-area.c                        initialize_input_line           132     
7
Logic error     Branch condition evaluates to a garbage value           
info/indices.c                          create_virtual_index            837     
20
Logic error     Branch condition evaluates to a garbage value           
info/info.c                             add_initial_nodes               460     
12
Logic error     Dereference of null pointer                             
info/infodoc.c                          info_get_info_help_node         375     
3
Memory Error    Use-after-free                                          
info/m-x.c                              info_execute_command            149     
11
Logic error     Dereference of null pointer                             
info/search.c                           skip_line                       530     
2
Logic error     Dereference of null pointer                             
info/session.c                          read_key_sequence               5706    
44
Logic error     Result of operation is garbage or undefined             
info/session.c                          info_search_internal            4132    
6
Memory Error    Use-after-free                                          
info/session.c                          info_intuit_options_node        3507    
23
Logic error     Called function pointer is null (null dereference)      
info/terminal.c                         terminal_begin_blink            457     
13
Logic error     Unix API                                                
info/tilde.c                            tilde_expand                    137     
3
Logic error     Dereference of null pointer                             
info/window.c                           window_change_window_height     419     
18
Logic error     Dereference of null pointer                             
info/window.c                           window_make_modeline            905     
12
Memory Error    Memory leak                                             
tp/Texinfo/Convert/XSParagraph/xspara.c xspara_init                     300     
14

Reply via email to