diff options
author | Christos Zoulas <christos@zoulas.com> | 2011-03-20 20:36:51 +0000 |
---|---|---|
committer | Christos Zoulas <christos@zoulas.com> | 2011-03-20 20:36:51 +0000 |
commit | 4d3ddf078bd92605c9035e17812677995343c64c (patch) | |
tree | 041d8b8bac86ad04281f4aca9519afca8db3d139 | |
parent | 7fdd69f613abbea5c2ae07d448e783665b6c17cf (diff) | |
download | file-git-4d3ddf078bd92605c9035e17812677995343c64c.tar.gz |
MAXPATHLEN elimination.
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/apprentice.c | 54 | ||||
-rw-r--r-- | src/file.c | 25 | ||||
-rw-r--r-- | src/file.h | 6 | ||||
-rw-r--r-- | src/getline.c | 100 | ||||
-rw-r--r-- | src/magic.c | 105 |
7 files changed, 216 insertions, 81 deletions
@@ -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 diff --git a/configure.ac b/configure.ac index 2a57213b..0e353a9e 100644 --- a/configure.ac +++ b/configure.ac @@ -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) diff --git a/src/apprentice.c b/src/apprentice.c index ecbb8b8d..e12efa31 100644 --- a/src/apprentice.c +++ b/src/apprentice.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: apprentice.c,v 1.167 2011/03/15 22:15:30 christos Exp $") +FILE_RCSID("@(#)$File: apprentice.c,v 1.168 2011/03/20 20:36:52 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); } /* @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: file.c,v 1.142 2011/02/03 01:57:33 christos Exp $") +FILE_RCSID("@(#)$File: file.c,v 1.143 2011/03/20 20:36:52 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; } @@ -27,7 +27,7 @@ */ /* * file.h - definitions for file(1) program - * @(#)$File: file.h,v 1.131 2011/02/03 01:43:33 christos Exp $ + * @(#)$File: file.h,v 1.132 2011/03/20 20:36:52 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 index 00000000..e3c41c4a --- /dev/null +++ b/src/getline.c @@ -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 diff --git a/src/magic.c b/src/magic.c index c917378e..06d12390 100644 --- a/src/magic.c +++ b/src/magic.c @@ -33,7 +33,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: magic.c,v 1.71 2011/02/24 03:35:37 christos Exp $") +FILE_RCSID("@(#)$File: magic.c,v 1.72 2011/03/20 20:36:52 christos Exp $") #endif /* lint */ #include "magic.h" @@ -73,10 +73,6 @@ FILE_RCSID("@(#)$File: magic.c,v 1.71 2011/02/24 03:35:37 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 * |