diff options
author | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2006-05-19 10:15:47 +0000 |
---|---|---|
committer | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2006-05-19 10:15:47 +0000 |
commit | 006955556f9677ecf73aac582497f6efc47d383f (patch) | |
tree | 463ca430a926b59419c750ecb279150af878bfe8 | |
parent | cc8e90d1fbaad77ba6748635792aad7121c212bb (diff) | |
download | busybox-w32-006955556f9677ecf73aac582497f6efc47d383f.tar.gz busybox-w32-006955556f9677ecf73aac582497f6efc47d383f.tar.bz2 busybox-w32-006955556f9677ecf73aac582497f6efc47d383f.zip |
Patch from Shaun Jackman:
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.
(r14978 from trunk)
-rw-r--r-- | coreutils/ls.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/coreutils/ls.c b/coreutils/ls.c index 964e7c964..2da634a52 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
@@ -350,20 +350,18 @@ static struct dnode **dnalloc(int num) | |||
350 | } | 350 | } |
351 | 351 | ||
352 | #ifdef CONFIG_FEATURE_LS_RECURSIVE | 352 | #ifdef CONFIG_FEATURE_LS_RECURSIVE |
353 | static void dfree(struct dnode **dnp) | 353 | static void dfree(struct dnode **dnp, int nfiles) |
354 | { | 354 | { |
355 | struct dnode *cur, *next; | 355 | int i; |
356 | 356 | ||
357 | if (dnp == NULL) | 357 | if (dnp == NULL) |
358 | return; | 358 | return; |
359 | 359 | ||
360 | cur = dnp[0]; | 360 | for (i = 0; i < nfiles; i++) { |
361 | while (cur != NULL) { | 361 | struct dnode *cur = dnp[i]; |
362 | if(cur->allocated) | 362 | if(cur->allocated) |
363 | free(cur->fullname); /* free the filename */ | 363 | free(cur->fullname); /* free the filename */ |
364 | next = cur->next; | ||
365 | free(cur); /* free the dnode */ | 364 | free(cur); /* free the dnode */ |
366 | cur = next; | ||
367 | } | 365 | } |
368 | free(dnp); /* free the array holding the dnode pointers */ | 366 | free(dnp); /* free the array holding the dnode pointers */ |
369 | } | 367 | } |
@@ -573,7 +571,7 @@ static void showdirs(struct dnode **dn, int ndirs, int first) | |||
573 | free(dnd); /* free the array of dnode pointers to the dirs */ | 571 | free(dnd); /* free the array of dnode pointers to the dirs */ |
574 | } | 572 | } |
575 | } | 573 | } |
576 | dfree(subdnp); /* free the dnodes and the fullname mem */ | 574 | dfree(subdnp, nfiles); /* free the dnodes and the fullname mem */ |
577 | #endif | 575 | #endif |
578 | } | 576 | } |
579 | } | 577 | } |
@@ -1164,13 +1162,19 @@ int ls_main(int argc, char **argv) | |||
1164 | shellsort(dnf, dnfiles); | 1162 | shellsort(dnf, dnfiles); |
1165 | #endif | 1163 | #endif |
1166 | showfiles(dnf, dnfiles); | 1164 | showfiles(dnf, dnfiles); |
1165 | if (ENABLE_FEATURE_CLEAN_UP) | ||
1166 | free(dnf); | ||
1167 | } | 1167 | } |
1168 | if (dndirs > 0) { | 1168 | if (dndirs > 0) { |
1169 | #ifdef CONFIG_FEATURE_LS_SORTFILES | 1169 | #ifdef CONFIG_FEATURE_LS_SORTFILES |
1170 | shellsort(dnd, dndirs); | 1170 | shellsort(dnd, dndirs); |
1171 | #endif | 1171 | #endif |
1172 | showdirs(dnd, dndirs, dnfiles == 0); | 1172 | showdirs(dnd, dndirs, dnfiles == 0); |
1173 | if (ENABLE_FEATURE_CLEAN_UP) | ||
1174 | free(dnd); | ||
1173 | } | 1175 | } |
1174 | } | 1176 | } |
1177 | if (ENABLE_FEATURE_CLEAN_UP) | ||
1178 | dfree(dnp, nfiles); | ||
1175 | return (status); | 1179 | return (status); |
1176 | } | 1180 | } |