upgraded libmagic to 5.14

This commit is contained in:
Anatol Belski 2013-04-07 22:15:56 +02:00
parent 39bc1bd25f
commit 10367fa7c6
23 changed files with 103555 additions and 79508 deletions

3
NEWS
View file

@ -11,6 +11,9 @@ PHP NEWS
- CURL:
. Add CURL_WRAPPERS_ENABLED constant. (Laruence)
- Fileinfo:
. Upgraded libmagic to 5.14. (Anatol)
?? ??? 2013, PHP 5.4.14
- Core:
. Fixed bug #64529 (Ran out of opcode space). (Dmitry)

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: ascmagic.c,v 1.84 2011/12/08 12:38:24 rrt Exp $")
FILE_RCSID("@(#)$File: ascmagic.c,v 1.85 2012/08/09 16:33:15 christos Exp $")
#endif /* lint */
#include "magic.h"
@ -134,13 +134,15 @@ file_ascmagic_with_encoding(struct magic_set *ms, const unsigned char *buf,
goto done;
}
if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0) {
if (ulen > 0 && (ms->flags & MAGIC_NO_CHECK_SOFT) == 0) {
/* Convert ubuf to UTF-8 and try text soft magic */
/* malloc size is a conservative overestimate; could be
improved, or at least realloced after conversion. */
mlen = ulen * 6;
utf8_buf = emalloc(mlen);
if ((utf8_buf = CAST(unsigned char *, emalloc(mlen))) == NULL) {
file_oomem(ms, mlen);
goto done;
}
if ((utf8_end = encode_utf8(utf8_buf, mlen, ubuf, ulen))
== NULL)
goto done;
@ -209,6 +211,7 @@ file_ascmagic_with_encoding(struct magic_set *ms, const unsigned char *buf,
case 0:
if (file_printf(ms, ", ") == -1)
goto done;
break;
case -1:
goto done;
default:

View file

@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: cdf.c,v 1.50 2012/02/20 22:35:29 christos Exp $")
FILE_RCSID("@(#)$File: cdf.c,v 1.53 2013/02/26 16:20:42 christos Exp $")
#endif
#include <assert.h>
@ -278,10 +278,10 @@ cdf_check_stream_offset(const cdf_stream_t *sst, const cdf_header_t *h,
const char *b = (const char *)sst->sst_tab;
const char *e = ((const char *)p) + tail;
(void)&line;
if (e >= b && (size_t)(e - b) < CDF_SEC_SIZE(h) * sst->sst_len)
if (e >= b && (size_t)(e - b) <= CDF_SEC_SIZE(h) * sst->sst_len)
return 0;
DPRINTF(("%d: offset begin %p end %p %" SIZE_T_FORMAT "u"
" >= %" SIZE_T_FORMAT "u [%" SIZE_T_FORMAT "u %"
DPRINTF(("%d: offset begin %p < end %p || %" SIZE_T_FORMAT "u"
" > %" SIZE_T_FORMAT "u [%" SIZE_T_FORMAT "u %"
SIZE_T_FORMAT "u]\n", line, b, e, (size_t)(e - b),
CDF_SEC_SIZE(h) * sst->sst_len, CDF_SEC_SIZE(h), sst->sst_len));
errno = EFTYPE;

View file

@ -39,6 +39,8 @@
#include <winsock2.h>
#define timespec timeval
#define tv_nsec tv_usec
#define asctime_r php_asctime_r
#define ctime_r php_ctime_r
#endif
#ifdef __DJGPP__
#define timespec timeval
@ -312,7 +314,7 @@ int cdf_print_elapsed_time(char *, size_t, cdf_timestamp_t);
uint16_t cdf_tole2(uint16_t);
uint32_t cdf_tole4(uint32_t);
uint64_t cdf_tole8(uint64_t);
char *cdf_ctime(const time_t *);
char *cdf_ctime(const time_t *, char *);
#ifdef CDF_DEBUG
void cdf_dump_header(const cdf_header_t *);

View file

@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: cdf_time.c,v 1.11 2011/12/13 13:48:41 christos Exp $")
FILE_RCSID("@(#)$File: cdf_time.c,v 1.12 2012/05/15 17:14:36 christos Exp $")
#endif
#include <time.h>
@ -104,6 +104,7 @@ cdf_timestamp_to_timespec(struct timeval *ts, cdf_timestamp_t t)
#endif
int rdays;
/* XXX 5.14 at least introdced 100 ns intervals, this is to do */
/* Time interval, in microseconds */
ts->tv_usec = (t % CDF_TIME_PREC) * CDF_TIME_PREC;
@ -166,15 +167,13 @@ cdf_timespec_to_timestamp(cdf_timestamp_t *t, const struct timeval *ts)
}
char *
cdf_ctime(const time_t *sec)
cdf_ctime(const time_t *sec, char *buf)
{
static char ctbuf[26];
char *ptr = ctime(sec);
char *ptr = ctime_r(sec, buf);
if (ptr != NULL)
return ptr;
(void)snprintf(ctbuf, sizeof(ctbuf), "*Bad* 0x%16.16llx\n",
(long long)*sec);
return ctbuf;
return buf;
(void)snprintf(buf, 26, "*Bad* 0x%16.16llx\n", (long long)*sec);
return buf;
}
@ -183,12 +182,13 @@ int
main(int argc, char *argv[])
{
struct timeval ts;
char buf[25];
static const cdf_timestamp_t tst = 0x01A5E403C2D59C00ULL;
static const char *ref = "Sat Apr 23 01:30:00 1977";
char *p, *q;
cdf_timestamp_to_timespec(&ts, tst);
p = cdf_ctime(&ts.tv_sec);
p = cdf_ctime(&ts.tv_sec, buf);
if ((q = strchr(p, '\n')) != NULL)
*q = '\0';
if (strcmp(ref, p) != 0)

View file

@ -36,7 +36,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: compress.c,v 1.68 2011/12/08 12:38:24 rrt Exp $")
FILE_RCSID("@(#)$File: compress.c,v 1.70 2012/11/07 17:54:48 christos Exp $")
#endif
#include "magic.h"
@ -188,9 +188,9 @@ sread(int fd, void *buf, size_t n, int canbepipe)
goto nocheck;
#ifdef FIONREAD
if ((canbepipe && (ioctl(fd, FIONREAD, &t) == -1)) || (t == 0)) {
if (canbepipe && (ioctl(fd, FIONREAD, &t) == -1 || t == 0)) {
#ifdef FD_ZERO
int cnt;
ssize_t cnt;
for (cnt = 0;; cnt++) {
fd_set check;
struct timeval tout = {0, 100 * 1000};
@ -247,9 +247,6 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
char buf[4096];
ssize_t r;
int tfd;
#ifdef HAVE_MKSTEMP
int te;
#endif
(void)strlcpy(buf, "/tmp/file.XXXXXX", sizeof buf);
#ifndef HAVE_MKSTEMP
@ -261,10 +258,13 @@ file_pipe2file(struct magic_set *ms, int fd, const void *startbuf,
errno = r;
}
#else
tfd = mkstemp(buf);
te = errno;
(void)unlink(buf);
errno = te;
{
int te;
tfd = mkstemp(buf);
te = errno;
(void)unlink(buf);
errno = te;
}
#endif
if (tfd == -1) {
file_error(ms, errno,
@ -345,7 +345,9 @@ uncompressgzipped(struct magic_set *ms, const unsigned char *old,
if (data_start >= n)
return 0;
*newch = (unsigned char *)emalloc(HOWMANY + 1));
if ((*newch = CAST(unsigned char *, emalloc(HOWMANY + 1))) == NULL) {
return 0;
}
/* XXX: const castaway, via strchr */
z.next_in = (Bytef *)strchr((const char *)old + data_start,

View file

@ -59,7 +59,8 @@
(off_t)elf_getu(swap, elfhdr.e_shoff),
elf_getu16(swap, elfhdr.e_shnum),
(size_t)elf_getu16(swap, elfhdr.e_shentsize),
fsize, &flags, elf_getu16(swap, elfhdr.e_machine)) == -1)
fsize, &flags, elf_getu16(swap, elfhdr.e_machine),
(int)elf_getu16(swap, elfhdr.e_shstrndx)) == -1)
return -1;
break;

View file

@ -27,7 +27,7 @@
*/
/*
* file.h - definitions for file(1) program
* @(#)$File: file.h,v 1.135 2011/09/20 15:30:14 christos Exp $
* @(#)$File: file.h,v 1.144 2013/02/18 15:40:59 christos Exp $
*/
#ifndef __file_h__
@ -90,10 +90,18 @@
#endif
#define private static
#if HAVE_VISIBILITY
#define public __attribute__ ((__visibility__("default")))
#ifndef protected
#define protected __attribute__ ((__visibility__("hidden")))
#endif
#else
#define public
#ifndef protected
#define protected
#endif
#define public
#endif
#ifndef __arraycount
#define __arraycount(a) (sizeof(a) / sizeof(a[0]))
@ -122,12 +130,13 @@
#endif
#define MAXMAGIS 8192 /* max entries in any one magic file
or directory */
#define MAXDESC 64 /* max leng of text description/MIME type */
#define MAXstring 64 /* max leng of "string" types */
#define MAXDESC 64 /* max len of text description/MIME type */
#define MAXMIME 80 /* max len of text MIME type */
#define MAXstring 64 /* max len of "string" types */
#define MAGICNO 0xF11E041C
#define VERSIONNO 8
#define FILE_MAGICSIZE 232
#define VERSIONNO 10
#define FILE_MAGICSIZE 248
#define FILE_LOAD 0
#define FILE_CHECK 1
@ -210,7 +219,12 @@ struct magic {
#define FILE_BEID3 39
#define FILE_LEID3 40
#define FILE_INDIRECT 41
#define FILE_NAMES_SIZE 42/* size of array to contain all names */
#define FILE_QWDATE 42
#define FILE_LEQWDATE 43
#define FILE_BEQWDATE 44
#define FILE_NAME 45
#define FILE_USE 46
#define FILE_NAMES_SIZE 47 /* size of array to contain all names */
#define IS_LIBMAGIC_STRING(t) \
((t) == FILE_STRING || \
@ -219,6 +233,8 @@ struct magic {
(t) == FILE_LESTRING16 || \
(t) == FILE_REGEX || \
(t) == FILE_SEARCH || \
(t) == FILE_NAME || \
(t) == FILE_USE || \
(t) == FILE_DEFAULT)
#define FILE_FMT_NONE 0
@ -287,9 +303,9 @@ struct magic {
union VALUETYPE value; /* either number or string */
/* Words 17-32 */
char desc[MAXDESC]; /* description */
/* Words 33-48 */
char mimetype[MAXDESC]; /* MIME type */
/* Words 49-50 */
/* Words 33-52 */
char mimetype[MAXMIME]; /* MIME type */
/* Words 53-54 */
char apple[8];
};
@ -310,12 +326,14 @@ struct magic {
#define PSTRING_LEN \
(PSTRING_1_BE|PSTRING_2_LE|PSTRING_2_BE|PSTRING_4_LE|PSTRING_4_BE)
#define PSTRING_LENGTH_INCLUDES_ITSELF BIT(12)
#define STRING_TRIM BIT(13)
#define CHAR_COMPACT_WHITESPACE 'W'
#define CHAR_COMPACT_OPTIONAL_WHITESPACE 'w'
#define CHAR_IGNORE_LOWERCASE 'c'
#define CHAR_IGNORE_UPPERCASE 'C'
#define CHAR_REGEX_OFFSET_START 's'
#define CHAR_TEXTTEST 't'
#define CHAR_TRIM 'T'
#define CHAR_BINTEST 'b'
#define CHAR_PSTRING_1_BE 'B'
#define CHAR_PSTRING_1_LE 'B'
@ -332,9 +350,7 @@ struct magic {
struct mlist {
struct magic *magic; /* array of magic entries */
uint32_t nmagic; /* number of entries in array */
int mapped; /* allocation type: 0 => apprentice_file
* 1 => apprentice_map + malloc
* 2 => apprentice_map + mmap */
void *map; /* internal resources used by entry */
struct mlist *next, *prev;
};
@ -354,8 +370,11 @@ struct level_info {
int last_cond; /* used for error checking by parse() */
#endif
};
#define MAGIC_SETS 2
struct magic_set {
struct mlist *mlist;
struct mlist *mlist[MAGIC_SETS]; /* list of regular entries */
struct cont {
size_t len;
struct level_info *li;
@ -389,10 +408,14 @@ struct magic_set {
typedef unsigned long unichar;
struct stat;
protected const char *file_fmttime(uint32_t, int);
#define FILE_T_LOCAL 1
#define FILE_T_WINDOWS 2
protected const char *file_fmttime(uint64_t, int, char *);
protected struct magic_set *file_ms_alloc(int);
protected void file_ms_free(struct magic_set *);
protected int file_buffer(struct magic_set *, php_stream *, const char *, const void *,
size_t);
protected int file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb, php_stream *stream);
protected int file_fsmagic(struct magic_set *, const char *, struct stat *, php_stream *);
protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
protected int file_replace(struct magic_set *, const char *, const char *);
protected int file_printf(struct magic_set *, const char *, ...);
@ -415,7 +438,8 @@ protected int file_encoding(struct magic_set *, const unsigned char *, size_t,
protected int file_is_tar(struct magic_set *, const unsigned char *, size_t);
protected int file_softmagic(struct magic_set *, const unsigned char *, size_t,
int, int);
protected struct mlist *file_apprentice(struct magic_set *, const char *, int);
protected int file_apprentice(struct magic_set *, const char *, int);
protected int file_magicfind(struct magic_set *, const char *, struct mlist *);
protected uint64_t file_signextend(struct magic_set *, struct magic *,
uint64_t);
protected void file_delmagic(struct magic *, int type, size_t entries);

View file

@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: fsmagic.c,v 1.64 2011/08/14 09:03:12 christos Exp $")
FILE_RCSID("@(#)$File: fsmagic.c,v 1.67 2013/03/17 15:43:20 christos Exp $")
#endif /* lint */
#include "magic.h"
@ -92,16 +92,19 @@ handle_mime(struct magic_set *ms, int mime, const char *str)
protected int
file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb, php_stream *stream)
{
int ret, did = 0;
int mime = ms->flags & MAGIC_MIME;
TSRMLS_FETCH();
if (ms->flags & MAGIC_APPLE)
return 0;
if (!fn && !stream) {
if (fn == NULL && !stream) {
return 0;
}
#define COMMA (did++ ? ", " : "")
if (stream) {
php_stream_statbuf ssb;
if (php_stream_stat(stream, &ssb) < 0) {
@ -122,20 +125,21 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb, php_stream *
}
}
ret = 1;
if (!mime) {
#ifdef S_ISUID
if (sb->st_mode & S_ISUID)
if (file_printf(ms, "setuid ") == -1)
if (file_printf(ms, "%ssetuid", COMMA) == -1)
return -1;
#endif
#ifdef S_ISGID
if (sb->st_mode & S_ISGID)
if (file_printf(ms, "setgid ") == -1)
if (file_printf(ms, "%ssetgid", COMMA) == -1)
return -1;
#endif
#ifdef S_ISVTX
if (sb->st_mode & S_ISVTX)
if (file_printf(ms, "sticky ") == -1)
if (file_printf(ms, "%ssticky", COMMA) == -1)
return -1;
#endif
}
@ -150,6 +154,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb, php_stream *
* are block special files and go on to the next file.
*/
if ((ms->flags & MAGIC_DEVICES) != 0) {
ret = 0;
break;
}
if (mime) {
@ -158,18 +163,18 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb, php_stream *
} else {
# ifdef HAVE_STAT_ST_RDEV
# ifdef dv_unit
if (file_printf(ms, "character special (%d/%d/%d)",
major(sb->st_rdev), dv_unit(sb->st_rdev),
if (file_printf(ms, "%scharacter special (%d/%d/%d)",
COMMA, major(sb->st_rdev), dv_unit(sb->st_rdev),
dv_subunit(sb->st_rdev)) == -1)
return -1;
# else
if (file_printf(ms, "character special (%ld/%ld)",
(long)major(sb->st_rdev), (long)minor(sb->st_rdev))
== -1)
if (file_printf(ms, "%scharacter special (%ld/%ld)",
COMMA, (long)major(sb->st_rdev),
(long)minor(sb->st_rdev)) == -1)
return -1;
# endif
# else
if (file_printf(ms, "character special") == -1)
if (file_printf(ms, "%scharacter special", COMMA) == -1)
return -1;
# endif
}
@ -184,18 +189,18 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb, php_stream *
if (mime) {
if (handle_mime(ms, mime, "fifo") == -1)
return -1;
} else if (file_printf(ms, "fifo (named pipe)") == -1)
} else if (file_printf(ms, "%sfifo (named pipe)", COMMA) == -1)
return -1;
return 1;
break;
#endif
#ifdef S_IFDOOR
case S_IFDOOR:
if (mime) {
if (handle_mime(ms, mime, "door") == -1)
return -1;
} else if (file_printf(ms, "door") == -1)
} else if (file_printf(ms, "%sdoor", COMMA) == -1)
return -1;
return 1;
break;
#endif
#ifdef S_IFLNK
case S_IFLNK:
@ -213,40 +218,40 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb, php_stream *
if (mime) {
if (handle_mime(ms, mime, "socket") == -1)
return -1;
} else if (file_printf(ms, "socket") == -1)
} else if (file_printf(ms, "%ssocket", COMMA) == -1)
return -1;
return 1;
break;
#endif
#endif
case S_IFREG:
break;
default:
file_error(ms, 0, "invalid mode 0%o", sb->st_mode);
return -1;
/*NOTREACHED*/
}
/*
* regular file, check next possibility
*
* If stat() tells us the file has zero length, report here that
* the file is empty, so we can skip all the work of opening and
* reading the file.
* But if the -s option has been given, we skip this optimization,
* since on some systems, stat() reports zero size for raw disk
* partitions. (If the block special device really has zero length,
* the fact that it is empty will be detected and reported correctly
* when we read the file.)
* But if the -s option has been given, we skip this
* optimization, since on some systems, stat() reports zero
* size for raw disk partitions. (If the block special device
* really has zero length, the fact that it is empty will be
* detected and reported correctly when we read the file.)
*/
if ((ms->flags & MAGIC_DEVICES) == 0 && sb->st_size == 0) {
if (mime) {
if (handle_mime(ms, mime, "x-empty") == -1)
return -1;
} else if (file_printf(ms, "empty") == -1)
} else if (file_printf(ms, "%sempty", COMMA) == -1)
return -1;
return 1;
break;
}
return 0;
ret = 0;
break;
default:
file_error(ms, 0, "invalid mode 0%o", sb->st_mode);
return -1;
/*NOTREACHED*/
}
return ret;
}

View file

@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: funcs.c,v 1.60 2011/12/08 12:38:24 rrt Exp $")
FILE_RCSID("@(#)$File: funcs.c,v 1.61 2012/10/30 23:11:51 christos Exp $")
#endif /* lint */
#include "magic.h"
@ -191,7 +191,7 @@ file_buffer(struct magic_set *ms, php_stream *stream, const char *inname, const
&code, &code_mime, &type);
}
#if defined(__EMX__)
#ifdef __EMX__
if ((ms->flags & MAGIC_NO_CHECK_APPTYPE) == 0 && inname) {
switch (file_os2_apptype(ms, inname, buf, nb)) {
case -1:
@ -307,7 +307,7 @@ file_buffer(struct magic_set *ms, php_stream *stream, const char *inname, const
protected int
file_reset(struct magic_set *ms)
{
if (ms->mlist == NULL) {
if (ms->mlist[0] == NULL) {
file_error(ms, 0, "no magic files loaded");
return -1;
}
@ -335,7 +335,7 @@ file_reset(struct magic_set *ms)
protected const char *
file_getbuffer(struct magic_set *ms)
{
char *pbuf, *op, *np;
char *op, *np;
size_t psize, len;
if (ms->event_flags & EVENT_HAD_ERR)
@ -353,8 +353,10 @@ file_getbuffer(struct magic_set *ms)
return NULL;
}
psize = len * 4 + 1;
pbuf = erealloc(ms->o.pbuf, psize);
ms->o.pbuf = pbuf;
if ((ms->o.pbuf = CAST(char *, erealloc(ms->o.pbuf, psize))) == NULL) {
file_oomem(ms, psize);
return NULL;
}
#if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
{
@ -413,7 +415,13 @@ file_check_mem(struct magic_set *ms, unsigned int level)
if (level >= ms->c.len) {
len = (ms->c.len += 20) * sizeof(*ms->c.li);
ms->c.li = (ms->c.li == NULL) ? emalloc(len) : erealloc(ms->c.li, len);
ms->c.li = CAST(struct level_info *, (ms->c.li == NULL) ?
emalloc(len) :
erealloc(ms->c.li, len));
if (ms->c.li == NULL) {
file_oomem(ms, len);
return -1;
}
}
ms->c.li[level].got_match = 0;
#ifdef ENABLE_CONDITIONALS
@ -445,11 +453,7 @@ file_replace(struct magic_set *ms, const char *pat, const char *rep)
ZVAL_STRINGL(patt, pat, strlen(pat), 0);
opts |= PCRE_MULTILINE;
convert_libmagic_pattern(patt, opts);
#if (PHP_MAJOR_VERSION < 6)
if ((pce = pcre_get_compiled_regex_cache(Z_STRVAL_P(patt), Z_STRLEN_P(patt) TSRMLS_CC)) == NULL) {
#else
if ((pce = pcre_get_compiled_regex_cache(IS_STRING, Z_STRVAL_P(patt), Z_STRLEN_P(patt) TSRMLS_CC)) == NULL) {
#endif
zval_dtor(patt);
FREE_ZVAL(patt);
return -1;

View file

@ -28,7 +28,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: magic.c,v 1.74 2011/05/26 01:27:59 christos Exp $")
FILE_RCSID("@(#)$File: magic.c,v 1.78 2013/01/07 18:20:19 christos Exp $")
#endif /* lint */
#include "magic.h"
@ -110,6 +110,10 @@ get_default_magic(void)
if ((home = getenv("HOME")) == NULL)
return MAGIC;
if (asprintf(&hmagicpath, "%s/.magic.mgc", home) < 0)
return MAGIC;
if (stat(hmagicpath, &st) == -1) {
free(hmagicpath);
if (asprintf(&hmagicpath, "%s/.magic", home) < 0)
return MAGIC;
if (stat(hmagicpath, &st) == -1)
@ -121,6 +125,7 @@ get_default_magic(void)
if (access(hmagicpath, R_OK) == -1)
goto out;
}
}
if (asprintf(&default_magic, "%s:%s", hmagicpath, MAGIC) < 0)
goto out;
@ -221,46 +226,7 @@ magic_getpath(const char *magicfile, int action)
public struct magic_set *
magic_open(int flags)
{
struct magic_set *ms;
ms = ecalloc((size_t)1, sizeof(struct magic_set));
if (magic_setflags(ms, flags) == -1) {
errno = EINVAL;
goto free;
}
ms->o.buf = ms->o.pbuf = NULL;
ms->c.li = emalloc((ms->c.len = 10) * sizeof(*ms->c.li));
ms->event_flags = 0;
ms->error = -1;
ms->mlist = NULL;
ms->file = "unknown";
ms->line = 0;
return ms;
free:
efree(ms);
return NULL;
}
private void
free_mlist(struct mlist *mlist)
{
struct mlist *ml;
if (mlist == NULL)
return;
for (ml = mlist->next; ml != mlist;) {
struct mlist *next = ml->next;
struct magic *mg = ml->magic;
file_delmagic(mg, ml->mapped, ml->nmagic);
efree(ml);
ml = next;
}
efree(ml);
return file_ms_alloc(flags);
}
private int
@ -284,19 +250,9 @@ unreadable_info(struct magic_set *ms, mode_t md, const char *file)
public void
magic_close(struct magic_set *ms)
{
if (ms->mlist) {
free_mlist(ms->mlist);
}
if (ms->o.pbuf) {
efree(ms->o.pbuf);
}
if (ms->o.buf) {
efree(ms->o.buf);
}
if (ms->c.li) {
efree(ms->c.li);
}
efree(ms);
if (ms == NULL)
return;
file_ms_free(ms);
}
/*
@ -305,30 +261,26 @@ magic_close(struct magic_set *ms)
public int
magic_load(struct magic_set *ms, const char *magicfile)
{
struct mlist *ml = file_apprentice(ms, magicfile, FILE_LOAD);
if (ml) {
free_mlist(ms->mlist);
ms->mlist = ml;
return 0;
}
if (ms == NULL)
return -1;
return file_apprentice(ms, magicfile, FILE_LOAD);
}
public int
magic_compile(struct magic_set *ms, const char *magicfile)
{
struct mlist *ml = file_apprentice(ms, magicfile, FILE_COMPILE);
free_mlist(ml);
return ml ? 0 : -1;
if (ms == NULL)
return -1;
return file_apprentice(ms, magicfile, FILE_COMPILE);
}
public int
magic_list(struct magic_set *ms, const char *magicfile)
{
struct mlist *ml = file_apprentice(ms, magicfile, FILE_LIST);
free_mlist(ml);
return ml ? 0 : -1;
if (ms == NULL)
return -1;
return file_apprentice(ms, magicfile, FILE_LIST);
}
private void
@ -368,6 +320,8 @@ close_and_restore(const struct magic_set *ms, const char *name, int fd,
public const char *
magic_descriptor(struct magic_set *ms, int fd)
{
if (ms == NULL)
return NULL;
return file_or_stream(ms, NULL, NULL);
}
@ -377,12 +331,16 @@ magic_descriptor(struct magic_set *ms, int fd)
public const char *
magic_file(struct magic_set *ms, const char *inname)
{
if (ms == NULL)
return NULL;
return file_or_stream(ms, inname, NULL);
}
public const char *
magic_stream(struct magic_set *ms, php_stream *stream)
{
if (ms == NULL)
return NULL;
return file_or_stream(ms, NULL, stream);
}
@ -469,6 +427,8 @@ done:
public const char *
magic_buffer(struct magic_set *ms, const void *buf, size_t nb)
{
if (ms == NULL)
return NULL;
if (file_reset(ms) == -1)
return NULL;
/*
@ -484,18 +444,24 @@ magic_buffer(struct magic_set *ms, const void *buf, size_t nb)
public const char *
magic_error(struct magic_set *ms)
{
if (ms == NULL)
return "Magic database is not open";
return (ms->event_flags & EVENT_HAD_ERR) ? ms->o.buf : NULL;
}
public int
magic_errno(struct magic_set *ms)
{
if (ms == NULL)
return EINVAL;
return (ms->event_flags & EVENT_HAD_ERR) ? ms->error : 0;
}
public int
magic_setflags(struct magic_set *ms, int flags)
{
if (ms == NULL)
return -1;
#if !defined(HAVE_UTIME) && !defined(HAVE_UTIMES)
if (flags & MAGIC_PRESERVE_ATIME)
return -1;
@ -503,3 +469,9 @@ magic_setflags(struct magic_set *ms, int flags)
ms->flags = flags;
return 0;
}
public int
magic_version(void)
{
return MAGIC_VERSION;
}

View file

@ -74,6 +74,8 @@
#define MAGIC_NO_CHECK_FORTRAN 0x000000 /* Don't check ascii/fortran */
#define MAGIC_NO_CHECK_TROFF 0x000000 /* Don't check ascii/troff */
#define MAGIC_VERSION 514 /* This implementation */
#ifdef __cplusplus
extern "C" {
@ -92,6 +94,7 @@ const char *magic_buffer(magic_t, const void *, size_t);
const char *magic_error(magic_t);
int magic_setflags(magic_t, int);
int magic_version(void);
int magic_load(magic_t, const char *);
int magic_compile(magic_t, const char *);
int magic_list(magic_t, const char *);

View file

@ -1,11 +1,15 @@
#define FILE_VERSION_MAJOR 5
#define patchlevel 11
#define patchlevel 14
/*
* Patchlevel file for Ian Darwin's MAGIC command.
* $File: patchlevel.h,v 1.68 2008/03/22 21:39:43 christos Exp $
*
* $Log$
* Revision 1.7 2013/03/26 22:27:12 ab
* Update libmagic to 5.14
*
* $Log$
* Revision 1.6 2012/03/26 21:01:37 ab
* Update libmagic to 5.11
*

View file

@ -35,7 +35,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: print.c,v 1.71 2011/09/20 15:28:09 christos Exp $")
FILE_RCSID("@(#)$File: print.c,v 1.76 2013/02/26 18:25:00 christos Exp $")
#endif /* lint */
#include <stdio.h>
@ -47,6 +47,11 @@ FILE_RCSID("@(#)$File: print.c,v 1.71 2011/09/20 15:28:09 christos Exp $")
#endif
#include <time.h>
#ifdef PHP_WIN32
# define asctime_r php_asctime_r
# define ctime_r php_ctime_r
#endif
#define SZOF(a) (sizeof(a) / sizeof(a[0]))
/*VARARGS*/
@ -67,14 +72,20 @@ file_magwarn(struct magic_set *ms, const char *f, ...)
}
protected const char *
file_fmttime(uint32_t v, int local)
file_fmttime(uint64_t v, int flags, char *buf)
{
char *pp;
time_t t = (time_t)v;
struct tm *tm;
if (local) {
pp = ctime(&t);
if (flags & FILE_T_WINDOWS) {
struct timeval ts;
cdf_timestamp_to_timespec(&ts, t);
t = ts.tv_sec;
}
if (flags & FILE_T_LOCAL) {
pp = ctime_r(&t, buf);
} else {
#ifndef HAVE_DAYLIGHT
private int daylight = 0;
@ -96,7 +107,7 @@ file_fmttime(uint32_t v, int local)
tm = gmtime(&t);
if (tm == NULL)
goto out;
pp = asctime(tm);
pp = asctime_r(tm, buf);
}
if (pp == NULL)
@ -104,5 +115,5 @@ file_fmttime(uint32_t v, int local)
pp[strcspn(pp, "\n")] = '\0';
return pp;
out:
return "*Invalid time*";
return strcpy(buf, "*Invalid time*");
}

View file

@ -26,7 +26,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: readcdf.c,v 1.29 2012/02/20 20:04:58 christos Exp $")
FILE_RCSID("@(#)$File: readcdf.c,v 1.33 2012/06/20 21:52:36 christos Exp $")
#endif
#include <stdlib.h>
@ -129,12 +129,12 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
case CDF_FILETIME:
tp = info[i].pi_tp;
if (tp != 0) {
char tbuf[64];
#if defined(PHP_WIN32) && _MSC_VER <= 1500
if (tp < 1000000000000000i64) {
#else
if (tp < 1000000000000000LL) {
#endif
char tbuf[64];
cdf_print_elapsed_time(tbuf,
sizeof(tbuf), tp);
if (NOTMIME(ms) && file_printf(ms,
@ -145,7 +145,7 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info,
if (cdf_timestamp_to_timespec(&ts, tp) == -1) {
return -1;
}
c = cdf_ctime(&ts.tv_sec);
c = cdf_ctime(&ts.tv_sec, tbuf);
if ((ec = strchr(c, '\n')) != NULL)
*ec = '\0';
@ -295,10 +295,14 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
d = &dir.dir_tab[j];
for (k = 0; k < sizeof(name); k++)
name[k] = (char)cdf_tole2(d->d_name[k]);
if (strstr(name, "WordDocument") == 0) {
if (strstr(name, "WordDocument") != 0) {
str = "msword";
break;
}
if (strstr(name, "PowerPoint") != 0) {
str = "vnd.ms-powerpoint";
break;
}
}
if (file_printf(ms, "application/%s", str) == -1)
return -1;
@ -315,13 +319,19 @@ out1:
free(sat.sat_tab);
out0:
if (i != 1) {
if (i == -1)
if (file_printf(ms, "Composite Document File V2 Document")
== -1)
if (i == -1) {
if (NOTMIME(ms)) {
if (file_printf(ms,
"Composite Document File V2 Document") == -1)
return -1;
if (*expn)
if (file_printf(ms, ", %s%s", corrupt, expn) == -1)
return -1;
} else {
if (file_printf(ms, "application/CDFV2-corrupt") == -1)
return -1;
}
}
i = 1;
}
return i;

View file

@ -27,7 +27,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: readelf.c,v 1.90 2011/08/23 08:01:12 christos Exp $")
FILE_RCSID("@(#)$File: readelf.c,v 1.97 2013/03/06 03:35:30 christos Exp $")
#endif
#ifdef BUILTIN_ELF
@ -139,9 +139,9 @@ getu64(int swap, uint64_t value)
? (void *) &sh32 \
: (void *) &sh64)
#define xsh_sizeof (clazz == ELFCLASS32 \
? sizeof sh32 \
: sizeof sh64)
#define xsh_size (clazz == ELFCLASS32 \
? sizeof(sh32) \
: sizeof(sh64))
#define xsh_size (size_t)(clazz == ELFCLASS32 \
? elf_getu32(swap, sh32.sh_size) \
: elf_getu64(swap, sh64.sh_size))
#define xsh_offset (off_t)(clazz == ELFCLASS32 \
@ -150,12 +150,15 @@ getu64(int swap, uint64_t value)
#define xsh_type (clazz == ELFCLASS32 \
? elf_getu32(swap, sh32.sh_type) \
: elf_getu32(swap, sh64.sh_type))
#define xsh_name (clazz == ELFCLASS32 \
? elf_getu32(swap, sh32.sh_name) \
: elf_getu32(swap, sh64.sh_name))
#define xph_addr (clazz == ELFCLASS32 \
? (void *) &ph32 \
: (void *) &ph64)
#define xph_sizeof (clazz == ELFCLASS32 \
? sizeof ph32 \
: sizeof ph64)
? sizeof(ph32) \
: sizeof(ph64))
#define xph_type (clazz == ELFCLASS32 \
? elf_getu32(swap, ph32.p_type) \
: elf_getu32(swap, ph64.p_type))
@ -357,7 +360,7 @@ dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
#endif
private size_t
donote(struct magic_set *ms, unsigned char *nbuf, size_t offset, size_t size,
donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
int clazz, int swap, size_t align, int *flags)
{
Elf32_Nhdr nh32;
@ -367,6 +370,7 @@ donote(struct magic_set *ms, unsigned char *nbuf, size_t offset, size_t size,
int os_style = -1;
#endif
uint32_t namesz, descsz;
unsigned char *nbuf = CAST(unsigned char *, vbuf);
(void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
offset += xnh_sizeof;
@ -415,6 +419,10 @@ donote(struct magic_set *ms, unsigned char *nbuf, size_t offset, size_t size,
(FLAGS_DID_NOTE|FLAGS_DID_BUILD_ID))
goto core;
if (namesz == 5 && strcmp((char *)&nbuf[noff], "SuSE") == 0 &&
xnh_type == NT_GNU_VERSION && descsz == 2) {
file_printf(ms, ", for SuSE %d.%d", nbuf[doff], nbuf[doff + 1]);
}
if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
xnh_type == NT_GNU_VERSION && descsz == 16) {
uint32_t desc[4];
@ -456,13 +464,14 @@ donote(struct magic_set *ms, unsigned char *nbuf, size_t offset, size_t size,
if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
xnh_type == NT_GNU_BUILD_ID && (descsz == 16 || descsz == 20)) {
uint32_t desc[5], i;
if (file_printf(ms, ", BuildID[%s]=0x", descsz == 16 ? "md5/uuid" :
uint8_t desc[20];
uint32_t i;
if (file_printf(ms, ", BuildID[%s]=", descsz == 16 ? "md5/uuid" :
"sha1") == -1)
return size;
(void)memcpy(desc, &nbuf[doff], descsz);
for (i = 0; i < descsz >> 2; i++)
if (file_printf(ms, "%.8x", desc[i]) == -1)
for (i = 0; i < descsz; i++)
if (file_printf(ms, "%02x", desc[i]) == -1)
return size;
*flags |= FLAGS_DID_BUILD_ID;
}
@ -841,15 +850,16 @@ static const cap_desc_t cap_desc_386[] = {
private int
doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
size_t size, off_t fsize, int *flags, int mach)
size_t size, off_t fsize, int *flags, int mach, int strtab)
{
Elf32_Shdr sh32;
Elf64_Shdr sh64;
int stripped = 1;
void *nbuf;
off_t noff, coff;
off_t noff, coff, name_off;
uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */
uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilites */
char name[50];
if (size != xsh_sizeof) {
if (file_printf(ms, ", corrupted section header size") == -1)

View file

@ -32,7 +32,7 @@
#include "file.h"
#ifndef lint
FILE_RCSID("@(#)$File: softmagic.c,v 1.147 2011/11/05 15:44:22 rrt Exp $")
FILE_RCSID("@(#)$File: softmagic.c,v 1.165 2013/03/07 02:22:24 christos Exp $")
#endif /* lint */
#include "magic.h"
@ -48,16 +48,18 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.147 2011/11/05 15:44:22 rrt Exp $")
private int match(struct magic_set *, struct magic *, uint32_t,
const unsigned char *, size_t, int, int);
const unsigned char *, size_t, size_t, int, int, int, int, int *, int *,
int *);
private int mget(struct magic_set *, const unsigned char *,
struct magic *, size_t, unsigned int, int);
struct magic *, size_t, size_t, unsigned int, int, int, int, int, int *,
int *, int *);
private int magiccheck(struct magic_set *, struct magic *);
private int32_t mprint(struct magic_set *, struct magic *);
private int32_t moffset(struct magic_set *, struct magic *);
private void mdebug(uint32_t, const char *, size_t);
private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
const unsigned char *, uint32_t, size_t, size_t);
private int mconvert(struct magic_set *, struct magic *);
private int mconvert(struct magic_set *, struct magic *, int);
private int print_sep(struct magic_set *, int);
private int handle_annotation(struct magic_set *, struct magic *);
private void cvt_8(union VALUETYPE *, const struct magic *);
@ -75,10 +77,11 @@ file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes,
int mode, int text)
{
struct mlist *ml;
int rv;
for (ml = ms->mlist->next; ml != ms->mlist; ml = ml->next)
if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, mode,
text)) != 0)
int rv, printed_something = 0, need_separator = 0;
for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next)
if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, 0, mode,
text, 0, 0, &printed_something, &need_separator,
NULL)) != 0)
return rv;
return 0;
@ -113,16 +116,19 @@ file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes,
*/
private int
match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
const unsigned char *s, size_t nbytes, int mode, int text)
const unsigned char *s, size_t nbytes, size_t offset, int mode, int text,
int flip, int recursion_level, int *printed_something, int *need_separator,
int *returnval)
{
uint32_t magindex = 0;
unsigned int cont_level = 0;
int need_separator = 0;
int returnval = 0, e; /* if a match is found it is set to 1*/
int returnvalv = 0, e; /* if a match is found it is set to 1*/
int firstline = 1; /* a flag to print X\n X\n- X */
int printed_something = 0;
int print = (ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0;
if (returnval == NULL)
returnval = &returnvalv;
if (file_check_mem(ms, cont_level) == -1)
return -1;
@ -130,14 +136,17 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
int flush = 0;
struct magic *m = &magic[magindex];
if (m->type != FILE_NAME)
if ((IS_LIBMAGIC_STRING(m->type) &&
((text && (m->str_flags & (STRING_BINTEST | STRING_TEXTTEST)) == STRING_BINTEST) ||
(!text && (m->str_flags & (STRING_TEXTTEST | STRING_BINTEST)) == STRING_TEXTTEST))) ||
#define FLT (STRING_BINTEST | STRING_TEXTTEST)
((text && (m->str_flags & FLT) == STRING_BINTEST) ||
(!text && (m->str_flags & FLT) == STRING_TEXTTEST))) ||
(m->flag & mode) != mode) {
/* Skip sub-tests */
while (magindex < nmagic - 1 && magic[magindex + 1].cont_level != 0) {
magindex++;
}
while (magindex + 1 < nmagic &&
magic[magindex + 1].cont_level != 0 &&
++magindex)
continue;
continue; /* Skip to next top-level test*/
}
@ -145,7 +154,9 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
ms->line = m->lineno;
/* if main entry matches, print it... */
switch (mget(ms, s, m, nbytes, cont_level, text)) {
switch (mget(ms, s, m, nbytes, offset, cont_level, mode, text,
flip, recursion_level + 1, printed_something,
need_separator, returnval)) {
case -1:
return -1;
case 0:
@ -153,7 +164,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
break;
default:
if (m->type == FILE_INDIRECT)
returnval = 1;
*returnval = 1;
switch (magiccheck(ms, m)) {
case -1:
@ -172,21 +183,23 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
* main entry didn't match,
* flush its continuations
*/
while (magindex < nmagic - 1 && magic[magindex + 1].cont_level != 0) {
while (magindex < nmagic - 1 &&
magic[magindex + 1].cont_level != 0)
magindex++;
}
continue;
}
if ((e = handle_annotation(ms, m)) != 0)
if ((e = handle_annotation(ms, m)) != 0) {
*returnval = 1;
return e;
}
/*
* If we are going to print something, we'll need to print
* a blank before we print something else.
*/
if (*m->desc) {
need_separator = 1;
printed_something = 1;
*need_separator = 1;
*printed_something = 1;
if (print_sep(ms, firstline) == -1)
return -1;
}
@ -201,8 +214,8 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
if (file_check_mem(ms, ++cont_level) == -1)
return -1;
while (magindex < nmagic - 1 && magic[magindex + 1].cont_level != 0) {
magindex++;
while (magindex + 1 < nmagic && magic[magindex+1].cont_level != 0 &&
++magindex) {
m = &magic[magindex];
ms->line = m->lineno; /* for messages */
@ -217,7 +230,8 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
}
ms->offset = m->offset;
if (m->flag & OFFADD) {
ms->offset += ms->c.li[cont_level - 1].off;
ms->offset +=
ms->c.li[cont_level - 1].off;
}
#ifdef ENABLE_CONDITIONALS
@ -227,7 +241,9 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
continue;
}
#endif
switch (mget(ms, s, m, nbytes, cont_level, text)) {
switch (mget(ms, s, m, nbytes, offset, cont_level, mode,
text, flip, recursion_level + 1, printed_something,
need_separator, returnval)) {
case -1:
return -1;
case 0:
@ -237,7 +253,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
break;
default:
if (m->type == FILE_INDIRECT)
returnval = 1;
*returnval = 1;
flush = 0;
break;
}
@ -260,15 +276,17 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
ms->c.li[cont_level].got_match = 0;
break;
}
if ((e = handle_annotation(ms, m)) != 0)
if ((e = handle_annotation(ms, m)) != 0) {
*returnval = 1;
return e;
}
/*
* If we are going to print something,
* make sure that we have a separator first.
*/
if (*m->desc) {
if (!printed_something) {
printed_something = 1;
if (!*printed_something) {
*printed_something = 1;
if (print_sep(ms, firstline)
== -1)
return -1;
@ -281,13 +299,13 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
* this item isn't empty.
*/
/* space if previous printed */
if (need_separator
if (*need_separator
&& ((m->flag & NOSPACE) == 0)
&& *m->desc) {
if (print &&
file_printf(ms, " ") == -1)
return -1;
need_separator = 0;
*need_separator = 0;
}
if (print && mprint(ms, m) == -1)
return -1;
@ -295,7 +313,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
ms->c.li[cont_level].off = moffset(ms, m);
if (*m->desc)
need_separator = 1;
*need_separator = 1;
/*
* If we see any continuations
@ -307,16 +325,16 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
break;
}
}
if (printed_something) {
if (*printed_something) {
firstline = 0;
if (print)
returnval = 1;
*returnval = 1;
}
if ((ms->flags & MAGIC_CONTINUE) == 0 && printed_something) {
return returnval; /* don't keep searching */
if ((ms->flags & MAGIC_CONTINUE) == 0 && *printed_something) {
return *returnval; /* don't keep searching */
}
}
return returnval; /* This is hit if -k is set or there is no match */
return *returnval; /* This is hit if -k is set or there is no match */
}
private int
@ -345,7 +363,7 @@ mprint(struct magic_set *ms, struct magic *m)
float vf;
double vd;
int64_t t = 0;
char buf[128];
char buf[128], tbuf[26];
union VALUETYPE *p = &ms->ms_value;
switch (m->type) {
@ -430,11 +448,30 @@ mprint(struct magic_set *ms, struct magic *m)
t = ms->offset + m->vallen;
}
else {
char *str = p->s;
/* compute t before we mangle the string? */
t = ms->offset + strlen(str);
if (*m->value.s == '\0')
p->s[strcspn(p->s, "\n")] = '\0';
if (file_printf(ms, m->desc, p->s) == -1)
str[strcspn(str, "\n")] = '\0';
if (m->str_flags & STRING_TRIM) {
char *last;
while (isspace((unsigned char)*str))
str++;
last = str;
while (*last)
last++;
--last;
while (isspace((unsigned char)*last))
last--;
*++last = '\0';
}
if (file_printf(ms, m->desc, str) == -1)
return -1;
t = ms->offset + strlen(p->s);
if (m->type == FILE_PSTRING)
t += file_pstring_length_size(m);
}
@ -444,25 +481,26 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_BEDATE:
case FILE_LEDATE:
case FILE_MEDATE:
if (file_printf(ms, m->desc, file_fmttime(p->l, 1)) == -1)
if (file_printf(ms, m->desc, file_fmttime(p->l, FILE_T_LOCAL,
tbuf)) == -1)
return -1;
t = ms->offset + sizeof(time_t);
t = ms->offset + sizeof(uint32_t);
break;
case FILE_LDATE:
case FILE_BELDATE:
case FILE_LELDATE:
case FILE_MELDATE:
if (file_printf(ms, m->desc, file_fmttime(p->l, 0)) == -1)
if (file_printf(ms, m->desc, file_fmttime(p->l, 0, tbuf)) == -1)
return -1;
t = ms->offset + sizeof(time_t);
t = ms->offset + sizeof(uint32_t);
break;
case FILE_QDATE:
case FILE_BEQDATE:
case FILE_LEQDATE:
if (file_printf(ms, m->desc, file_fmttime((uint32_t)p->q,
1)) == -1)
if (file_printf(ms, m->desc, file_fmttime(p->q, FILE_T_LOCAL,
tbuf)) == -1)
return -1;
t = ms->offset + sizeof(uint64_t);
break;
@ -470,8 +508,16 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_QLDATE:
case FILE_BEQLDATE:
case FILE_LEQLDATE:
if (file_printf(ms, m->desc, file_fmttime((uint32_t)p->q,
0)) == -1)
if (file_printf(ms, m->desc, file_fmttime(p->q, 0, tbuf)) == -1)
return -1;
t = ms->offset + sizeof(uint64_t);
break;
case FILE_QWDATE:
case FILE_BEQWDATE:
case FILE_LEQWDATE:
if (file_printf(ms, m->desc, file_fmttime(p->q, FILE_T_WINDOWS,
tbuf)) == -1)
return -1;
t = ms->offset + sizeof(uint64_t);
break;
@ -521,7 +567,10 @@ mprint(struct magic_set *ms, struct magic *m)
int rval;
cp = estrndup((const char *)ms->search.s, ms->search.rm_len);
if (cp == NULL) {
file_oomem(ms, ms->search.rm_len);
return -1;
}
rval = file_printf(ms, m->desc, cp);
efree(cp);
@ -551,6 +600,8 @@ mprint(struct magic_set *ms, struct magic *m)
break;
case FILE_INDIRECT:
case FILE_USE:
case FILE_NAME:
t = ms->offset;
break;
@ -598,7 +649,7 @@ moffset(struct magic_set *ms, struct magic *m)
p->s[strcspn(p->s, "\n")] = '\0';
t = CAST(uint32_t, (ms->offset + strlen(p->s)));
if (m->type == FILE_PSTRING)
t += file_pstring_length_size(m);
t += (uint32_t)file_pstring_length_size(m);
return t;
}
@ -606,13 +657,13 @@ moffset(struct magic_set *ms, struct magic *m)
case FILE_BEDATE:
case FILE_LEDATE:
case FILE_MEDATE:
return CAST(int32_t, (ms->offset + sizeof(time_t)));
return CAST(int32_t, (ms->offset + sizeof(uint32_t)));
case FILE_LDATE:
case FILE_BELDATE:
case FILE_LELDATE:
case FILE_MELDATE:
return CAST(int32_t, (ms->offset + sizeof(time_t)));
return CAST(int32_t, (ms->offset + sizeof(uint32_t)));
case FILE_QDATE:
case FILE_BEQDATE:
@ -658,6 +709,56 @@ moffset(struct magic_set *ms, struct magic *m)
}
}
private int
cvt_flip(int type, int flip)
{
if (flip == 0)
return type;
switch (type) {
case FILE_BESHORT:
return FILE_LESHORT;
case FILE_BELONG:
return FILE_LELONG;
case FILE_BEDATE:
return FILE_LEDATE;
case FILE_BELDATE:
return FILE_LELDATE;
case FILE_BEQUAD:
return FILE_LEQUAD;
case FILE_BEQDATE:
return FILE_LEQDATE;
case FILE_BEQLDATE:
return FILE_LEQLDATE;
case FILE_BEQWDATE:
return FILE_LEQWDATE;
case FILE_LESHORT:
return FILE_BESHORT;
case FILE_LELONG:
return FILE_BELONG;
case FILE_LEDATE:
return FILE_BEDATE;
case FILE_LELDATE:
return FILE_BELDATE;
case FILE_LEQUAD:
return FILE_BEQUAD;
case FILE_LEQDATE:
return FILE_BEQDATE;
case FILE_LEQLDATE:
return FILE_BEQLDATE;
case FILE_LEQWDATE:
return FILE_BEQWDATE;
case FILE_BEFLOAT:
return FILE_LEFLOAT;
case FILE_LEFLOAT:
return FILE_BEFLOAT;
case FILE_BEDOUBLE:
return FILE_LEDOUBLE;
case FILE_LEDOUBLE:
return FILE_BEDOUBLE;
default:
return type;
}
}
#define DO_CVT(fld, cast) \
if (m->num_mask) \
switch (m->mask_op & FILE_OPS_MASK) { \
@ -748,11 +849,11 @@ cvt_double(union VALUETYPE *p, const struct magic *m)
* (unless you have a better idea)
*/
private int
mconvert(struct magic_set *ms, struct magic *m)
mconvert(struct magic_set *ms, struct magic *m, int flip)
{
union VALUETYPE *p = &ms->ms_value;
switch (m->type) {
switch (cvt_flip(m->type, flip)) {
case FILE_BYTE:
cvt_8(p, m);
return 1;
@ -767,6 +868,7 @@ mconvert(struct magic_set *ms, struct magic *m)
case FILE_QUAD:
case FILE_QDATE:
case FILE_QLDATE:
case FILE_QWDATE:
cvt_64(p, m);
return 1;
case FILE_STRING:
@ -800,6 +902,7 @@ mconvert(struct magic_set *ms, struct magic *m)
case FILE_BEQUAD:
case FILE_BEQDATE:
case FILE_BEQLDATE:
case FILE_BEQWDATE:
p->q = (uint64_t)
(((uint64_t)p->hq[0]<<56)|((uint64_t)p->hq[1]<<48)|
((uint64_t)p->hq[2]<<40)|((uint64_t)p->hq[3]<<32)|
@ -821,6 +924,7 @@ mconvert(struct magic_set *ms, struct magic *m)
case FILE_LEQUAD:
case FILE_LEQDATE:
case FILE_LEQLDATE:
case FILE_LEQWDATE:
p->q = (uint64_t)
(((uint64_t)p->hq[7]<<56)|((uint64_t)p->hq[6]<<48)|
((uint64_t)p->hq[5]<<40)|((uint64_t)p->hq[4]<<32)|
@ -868,6 +972,8 @@ mconvert(struct magic_set *ms, struct magic *m)
case FILE_REGEX:
case FILE_SEARCH:
case FILE_DEFAULT:
case FILE_NAME:
case FILE_USE:
return 1;
default:
file_magerror(ms, "invalid type %d in mconvert()", m->type);
@ -879,7 +985,7 @@ mconvert(struct magic_set *ms, struct magic *m)
private void
mdebug(uint32_t offset, const char *str, size_t len)
{
(void) fprintf(stderr, "mget @%d: ", offset);
(void) fprintf(stderr, "mget/%zu @%d: ", len, offset);
file_showstr(stderr, str, len);
(void) fputc('\n', stderr);
(void) fputc('\n', stderr);
@ -946,8 +1052,8 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
if (type == FILE_BESTRING16)
src++;
/* check for pointer overflow */
if (src < s) {
/* check that offset is within range */
if (offset >= nbytes) {
file_magerror(ms, "invalid offset %u in mcopy()",
offset);
return -1;
@ -996,26 +1102,40 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
}
private int
mget(struct magic_set *ms, const unsigned char *s,
struct magic *m, size_t nbytes, unsigned int cont_level, int text)
mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
size_t nbytes, size_t o, unsigned int cont_level, int mode, int text,
int flip, int recursion_level, int *printed_something,
int *need_separator, int *returnval)
{
uint32_t offset = ms->offset;
uint32_t soffset, offset = ms->offset;
uint32_t count = m->str_range;
int rv, oneed_separator;
char *sbuf, *rbuf;
union VALUETYPE *p = &ms->ms_value;
struct mlist ml;
if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, nbytes, count) == -1)
if (recursion_level >= 20) {
file_error(ms, 0, "recursion nesting exceeded");
return -1;
}
if (mcopy(ms, p, m->type, m->flag & INDIR, s, (uint32_t)(offset + o),
(uint32_t)nbytes, count) == -1)
return -1;
if ((ms->flags & MAGIC_DEBUG) != 0) {
fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%zu, "
"nbytes=%zu, count=%u)\n", m->type, m->flag, offset, o,
nbytes, count);
mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
}
if (m->flag & INDIR) {
int off = m->in_offset;
if (m->in_op & FILE_OPINDIRECT) {
const union VALUETYPE *q =
((const void *)(s + offset + off));
switch (m->in_type) {
const union VALUETYPE *q = CAST(const union VALUETYPE *,
((const void *)(s + offset + off)));
switch (cvt_flip(m->in_type, flip)) {
case FILE_BYTE:
off = q->b;
break;
@ -1046,8 +1166,10 @@ mget(struct magic_set *ms, const unsigned char *s,
(q->hl[3]<<8)|(q->hl[2]));
break;
}
if ((ms->flags & MAGIC_DEBUG) != 0)
fprintf(stderr, "indirect offs=%u\n", off);
}
switch (m->in_type) {
switch (cvt_flip(m->in_type, flip)) {
case FILE_BYTE:
if (nbytes < (offset + 1))
return 0;
@ -1472,7 +1594,7 @@ mget(struct magic_set *ms, const unsigned char *s,
break;
}
switch (m->in_type) {
switch (cvt_flip(m->in_type, flip)) {
case FILE_LEID3:
case FILE_BEID3:
offset = ((((offset >> 0) & 0x7f) << 0) |
@ -1486,6 +1608,14 @@ mget(struct magic_set *ms, const unsigned char *s,
if (m->flag & INDIROFFADD) {
offset += ms->c.li[cont_level-1].off;
if (offset == 0) {
if ((ms->flags & MAGIC_DEBUG) != 0)
fprintf(stderr,
"indirect *zero* offset\n");
return 0;
}
if ((ms->flags & MAGIC_DEBUG) != 0)
fprintf(stderr, "indirect +offs=%u\n", offset);
}
if (mcopy(ms, p, m->type, 0, s, offset, nbytes, count) == -1)
return -1;
@ -1550,19 +1680,61 @@ mget(struct magic_set *ms, const unsigned char *s,
break;
case FILE_INDIRECT:
if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
file_printf(ms, "%s", m->desc) == -1)
return -1;
if (nbytes < offset)
return 0;
return file_softmagic(ms, s + offset, nbytes - offset,
sbuf = ms->o.buf;
soffset = ms->offset;
ms->o.buf = NULL;
ms->offset = 0;
rv = file_softmagic(ms, s + offset, nbytes - offset,
BINTEST, text);
if ((ms->flags & MAGIC_DEBUG) != 0)
fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
rbuf = ms->o.buf;
ms->o.buf = sbuf;
ms->offset = soffset;
if (rv == 1) {
if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
file_printf(ms, m->desc, offset) == -1)
return -1;
if (file_printf(ms, "%s", rbuf) == -1)
return -1;
free(rbuf);
}
return rv;
case FILE_USE:
if (nbytes < offset)
return 0;
sbuf = m->value.s;
if (*sbuf == '^') {
sbuf++;
flip = !flip;
}
if (file_magicfind(ms, sbuf, &ml) == -1) {
file_error(ms, 0, "cannot find entry `%s'", sbuf);
return -1;
}
oneed_separator = *need_separator;
if (m->flag & NOSPACE)
*need_separator = 0;
rv = match(ms, ml.magic, ml.nmagic, s, nbytes, offset + o,
mode, text, flip, recursion_level, printed_something,
need_separator, returnval);
if (rv != 1)
*need_separator = oneed_separator;
return rv;
case FILE_NAME:
if (file_printf(ms, "%s", m->desc) == -1)
return -1;
return 1;
case FILE_DEFAULT: /* nothing to check */
default:
break;
}
if (!mconvert(ms, m))
if (!mconvert(ms, m, flip))
return 0;
return 1;
}
@ -1723,6 +1895,9 @@ magiccheck(struct magic_set *ms, struct magic *m)
case FILE_QLDATE:
case FILE_BEQLDATE:
case FILE_LEQLDATE:
case FILE_QWDATE:
case FILE_BEQWDATE:
case FILE_LEQWDATE:
v = p->q;
break;
@ -1851,11 +2026,7 @@ magiccheck(struct magic_set *ms, struct magic *m)
convert_libmagic_pattern(pattern, options);
l = v = 0;
#if (PHP_MAJOR_VERSION < 6)
if ((pce = pcre_get_compiled_regex_cache(Z_STRVAL_P(pattern), Z_STRLEN_P(pattern) TSRMLS_CC)) == NULL) {
#else
if ((pce = pcre_get_compiled_regex_cache(IS_STRING, Z_STRVAL_P(pattern), Z_STRLEN_P(pattern) TSRMLS_CC)) == NULL) {
#endif
zval_dtor(pattern);
FREE_ZVAL(pattern);
return -1;
@ -1872,11 +2043,7 @@ magiccheck(struct magic_set *ms, struct magic *m)
haystack = estrndup(ms->search.s, ms->search.s_len);
/* match v = 0, no match v = 1 */
#if (PHP_MAJOR_VERSION < 6)
php_pcre_match_impl(pce, haystack, ms->search.s_len, retval, subpats, 1, 1, PREG_OFFSET_CAPTURE, 0 TSRMLS_CC);
#else
php_pcre_match_impl(pce, IS_STRING, haystack, ms->search.s_len, retval, subpats, 1, 1, PREG_OFFSET_CAPTURE, 0 TSRMLS_CC);
#endif
/* Free haystack */
efree(haystack);
@ -1990,6 +2157,8 @@ magiccheck(struct magic_set *ms, struct magic *m)
break;
}
case FILE_INDIRECT:
case FILE_USE:
case FILE_NAME:
return 1;
default:
file_magerror(ms, "invalid type %d in magiccheck()", m->type);

View file

@ -26,5 +26,5 @@ var_dump( finfo_file( $finfo, $magicFile ) );
*** Testing finfo_file() : basic functionality ***
string(28) "text/x-php; charset=us-ascii"
string(22) "PHP script, ASCII text"
string(32) "text/plain; charset=unknown-8bit"
string(25) "text/plain; charset=utf-8"
===DONE===

View file

@ -27,25 +27,25 @@ var_dump( new finfo('foobar') );
--EXPECTF--
*** Testing finfo_open() : error functionality ***
Warning: finfo_open(%sfoobarfile): failed to open stream: No such file or directory in %s on line %d
Warning: finfo_open(%sfoobarfile): failed to open stream: No such file or directory in %sfinfo_open_error.php on line 12
Warning: finfo_open(%sfoobarfile): failed to open stream: No such file or directory in %s on line %d
Warning: finfo_open(%sfoobarfile): failed to open stream: No such file or directory in %sfinfo_open_error.php on line 12
Warning: finfo_open(): Failed to load magic database at '%sfoobarfile'. in %s on line %d
Warning: finfo_open(): Failed to load magic database at '%sfoobarfile'. in %sfinfo_open_error.php on line 12
bool(false)
Warning: finfo_open() expects parameter 1 to be long, array given in %s on line %d
Warning: finfo_open() expects parameter 1 to be long, array given in %sfinfo_open_error.php on line 13
bool(false)
Warning: finfo_open() expects at most 2 parameters, 3 given in %s on line %d
Warning: finfo_open() expects at most 2 parameters, 3 given in %sfinfo_open_error.php on line 14
bool(false)
Notice: finfo_open(): Warning: using regular magic file `%s' in %s on line %d
resource(%d) of type (file_info)
Notice: finfo_open(): Warning: using regular magic file `%smagic' in %sfinfo_open_error.php on line 15
resource(6) of type (file_info)
Warning: finfo_open() expects parameter 1 to be long, string given in %s on line %d
Warning: finfo_open() expects parameter 1 to be long, string given in %sfinfo_open_error.php on line 16
bool(false)
Warning: finfo::finfo() expects parameter 1 to be long, string given in %s on line %d
Warning: finfo::finfo() expects parameter 1 to be long, string given in %sfinfo_open_error.php on line 18
NULL
===DONE===

File diff suppressed because it is too large Load diff