=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/file/Attic/funcs.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- src/usr.bin/file/Attic/funcs.c 2008/05/08 01:40:56 1.5 +++ src/usr.bin/file/Attic/funcs.c 2009/04/24 18:54:34 1.6 @@ -1,4 +1,4 @@ -/* $OpenBSD: funcs.c,v 1.5 2008/05/08 01:40:56 chl Exp $ */ +/* $OpenBSD: funcs.c,v 1.6 2009/04/24 18:54:34 chl Exp $ */ /* * Copyright (c) Christos Zoulas 2003. * All Rights Reserved. @@ -37,67 +37,40 @@ #if defined(HAVE_WCTYPE_H) #include #endif -#if defined(HAVE_LIMITS_H) -#include -#endif -#ifndef SIZE_T_MAX -#ifdef __LP64__ -#define SIZE_T_MAX (size_t)0xfffffffffffffffffU -#else -#define SIZE_T_MAX (size_t)0xffffffffU -#endif -#endif #ifndef lint -FILE_RCSID("@(#)$Id: funcs.c,v 1.5 2008/05/08 01:40:56 chl Exp $") +FILE_RCSID("@(#)$Id: funcs.c,v 1.6 2009/04/24 18:54:34 chl Exp $") #endif /* lint */ -#ifndef HAVE_VSNPRINTF -int vsnprintf(char *, size_t, const char *, va_list); -#endif - /* - * Like printf, only we print to a buffer and advance it. + * Like printf, only we append to a buffer. */ protected int file_printf(struct magic_set *ms, const char *fmt, ...) { va_list ap; - size_t len, size; - char *buf; + int len; + char *buf, *newstr; va_start(ap, fmt); + len = vasprintf(&buf, fmt, ap); + if (len < 0) + goto out; + va_end(ap); - len = vsnprintf(ms->o.ptr, ms->o.left, fmt, ap); - if (len == -1) { - file_error(ms, errno, "vsnprintf failed"); - return -1; - } else if (len >= ms->o.left) { - long diff; /* XXX: really ptrdiff_t */ - - va_end(ap); - size = (ms->o.size - ms->o.left) + len + 1024; - if ((buf = realloc(ms->o.buf, size)) == NULL) { - file_oomem(ms, size); - return -1; - } - diff = ms->o.ptr - ms->o.buf; - ms->o.ptr = buf + diff; - ms->o.buf = buf; - ms->o.left = size - diff; - ms->o.size = size; - - va_start(ap, fmt); - len = vsnprintf(ms->o.ptr, ms->o.left, fmt, ap); - if (len == -1) { - file_error(ms, errno, "vsnprintf failed"); - return -1; - } + if (ms->o.buf != NULL) { + len = asprintf(&newstr, "%s%s", ms->o.buf, buf); + free(buf); + if (len < 0) + goto out; + free(ms->o.buf); + buf = newstr; } - va_end(ap); - ms->o.ptr += len; - ms->o.left -= len; + ms->o.buf = buf; return 0; +out: + file_error(ms, errno, "vasprintf failed"); + return -1; } /* @@ -108,21 +81,17 @@ file_error_core(struct magic_set *ms, int error, const char *f, va_list va, uint32_t lineno) { - size_t len; /* Only the first error is ok */ if (ms->haderr) return; - len = 0; if (lineno != 0) { - (void)snprintf(ms->o.buf, ms->o.size, "line %u: ", lineno); - len = strlen(ms->o.buf); + free(ms->o.buf); + ms->o.buf = NULL; + file_printf(ms, "line %u: ", lineno); } - (void)vsnprintf(ms->o.buf + len, ms->o.size - len, f, va); - if (error > 0) { - len = strlen(ms->o.buf); - (void)snprintf(ms->o.buf + len, ms->o.size - len, " (%s)", - strerror(error)); - } + file_printf(ms, f, va); + if (error > 0) + file_printf(ms, " (%s)", strerror(error)); ms->haderr++; ms->error = error; } @@ -173,59 +142,73 @@ file_buffer(struct magic_set *ms, int fd, const char *inname, const void *buf, size_t nb) { - int m; + int m; + int mime = ms->flags & MAGIC_MIME; + if (nb == 0) { + if ((!mime || (mime & MAGIC_MIME_TYPE)) && + file_printf(ms, mime ? "application/x-empty" : + "empty") == -1) + return -1; + return 1; + } else if (nb == 1) { + if ((!mime || (mime & MAGIC_MIME_TYPE)) && + file_printf(ms, mime ? "application/octet-stream" : + "very short file (no magic)") == -1) + return -1; + return 1; + } + #ifdef __EMX__ - if ((ms->flags & MAGIC_NO_CHECK_APPTYPE) == 0 && inname) { - switch (file_os2_apptype(ms, inname, buf, nb)) { - case -1: - return -1; - case 0: - break; - default: - return 1; + if ((ms->flags & MAGIC_NO_CHECK_APPTYPE) == 0 && inname) { + switch (file_os2_apptype(ms, inname, buf, nb)) { + case -1: + return -1; + case 0: + break; + default: + return 1; + } } - } #endif - /* try compression stuff */ - if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) != 0 || - (m = file_zmagic(ms, fd, inname, buf, nb)) == 0) { - /* Check if we have a tar file */ - if ((ms->flags & MAGIC_NO_CHECK_TAR) != 0 || - (m = file_is_tar(ms, buf, nb)) == 0) { - /* try tests in /etc/magic (or surrogate magic file) */ - if ((ms->flags & MAGIC_NO_CHECK_SOFT) != 0 || - (m = file_softmagic(ms, buf, nb)) == 0) { - /* try known keywords, check whether it is ASCII */ - if ((ms->flags & MAGIC_NO_CHECK_ASCII) != 0 || - (m = file_ascmagic(ms, buf, nb)) == 0) { - /* abandon hope, all ye who remain here */ - if (file_printf(ms, ms->flags & MAGIC_MIME ? - (nb ? "application/octet-stream" : - "application/empty") : - (nb ? "data" : - "empty")) == -1) - return -1; - m = 1; + /* try compression stuff */ + if ((ms->flags & MAGIC_NO_CHECK_COMPRESS) != 0 || + (m = file_zmagic(ms, fd, inname, buf, nb)) == 0) { + /* Check if we have a tar file */ + if ((ms->flags & MAGIC_NO_CHECK_TAR) != 0 || + (m = file_is_tar(ms, buf, nb)) == 0) { + /* try tests in /etc/magic (or surrogate magic file) */ + if ((ms->flags & MAGIC_NO_CHECK_SOFT) != 0 || + (m = file_softmagic(ms, buf, nb, BINTEST)) == 0) { + /* try known keywords, check whether it is ASCII */ + if ((ms->flags & MAGIC_NO_CHECK_ASCII) != 0 || + (m = file_ascmagic(ms, buf, nb)) == 0) { + /* abandon hope, all ye who remain here */ + if ((!mime || (mime & MAGIC_MIME_TYPE)) && + file_printf(ms, mime ? "application/octet-stream" : + "data") == -1) + return -1; + m = 1; + } } } } - } #ifdef BUILTIN_ELF - if ((ms->flags & MAGIC_NO_CHECK_ELF) == 0 && m == 1 && nb > 5 && fd != -1) { - /* - * We matched something in the file, so this *might* - * be an ELF file, and the file is at least 5 bytes - * long, so if it's an ELF file it has at least one - * byte past the ELF magic number - try extracting - * information from the ELF headers that cannot easily - * be extracted with rules in the magic file. - */ - (void)file_tryelf(ms, fd, buf, nb); - } + if ((ms->flags & MAGIC_NO_CHECK_ELF) == 0 && m == 1 && + nb > 5 && fd != -1) { + /* + * We matched something in the file, so this *might* + * be an ELF file, and the file is at least 5 bytes + * long, so if it's an ELF file it has at least one + * byte past the ELF magic number - try extracting + * information from the ELF headers that cannot easily + * be extracted with rules in the magic file. + */ + (void)file_tryelf(ms, fd, buf, nb); + } #endif - return m; + return m; } #endif @@ -236,8 +219,7 @@ file_error(ms, 0, "no magic files loaded"); return -1; } - ms->o.ptr = ms->o.buf; - ms->o.left = ms->o.size; + ms->o.buf = NULL; ms->haderr = 0; ms->error = -1; return 0; @@ -263,21 +245,18 @@ if (ms->flags & MAGIC_RAW) return ms->o.buf; - len = ms->o.size - ms->o.left; /* * 4 is for octal representation, + 1 is for NUL */ - if (len > (SIZE_T_MAX - 1) / 4) { + len = strlen(ms->o.buf); + if (len > (SIZE_MAX - 1) / 4) { file_oomem(ms, len); return NULL; } psize = len * 4 + 1; - if (ms->o.psize < psize) { - if ((pbuf = realloc(ms->o.pbuf, psize)) == NULL) { - file_oomem(ms, psize); - return NULL; - } - ms->o.psize = psize; - ms->o.pbuf = pbuf; + if ((pbuf = realloc(ms->o.pbuf, psize)) == NULL) { + file_oomem(ms, psize); + return NULL; } + ms->o.pbuf = pbuf; #if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH) { @@ -290,7 +269,7 @@ np = ms->o.pbuf; op = ms->o.buf; - eop = op + strlen(ms->o.buf); + eop = op + len; while (op < eop) { bytesconsumed = mbrtowc(&nextchar, op, @@ -350,28 +329,3 @@ #endif /* ENABLE_CONDITIONALS */ return 0; } -/* - * Yes these wrappers suffer from buffer overflows, but if your OS does not - * have the real functions, maybe you should consider replacing your OS? - */ -#ifndef HAVE_VSNPRINTF -int -vsnprintf(char *buf, size_t len, const char *fmt, va_list ap) -{ - return vsprintf(buf, fmt, ap); -} -#endif - -#ifndef HAVE_SNPRINTF -/*ARGSUSED*/ -int -snprintf(char *buf, size_t len, const char *fmt, ...) -{ - int rv; - va_list ap; - va_start(ap, fmt); - rv = vsprintf(buf, fmt, ap); - va_end(ap); - return rv; -} -#endif