]> granicus.if.org Git - file/commitdiff
MAXPATHLEN elimination.
authorChristos Zoulas <christos@zoulas.com>
Sun, 20 Mar 2011 20:36:51 +0000 (20:36 +0000)
committerChristos Zoulas <christos@zoulas.com>
Sun, 20 Mar 2011 20:36:51 +0000 (20:36 +0000)
ChangeLog
configure.ac
src/apprentice.c
src/file.c
src/file.h
src/getline.c [new file with mode: 0644]
src/magic.c

index 7d9307981770d253d96289bec10dcea987e0299c..0ea7242477c6d6fcb789d7b0daf463788f674ef0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2011-03-20  16:35  Christos Zoulas <christos@zoulas.com>
+
+       * Eliminate MAXPATHLEN and use dynamic allocation for
+         path and file buffers.
+
 2011-03-15  18:15  Christos Zoulas <christos@zoulas.com>
 
        * binary tests on magic entries with masks could spuriously
index 2a57213b8f8c0af337cbfeeb462a9c43f470a96d..0e353a9e5a7e95e6af2282b2532018eb029a472b 100644 (file)
@@ -159,7 +159,7 @@ dnl Checks for functions
 AC_CHECK_FUNCS(mmap strerror strndup strtoul mbrtowc mkstemp utimes utime wcwidth strtof fork)
 
 dnl Provide implementation of some required functions if necessary
-AC_REPLACE_FUNCS(getopt_long asprintf vasprintf strlcpy strlcat)
+AC_REPLACE_FUNCS(getopt_long asprintf vasprintf strlcpy strlcat getline)
 
 dnl Checks for libraries
 AC_CHECK_LIB(z,gzopen)
index 02f87c128d02c3470828b6c1792e4de2a3f8a028..54546869a0fafd711a108e9bf207c8747235c55b 100644 (file)
@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.166 2011/02/24 03:35:59 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.167 2011/03/15 22:15:30 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -672,36 +672,38 @@ private void
 load_1(struct magic_set *ms, int action, const char *fn, int *errs,
    struct magic_entry **marray, uint32_t *marraycount)
 {
-       char line[BUFSIZ];
-       size_t lineno = 0;
+       size_t lineno = 0, llen = 0;
+       char *line = NULL;
+       ssize_t len;
+
        FILE *f = fopen(ms->file = fn, "r");
        if (f == NULL) {
                if (errno != ENOENT)
                        file_error(ms, errno, "cannot read magic file `%s'",
                                   fn);
                (*errs)++;
-       } else {
-               /* read and parse this file */
-               for (ms->line = 1;
-                   fgets(line, CAST(int, sizeof(line)), f) != NULL;
-                   ms->line++) {
-                       size_t len;
-                       len = strlen(line);
-                       if (len == 0) /* null line, garbage, etc */
-                               continue;
-                       if (line[len - 1] == '\n') {
-                               lineno++;
-                               line[len - 1] = '\0'; /* delete newline */
-                       }
-                       if (line[0] == '\0')    /* empty, do not parse */
-                               continue;
-                       if (line[0] == '#')     /* comment, do not parse */
-                               continue;
-                       if (line[0] == '!' && line[1] == ':') {
+               return;
+       }
+
+       /* read and parse this file */
+       for (ms->line = 1; (len = getline(&line, &llen, f)) != -1;
+           ms->line++) {
+               if (len == 0) /* null line, garbage, etc */
+                       continue;
+               if (line[len - 1] == '\n') {
+                       lineno++;
+                       line[len - 1] = '\0'; /* delete newline */
+               }
+               switch (line[0]) {
+               case '\0':      /* empty, do not parse */
+               case '#':       /* comment, do not parse */
+                       continue;
+               case '!':
+                       if (line[1] == ':') {
                                size_t i;
 
                                for (i = 0; bang[i].name != NULL; i++) {
-                                       if (len - 2 > bang[i].len &&
+                                       if ((size_t)(len - 2) > bang[i].len &&
                                            memcmp(bang[i].name, line + 2,
                                            bang[i].len) == 0)
                                                break;
@@ -727,13 +729,17 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs,
                                }
                                continue;
                        }
+                       /*FALLTHROUGH*/
+               default:
                        if (parse(ms, marray, marraycount, line, lineno,
                            action) != 0)
                                (*errs)++;
+                       break;
                }
-
-               (void)fclose(f);
        }
+       if (line)
+               free(line);
+       (void)fclose(f);
 }
 
 /*
index f0f5734715778268b188ba2ef6985df28c979bc2..dab6f78082deef2de51c821981788607a2568a50 100644 (file)
@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: file.c,v 1.141 2011/02/03 01:54:43 christos Exp $")
+FILE_RCSID("@(#)$File: file.c,v 1.142 2011/02/03 01:57:33 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -86,10 +86,6 @@ int getopt_long(int argc, char * const *argv, const char *optstring, const struc
     "       %s -C [-m magicfiles]\n" \
     "       %s [--help]\n"
 
-#ifndef MAXPATHLEN
-#define        MAXPATHLEN      1024
-#endif
-
 private int            /* Global command-line options          */
        bflag = 0,      /* brief output format                  */
        nopad = 0,      /* Don't pad output                     */
@@ -375,8 +371,10 @@ load(const char *magicfile, int flags)
 private int
 unwrap(struct magic_set *ms, const char *fn)
 {
-       char buf[MAXPATHLEN];
        FILE *f;
+       ssize_t len;
+       char *line = NULL;
+       size_t llen = 0;
        int wid = 0, cwid;
        int e = 0;
 
@@ -390,9 +388,10 @@ unwrap(struct magic_set *ms, const char *fn)
                        return 1;
                }
 
-               while (fgets(buf, sizeof(buf), f) != NULL) {
-                       buf[strcspn(buf, "\n")] = '\0';
-                       cwid = file_mbswidth(buf);
+               while ((len = getline(&line, &llen, f)) > 0) {
+                       if (line[len - 1] == '\n')
+                               line[len - 1] = '\0';
+                       cwid = file_mbswidth(line);
                        if (cwid > wid)
                                wid = cwid;
                }
@@ -400,13 +399,15 @@ unwrap(struct magic_set *ms, const char *fn)
                rewind(f);
        }
 
-       while (fgets(buf, sizeof(buf), f) != NULL) {
-               buf[strcspn(buf, "\n")] = '\0';
-               e |= process(ms, buf, wid);
+       while ((len = getline(&line, &llen, f)) > 0) {
+               if (line[len - 1] == '\n')
+                       line[len - 1] = '\0';
+               e |= process(ms, line, wid);
                if(nobuffer)
                        (void)fflush(stdout);
        }
 
+       free(line);
        (void)fclose(f);
        return e;
 }
index a0c722ffd9b454e01176a384167e917c8ca4dbd4..6b0ad956aac58c05562bed6bf359d1dad80c3258 100644 (file)
@@ -27,7 +27,7 @@
  */
 /*
  * file.h - definitions for file(1) program
- * @(#)$File: file.h,v 1.130 2011/01/04 19:29:32 rrt Exp $
+ * @(#)$File: file.h,v 1.131 2011/02/03 01:43:33 christos Exp $
  */
 
 #ifndef __file_h__
@@ -466,6 +466,10 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
 #ifndef HAVE_STRLCAT
 size_t strlcat(char *dst, const char *src, size_t siz);
 #endif
+#ifndef HAVE_GETLINE
+ssize_t getline(char **dst, size_t *len, FILE *fp);
+ssize_t getdelim(char **dst, size_t *len, int delimiter, FILE *fp);
+#endif
 
 #if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK)
 #define QUICK
diff --git a/src/getline.c b/src/getline.c
new file mode 100644 (file)
index 0000000..e3c41c4
--- /dev/null
@@ -0,0 +1,100 @@
+/*     $NetBSD: fgetln.c,v 1.9 2008/04/29 06:53:03 martin Exp $        */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "file.h"
+#if !HAVE_GETLINE
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+ssize_t
+getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp)
+{
+       char *ptr, *eptr;
+
+
+       if (*buf == NULL || *bufsiz == 0) {
+               *bufsiz = BUFSIZ;
+               if ((*buf = malloc(*bufsiz)) == NULL)
+                       return -1;
+       }
+
+       for (ptr = *buf, eptr = *buf + *bufsiz;;) {
+               int c = fgetc(fp);
+               if (c == -1) {
+                       if (feof(fp))
+                               return ptr == *buf ? -1 : ptr - *buf;
+                       else
+                               return -1;
+               }
+               *ptr++ = c;
+               if (c == delimiter) {
+                       *ptr = '\0';
+                       return ptr - *buf;
+               }
+               if (ptr + 2 >= eptr) {
+                       char *nbuf;
+                       size_t nbufsiz = *bufsiz * 2;
+                       ssize_t d = ptr - *buf;
+                       if ((nbuf = realloc(*buf, nbufsiz)) == NULL)
+                               return -1;
+                       *buf = nbuf;
+                       *bufsiz = nbufsiz;
+                       eptr = nbuf + nbufsiz;
+                       ptr = nbuf + d;
+               }
+       }
+}
+
+ssize_t
+getline(char **buf, size_t *bufsiz, FILE *fp)
+{
+       return getdelim(buf, bufsiz, '\n', fp);
+}
+
+#endif
+
+#ifdef TEST
+int
+main(int argc, char *argv[])
+{
+       char *p = NULL;
+       ssize_t len;
+       size_t n = 0;
+
+       while ((len = getline(&p, &n, stdin)) != -1)
+               (void)printf("%zd %s", len, p);
+       free(p);
+       return 0;
+}
+#endif
index c7c1df76cef4ffd147c1245e92687817e640cfdc..130dfe69e4d631dbc45dac0912a02ba7ad8435d5 100644 (file)
@@ -33,7 +33,7 @@
 #include "file.h"
 
 #ifndef        lint
-FILE_RCSID("@(#)$File: magic.c,v 1.70 2011/01/21 18:59:40 christos Exp $")
+FILE_RCSID("@(#)$File: magic.c,v 1.71 2011/02/24 03:35:37 christos Exp $")
 #endif /* lint */
 
 #include "magic.h"
@@ -73,10 +73,6 @@ FILE_RCSID("@(#)$File: magic.c,v 1.70 2011/01/21 18:59:40 christos Exp $")
 #endif
 #endif
 
-#ifndef MAXPATHLEN
-#define MAXPATHLEN 1024
-#endif
-
 private void free_mlist(struct mlist *);
 private void close_and_restore(const struct magic_set *, const char *, int,
     const struct stat *);
@@ -112,56 +108,82 @@ private const char *
 get_default_magic(void)
 {
        static const char hmagic[] = "/.magic/magic.mgc";
-       static char default_magic[2 * MAXPATHLEN + 2];
-       char *home;
-       char hmagicpath[MAXPATHLEN + 1] = { 0 };
+       static char *default_magic;
+       char *home, *hmagicpath;
 
 #ifndef WIN32
        struct stat st;
 
+       if (default_magic) {
+               free(default_magic);
+               default_magic = NULL;
+       }
        if ((home = getenv("HOME")) == NULL)
                return MAGIC;
 
-       (void)snprintf(hmagicpath, sizeof(hmagicpath), "%s/.magic", home);
-       if (stat(hmagicpath, &st) == -1)
+       if (asprintf(&hmagicpath, "%s/.magic", home) < 0)
                return MAGIC;
+       if (stat(hmagicpath, &st) == -1)
+               goto out;
        if (S_ISDIR(st.st_mode)) {
-               (void)snprintf(hmagicpath, sizeof(hmagicpath), "%s/%s", home,
-                   hmagic);
-               if (access(hmagicpath, R_OK) == -1)
+               free(hmagicpath);
+               if (asprintf(&hmagicpath, "%s/%s", home, hmagic) < 0)
                        return MAGIC;
+               if (access(hmagicpath, R_OK) == -1)
+                       goto out;
        }
 
-       (void)snprintf(default_magic, sizeof(default_magic), "%s:%s",
-           hmagicpath, MAGIC);
+       if (asprintf(&default_magic, "%s:%s", hmagicpath, MAGIC) < 0)
+               goto out;
+       free(hmagicpath);
+       return default_magic;
+out:
+       default_magic = NULL;
+       free(hmagicpath);
+       return MAGIC;
 #else
        char *hmagicp = hmagicpath;
-       char tmppath[MAXPATHLEN + 1] = { 0 };
-       char *hmagicend = &hmagicpath[sizeof(hmagicpath) - 1];
-       static const char pathsep[] = { PATHSEP, '\0' };
+       char *tmppath = NULL;
 
 #define APPENDPATH() \
-       if (access(tmppath, R_OK) != -1) \
-               hmagicp += snprintf(hmagicp, hmagicend - hmagicp, \
-                   "%s%s", hmagicp == hmagicpath ? "" : pathsep, tmppath)
+       do { \
+               if (tmppath && access(tmppath, R_OK) != -1) { \
+                       if (hmagicpath == NULL) { \
+                               hmagicpath = tmppath; \
+                               tmppath = NULL; \
+                       } else { \
+                               free(tmppath); \
+                               if (asprintf(&hmagicp, "%s%c%s", hmagicpath, \
+                                   PATHSEP, tmppath) >= 0) { \
+                                       free(hmagicpath); \
+                                       hmagicpath = hmagicp; \
+                               } \
+                       } \
+       } while (/*CONSTCOND*/0)
+                               
+       if (default_magic) {
+               free(default_magic);
+               default_magic = NULL;
+       }
+
        /* First, try to get user-specific magic file */
        if ((home = getenv("LOCALAPPDATA")) == NULL) {
                if ((home = getenv("USERPROFILE")) != NULL)
-                       (void)snprintf(tmppath, sizeof(tmppath),
+                       if (asprintf(&tmppath,
                            "%s/Local Settings/Application Data%s", home,
-                           hmagic);
+                           hmagic) < 0)
+                               tmppath = NULL;
        } else {
-               (void)snprintf(tmppath, sizeof(tmppath), "%s%s",
-                   home, hmagic);
-       }
-       if (tmppath[0] != '\0') {
-               APPENDPATH();
+               if (asprintf(&tmppath, "%s%s", home, hmagic) < 0)
+                       tmppath = NULL;
        }
 
+       APPENDPATH();
+
        /* Second, try to get a magic file from Common Files */
        if ((home = getenv("COMMONPROGRAMFILES")) != NULL) {
-               (void)snprintf(tmppath, sizeof(tmppath), "%s%s", home, hmagic);
-               APPENDPATH();
+               if (asprintf(&tmppath, "%s%s", home, hmagic) >= 0)
+                       APPENDPATH();
        }
 
 
@@ -169,27 +191,24 @@ get_default_magic(void)
        if (dllpath[0] != 0) {
                if (strlen(dllpath) > 3 &&
                    stricmp(&dllpath[strlen(dllpath) - 3], "bin") == 0) {
-                       (void)snprintf(tmppath, sizeof(tmppath),
-                           "%s/../share/misc/magic.mgc", dllpath);
-                       APPENDPATH();
+                       if (asprintf(&tmppath,
+                           "%s/../share/misc/magic.mgc", dllpath) >= 0)
+                               APPENDPATH();
                } else {
-                       (void)snprintf(tmppath, sizeof(tmppath),
-                           "%s/share/misc/magic.mgc", dllpath);
-                       APPENDPATH();
-                       else {
-                               (void)snprintf(tmppath, sizeof(tmppath),
-                                   "%s/magic.mgc", dllpath);
+                       if (asprintf(&tmppath,
+                           "%s/share/misc/magic.mgc", dllpath) >= 0)
+                               APPENDPATH();
+                       else if (asprintf(&tmppath,
+                           "%s/magic.mgc", dllpath) >= 0)
                                APPENDPATH();
-                       }
                }
        }
 
        /* Don't put MAGIC constant - it likely points to a file within MSys
        tree */
-       (void)strlcpy(default_magic, hmagicpath, sizeof(default_magic));
-#endif
-
+       default_magic = hmagicpath;
        return default_magic;
+#endif
 }
 
 public const char *