Patch from Shaun Jackman:
authorRob Landley <rob@landley.net>
Tue, 2 May 2006 19:46:52 +0000 (19:46 -0000)
committerRob Landley <rob@landley.net>
Tue, 2 May 2006 19:46:52 +0000 (19:46 -0000)
ls has an ugly bug. ls uses an array of pointers, the elements of
which are all in a linked list. To free the elements, instead of
freeing all the elements in the array, array[0..nelements], it frees
by iterating the linked list starting at array[0], which it assumes is
the head of the list. Unfortunately, ls also sorts the array! So,
array[0] is no longer the head, but somewhere in the middle of the
linked list. This patch fixes this bug, and also adds an
ENABLE_FEATURE_CLEAN_UP stanza.

coreutils/ls.c

index c9d24ff4a436ee1031643b09f5b3ce72f0b17c09..9cbb4cab7188e5274665cba2b50c5e33f63ce765 100644 (file)
@@ -338,20 +338,18 @@ static struct dnode **dnalloc(int num)
 }
 
 #ifdef CONFIG_FEATURE_LS_RECURSIVE
-static void dfree(struct dnode **dnp)
+static void dfree(struct dnode **dnp, int nfiles)
 {
-       struct dnode *cur, *next;
+       int i;
 
        if (dnp == NULL)
                return;
 
-       cur = dnp[0];
-       while (cur != NULL) {
+       for (i = 0; i < nfiles; i++) {
+               struct dnode *cur = dnp[i];
                if(cur->allocated)
                        free(cur->fullname);    /* free the filename */
-               next = cur->next;
                free(cur);              /* free the dnode */
-               cur = next;
        }
        free(dnp);                      /* free the array holding the dnode pointers */
 }
@@ -561,7 +559,7 @@ static void showdirs(struct dnode **dn, int ndirs, int first)
                                        free(dnd);      /* free the array of dnode pointers to the dirs */
                                }
                        }
-                       dfree(subdnp);  /* free the dnodes and the fullname mem */
+                       dfree(subdnp, nfiles);  /* free the dnodes and the fullname mem */
 #endif
                }
        }
@@ -1151,13 +1149,19 @@ int ls_main(int argc, char **argv)
                        shellsort(dnf, dnfiles);
 #endif
                        showfiles(dnf, dnfiles);
+                       if (ENABLE_FEATURE_CLEAN_UP)
+                               free(dnf);
                }
                if (dndirs > 0) {
 #ifdef CONFIG_FEATURE_LS_SORTFILES
                        shellsort(dnd, dndirs);
 #endif
                        showdirs(dnd, dndirs, dnfiles == 0);
+                       if (ENABLE_FEATURE_CLEAN_UP)
+                               free(dnd);
                }
        }
+       if (ENABLE_FEATURE_CLEAN_UP)
+               dfree(dnp, nfiles);
        return (status);
 }