summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristos Zoulas <christos@zoulas.com>2011-03-20 20:36:51 +0000
committerChristos Zoulas <christos@zoulas.com>2011-03-20 20:36:51 +0000
commit4d3ddf078bd92605c9035e17812677995343c64c (patch)
tree041d8b8bac86ad04281f4aca9519afca8db3d139
parent7fdd69f613abbea5c2ae07d448e783665b6c17cf (diff)
downloadfile-git-4d3ddf078bd92605c9035e17812677995343c64c.tar.gz
MAXPATHLEN elimination.
-rw-r--r--ChangeLog5
-rw-r--r--configure.ac2
-rw-r--r--src/apprentice.c54
-rw-r--r--src/file.c25
-rw-r--r--src/file.h6
-rw-r--r--src/getline.c100
-rw-r--r--src/magic.c105
7 files changed, 216 insertions, 81 deletions
diff --git a/ChangeLog b/ChangeLog
index 7d930798..0ea72424 100644
--- 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
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);
}
/*
diff --git a/src/file.c b/src/file.c
index 8dfb199d..25367357 100644
--- a/src/file.c
+++ b/src/file.c
@@ -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;
}
diff --git a/src/file.h b/src/file.h
index d171a253..683dffc9 100644
--- a/src/file.h
+++ b/src/file.h
@@ -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 *