avoid staircase, fix leak, use directory again
authorChristos Zoulas <christos@zoulas.com>
Fri, 11 Sep 2009 23:39:25 +0000 (23:39 +0000)
committerChristos Zoulas <christos@zoulas.com>
Fri, 11 Sep 2009 23:39:25 +0000 (23:39 +0000)
src/apprentice.c

index b1e0231af6bff0af44c6c3f836b9036db98ccc58..fd8a243d0041f3bc4fd6634417d1d1bdc43f145c 100644 (file)
@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.154 2009/08/20 12:51:10 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.155 2009/09/11 22:40:50 rrt Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -721,36 +721,41 @@ apprentice_load(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp,
        /* load directory or file */
        if (stat(fn, &st) == 0 && S_ISDIR(st.st_mode)) {
                dir = opendir(fn);
-               if (dir) {
-                       while ((d = readdir(dir)) != NULL) {
-                               snprintf(subfn, sizeof(subfn), "%s/%s",
-                                   fn, d->d_name);
-                               if (stat(subfn, &st) == 0 &&
-                                   S_ISREG(st.st_mode)) {
-                                        if ((mfn = strdup(subfn)) == NULL) {
-                                                file_oomem(ms, strlen(subfn));
-                                                errs++;
-                                                goto out;
-                                        }
-                                        if (files >= maxfiles) {
-                                                maxfiles = (maxfiles + 1) * 2;
-                                                if ((filearr = CAST(char **, realloc(filearr, maxfiles * sizeof(*filearr)))) == NULL) {
-                                                        file_oomem(ms, files * sizeof(*filearr));
-                                                        errs++;
-                                                        goto out;
-                                                }
-                                        }
-                                        filearr[files++] = mfn;
-                               }
+               if (!dir) {
+                       errs++;
+                       goto out;
+               }
+               while ((d = readdir(dir)) != NULL) {
+                       (void)snprintf(subfn, sizeof(subfn), "%s/%s",
+                           fn, d->d_name);
+                       if (stat(subfn, &st) == -1 || !S_ISREG(st.st_mode))
+                               continue;
+                       if ((mfn = strdup(subfn)) == NULL) {
+                               file_oomem(ms, strlen(subfn));
+                               errs++;
+                               goto out;
                        }
-                       closedir(dir);
-                       qsort((void *)filearr, files, sizeof(char *), cmpstrp);
-                        for (i = 0; i < files; i++) {
-                                load_1(ms, action, filearr[i], &errs, &marray, &marraycount);
-                               free(filearr[i]);
+                       if (files >= maxfiles) {
+                               size_t mlen;
+                               maxfiles = (maxfiles + 1) * 2;
+                               mlen = maxfiles * sizeof(*filearr);
+                               if ((filearr = CAST(char **,
+                                   realloc(filearr, mlen))) == NULL) {
+                                       file_oomem(ms, mlen);
+                                       errs++;
+                                       goto out;
+                               }
                        }
-               } else
-                       errs++;
+                       filearr[files++] = mfn;
+               }
+               closedir(dir);
+               qsort(filearr, files, sizeof(*filearr), cmpstrp);
+               for (i = 0; i < files; i++) {
+                       load_1(ms, action, filearr[i], &errs, &marray,
+                           &marraycount);
+                       free(filearr[i]);
+               }
+               free(filearr);
        } else
                load_1(ms, action, fn, &errs, &marray, &marraycount);
        if (errs)