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: - CURL:
. Add CURL_WRAPPERS_ENABLED constant. (Laruence) . Add CURL_WRAPPERS_ENABLED constant. (Laruence)
- Fileinfo:
. Upgraded libmagic to 5.14. (Anatol)
?? ??? 2013, PHP 5.4.14 ?? ??? 2013, PHP 5.4.14
- Core: - Core:
. Fixed bug #64529 (Ran out of opcode space). (Dmitry) . 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" #include "file.h"
#ifndef lint #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 */ #endif /* lint */
#include "magic.h" #include "magic.h"
@ -134,13 +134,15 @@ file_ascmagic_with_encoding(struct magic_set *ms, const unsigned char *buf,
goto done; 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 */ /* Convert ubuf to UTF-8 and try text soft magic */
/* malloc size is a conservative overestimate; could be /* malloc size is a conservative overestimate; could be
improved, or at least realloced after conversion. */ improved, or at least realloced after conversion. */
mlen = ulen * 6; 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)) if ((utf8_end = encode_utf8(utf8_buf, mlen, ubuf, ulen))
== NULL) == NULL)
goto done; goto done;
@ -209,6 +211,7 @@ file_ascmagic_with_encoding(struct magic_set *ms, const unsigned char *buf,
case 0: case 0:
if (file_printf(ms, ", ") == -1) if (file_printf(ms, ", ") == -1)
goto done; goto done;
break;
case -1: case -1:
goto done; goto done;
default: default:

View file

@ -35,7 +35,7 @@
#include "file.h" #include "file.h"
#ifndef lint #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 #endif
#include <assert.h> #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 *b = (const char *)sst->sst_tab;
const char *e = ((const char *)p) + tail; const char *e = ((const char *)p) + tail;
(void)&line; (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; return 0;
DPRINTF(("%d: offset begin %p end %p %" 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 [%" SIZE_T_FORMAT "u %"
SIZE_T_FORMAT "u]\n", line, b, e, (size_t)(e - b), 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)); CDF_SEC_SIZE(h) * sst->sst_len, CDF_SEC_SIZE(h), sst->sst_len));
errno = EFTYPE; errno = EFTYPE;

View file

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

View file

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

View file

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

View file

@ -59,7 +59,8 @@
(off_t)elf_getu(swap, elfhdr.e_shoff), (off_t)elf_getu(swap, elfhdr.e_shoff),
elf_getu16(swap, elfhdr.e_shnum), elf_getu16(swap, elfhdr.e_shnum),
(size_t)elf_getu16(swap, elfhdr.e_shentsize), (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; return -1;
break; break;

View file

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

View file

@ -32,7 +32,7 @@
#include "file.h" #include "file.h"
#ifndef lint #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 */ #endif /* lint */
#include "magic.h" #include "magic.h"
@ -92,16 +92,19 @@ handle_mime(struct magic_set *ms, int mime, const char *str)
protected int protected int
file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb, php_stream *stream) 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; int mime = ms->flags & MAGIC_MIME;
TSRMLS_FETCH(); TSRMLS_FETCH();
if (ms->flags & MAGIC_APPLE) if (ms->flags & MAGIC_APPLE)
return 0; return 0;
if (!fn && !stream) { if (fn == NULL && !stream) {
return 0; return 0;
} }
#define COMMA (did++ ? ", " : "")
if (stream) { if (stream) {
php_stream_statbuf ssb; php_stream_statbuf ssb;
if (php_stream_stat(stream, &ssb) < 0) { 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) { if (!mime) {
#ifdef S_ISUID #ifdef S_ISUID
if (sb->st_mode & S_ISUID) if (sb->st_mode & S_ISUID)
if (file_printf(ms, "setuid ") == -1) if (file_printf(ms, "%ssetuid", COMMA) == -1)
return -1; return -1;
#endif #endif
#ifdef S_ISGID #ifdef S_ISGID
if (sb->st_mode & S_ISGID) if (sb->st_mode & S_ISGID)
if (file_printf(ms, "setgid ") == -1) if (file_printf(ms, "%ssetgid", COMMA) == -1)
return -1; return -1;
#endif #endif
#ifdef S_ISVTX #ifdef S_ISVTX
if (sb->st_mode & S_ISVTX) if (sb->st_mode & S_ISVTX)
if (file_printf(ms, "sticky ") == -1) if (file_printf(ms, "%ssticky", COMMA) == -1)
return -1; return -1;
#endif #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. * are block special files and go on to the next file.
*/ */
if ((ms->flags & MAGIC_DEVICES) != 0) { if ((ms->flags & MAGIC_DEVICES) != 0) {
ret = 0;
break; break;
} }
if (mime) { if (mime) {
@ -158,18 +163,18 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb, php_stream *
} else { } else {
# ifdef HAVE_STAT_ST_RDEV # ifdef HAVE_STAT_ST_RDEV
# ifdef dv_unit # ifdef dv_unit
if (file_printf(ms, "character special (%d/%d/%d)", if (file_printf(ms, "%scharacter special (%d/%d/%d)",
major(sb->st_rdev), dv_unit(sb->st_rdev), COMMA, major(sb->st_rdev), dv_unit(sb->st_rdev),
dv_subunit(sb->st_rdev)) == -1) dv_subunit(sb->st_rdev)) == -1)
return -1; return -1;
# else # else
if (file_printf(ms, "character special (%ld/%ld)", if (file_printf(ms, "%scharacter special (%ld/%ld)",
(long)major(sb->st_rdev), (long)minor(sb->st_rdev)) COMMA, (long)major(sb->st_rdev),
== -1) (long)minor(sb->st_rdev)) == -1)
return -1; return -1;
# endif # endif
# else # else
if (file_printf(ms, "character special") == -1) if (file_printf(ms, "%scharacter special", COMMA) == -1)
return -1; return -1;
# endif # endif
} }
@ -184,18 +189,18 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb, php_stream *
if (mime) { if (mime) {
if (handle_mime(ms, mime, "fifo") == -1) if (handle_mime(ms, mime, "fifo") == -1)
return -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;
return 1; break;
#endif #endif
#ifdef S_IFDOOR #ifdef S_IFDOOR
case S_IFDOOR: case S_IFDOOR:
if (mime) { if (mime) {
if (handle_mime(ms, mime, "door") == -1) if (handle_mime(ms, mime, "door") == -1)
return -1; return -1;
} else if (file_printf(ms, "door") == -1) } else if (file_printf(ms, "%sdoor", COMMA) == -1)
return -1; return -1;
return 1; break;
#endif #endif
#ifdef S_IFLNK #ifdef S_IFLNK
case 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 (mime) {
if (handle_mime(ms, mime, "socket") == -1) if (handle_mime(ms, mime, "socket") == -1)
return -1; return -1;
} else if (file_printf(ms, "socket") == -1) } else if (file_printf(ms, "%ssocket", COMMA) == -1)
return -1; return -1;
return 1; break;
#endif #endif
#endif #endif
case S_IFREG: case S_IFREG:
break;
default:
file_error(ms, 0, "invalid mode 0%o", sb->st_mode);
return -1;
/*NOTREACHED*/
}
/* /*
* regular file, check next possibility * regular file, check next possibility
* *
* If stat() tells us the file has zero length, report here that * 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 * the file is empty, so we can skip all the work of opening and
* reading the file. * reading the file.
* But if the -s option has been given, we skip this optimization, * But if the -s option has been given, we skip this
* since on some systems, stat() reports zero size for raw disk * optimization, since on some systems, stat() reports zero
* partitions. (If the block special device really has zero length, * size for raw disk partitions. (If the block special device
* the fact that it is empty will be detected and reported correctly * really has zero length, the fact that it is empty will be
* when we read the file.) * detected and reported correctly when we read the file.)
*/ */
if ((ms->flags & MAGIC_DEVICES) == 0 && sb->st_size == 0) { if ((ms->flags & MAGIC_DEVICES) == 0 && sb->st_size == 0) {
if (mime) { if (mime) {
if (handle_mime(ms, mime, "x-empty") == -1) if (handle_mime(ms, mime, "x-empty") == -1)
return -1; return -1;
} else if (file_printf(ms, "empty") == -1) } else if (file_printf(ms, "%sempty", COMMA) == -1)
return -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" #include "file.h"
#ifndef lint #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 */ #endif /* lint */
#include "magic.h" #include "magic.h"
@ -191,7 +191,7 @@ file_buffer(struct magic_set *ms, php_stream *stream, const char *inname, const
&code, &code_mime, &type); &code, &code_mime, &type);
} }
#if defined(__EMX__) #ifdef __EMX__
if ((ms->flags & MAGIC_NO_CHECK_APPTYPE) == 0 && inname) { if ((ms->flags & MAGIC_NO_CHECK_APPTYPE) == 0 && inname) {
switch (file_os2_apptype(ms, inname, buf, nb)) { switch (file_os2_apptype(ms, inname, buf, nb)) {
case -1: case -1:
@ -307,7 +307,7 @@ file_buffer(struct magic_set *ms, php_stream *stream, const char *inname, const
protected int protected int
file_reset(struct magic_set *ms) file_reset(struct magic_set *ms)
{ {
if (ms->mlist == NULL) { if (ms->mlist[0] == NULL) {
file_error(ms, 0, "no magic files loaded"); file_error(ms, 0, "no magic files loaded");
return -1; return -1;
} }
@ -335,7 +335,7 @@ file_reset(struct magic_set *ms)
protected const char * protected const char *
file_getbuffer(struct magic_set *ms) file_getbuffer(struct magic_set *ms)
{ {
char *pbuf, *op, *np; char *op, *np;
size_t psize, len; size_t psize, len;
if (ms->event_flags & EVENT_HAD_ERR) if (ms->event_flags & EVENT_HAD_ERR)
@ -353,8 +353,10 @@ file_getbuffer(struct magic_set *ms)
return NULL; return NULL;
} }
psize = len * 4 + 1; psize = len * 4 + 1;
pbuf = erealloc(ms->o.pbuf, psize); if ((ms->o.pbuf = CAST(char *, erealloc(ms->o.pbuf, psize))) == NULL) {
ms->o.pbuf = pbuf; file_oomem(ms, psize);
return NULL;
}
#if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH) #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) { if (level >= ms->c.len) {
len = (ms->c.len += 20) * sizeof(*ms->c.li); 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; ms->c.li[level].got_match = 0;
#ifdef ENABLE_CONDITIONALS #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); ZVAL_STRINGL(patt, pat, strlen(pat), 0);
opts |= PCRE_MULTILINE; opts |= PCRE_MULTILINE;
convert_libmagic_pattern(patt, opts); 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) { 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); zval_dtor(patt);
FREE_ZVAL(patt); FREE_ZVAL(patt);
return -1; return -1;

View file

@ -28,7 +28,7 @@
#include "file.h" #include "file.h"
#ifndef lint #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 */ #endif /* lint */
#include "magic.h" #include "magic.h"
@ -110,6 +110,10 @@ get_default_magic(void)
if ((home = getenv("HOME")) == NULL) if ((home = getenv("HOME")) == NULL)
return MAGIC; 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) if (asprintf(&hmagicpath, "%s/.magic", home) < 0)
return MAGIC; return MAGIC;
if (stat(hmagicpath, &st) == -1) if (stat(hmagicpath, &st) == -1)
@ -121,6 +125,7 @@ get_default_magic(void)
if (access(hmagicpath, R_OK) == -1) if (access(hmagicpath, R_OK) == -1)
goto out; goto out;
} }
}
if (asprintf(&default_magic, "%s:%s", hmagicpath, MAGIC) < 0) if (asprintf(&default_magic, "%s:%s", hmagicpath, MAGIC) < 0)
goto out; goto out;
@ -221,46 +226,7 @@ magic_getpath(const char *magicfile, int action)
public struct magic_set * public struct magic_set *
magic_open(int flags) magic_open(int flags)
{ {
struct magic_set *ms; return file_ms_alloc(flags);
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);
} }
private int private int
@ -284,19 +250,9 @@ unreadable_info(struct magic_set *ms, mode_t md, const char *file)
public void public void
magic_close(struct magic_set *ms) magic_close(struct magic_set *ms)
{ {
if (ms->mlist) { if (ms == NULL)
free_mlist(ms->mlist); return;
} file_ms_free(ms);
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);
} }
/* /*
@ -305,30 +261,26 @@ magic_close(struct magic_set *ms)
public int public int
magic_load(struct magic_set *ms, const char *magicfile) magic_load(struct magic_set *ms, const char *magicfile)
{ {
struct mlist *ml = file_apprentice(ms, magicfile, FILE_LOAD); if (ms == NULL)
if (ml) {
free_mlist(ms->mlist);
ms->mlist = ml;
return 0;
}
return -1; return -1;
return file_apprentice(ms, magicfile, FILE_LOAD);
} }
public int public int
magic_compile(struct magic_set *ms, const char *magicfile) magic_compile(struct magic_set *ms, const char *magicfile)
{ {
struct mlist *ml = file_apprentice(ms, magicfile, FILE_COMPILE); if (ms == NULL)
free_mlist(ml); return -1;
return ml ? 0 : -1; return file_apprentice(ms, magicfile, FILE_COMPILE);
} }
public int public int
magic_list(struct magic_set *ms, const char *magicfile) magic_list(struct magic_set *ms, const char *magicfile)
{ {
struct mlist *ml = file_apprentice(ms, magicfile, FILE_LIST); if (ms == NULL)
free_mlist(ml); return -1;
return ml ? 0 : -1; return file_apprentice(ms, magicfile, FILE_LIST);
} }
private void private void
@ -368,6 +320,8 @@ close_and_restore(const struct magic_set *ms, const char *name, int fd,
public const char * public const char *
magic_descriptor(struct magic_set *ms, int fd) magic_descriptor(struct magic_set *ms, int fd)
{ {
if (ms == NULL)
return NULL;
return file_or_stream(ms, NULL, NULL); return file_or_stream(ms, NULL, NULL);
} }
@ -377,12 +331,16 @@ magic_descriptor(struct magic_set *ms, int fd)
public const char * public const char *
magic_file(struct magic_set *ms, const char *inname) magic_file(struct magic_set *ms, const char *inname)
{ {
if (ms == NULL)
return NULL;
return file_or_stream(ms, inname, NULL); return file_or_stream(ms, inname, NULL);
} }
public const char * public const char *
magic_stream(struct magic_set *ms, php_stream *stream) magic_stream(struct magic_set *ms, php_stream *stream)
{ {
if (ms == NULL)
return NULL;
return file_or_stream(ms, NULL, stream); return file_or_stream(ms, NULL, stream);
} }
@ -469,6 +427,8 @@ done:
public const char * public const char *
magic_buffer(struct magic_set *ms, const void *buf, size_t nb) magic_buffer(struct magic_set *ms, const void *buf, size_t nb)
{ {
if (ms == NULL)
return NULL;
if (file_reset(ms) == -1) if (file_reset(ms) == -1)
return NULL; return NULL;
/* /*
@ -484,18 +444,24 @@ magic_buffer(struct magic_set *ms, const void *buf, size_t nb)
public const char * public const char *
magic_error(struct magic_set *ms) 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; return (ms->event_flags & EVENT_HAD_ERR) ? ms->o.buf : NULL;
} }
public int public int
magic_errno(struct magic_set *ms) magic_errno(struct magic_set *ms)
{ {
if (ms == NULL)
return EINVAL;
return (ms->event_flags & EVENT_HAD_ERR) ? ms->error : 0; return (ms->event_flags & EVENT_HAD_ERR) ? ms->error : 0;
} }
public int public int
magic_setflags(struct magic_set *ms, int flags) magic_setflags(struct magic_set *ms, int flags)
{ {
if (ms == NULL)
return -1;
#if !defined(HAVE_UTIME) && !defined(HAVE_UTIMES) #if !defined(HAVE_UTIME) && !defined(HAVE_UTIMES)
if (flags & MAGIC_PRESERVE_ATIME) if (flags & MAGIC_PRESERVE_ATIME)
return -1; return -1;
@ -503,3 +469,9 @@ magic_setflags(struct magic_set *ms, int flags)
ms->flags = flags; ms->flags = flags;
return 0; 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_FORTRAN 0x000000 /* Don't check ascii/fortran */
#define MAGIC_NO_CHECK_TROFF 0x000000 /* Don't check ascii/troff */ #define MAGIC_NO_CHECK_TROFF 0x000000 /* Don't check ascii/troff */
#define MAGIC_VERSION 514 /* This implementation */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -92,6 +94,7 @@ const char *magic_buffer(magic_t, const void *, size_t);
const char *magic_error(magic_t); const char *magic_error(magic_t);
int magic_setflags(magic_t, int); int magic_setflags(magic_t, int);
int magic_version(void);
int magic_load(magic_t, const char *); int magic_load(magic_t, const char *);
int magic_compile(magic_t, const char *); int magic_compile(magic_t, const char *);
int magic_list(magic_t, const char *); int magic_list(magic_t, const char *);

View file

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

View file

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

View file

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

View file

@ -27,7 +27,7 @@
#include "file.h" #include "file.h"
#ifndef lint #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 #endif
#ifdef BUILTIN_ELF #ifdef BUILTIN_ELF
@ -139,9 +139,9 @@ getu64(int swap, uint64_t value)
? (void *) &sh32 \ ? (void *) &sh32 \
: (void *) &sh64) : (void *) &sh64)
#define xsh_sizeof (clazz == ELFCLASS32 \ #define xsh_sizeof (clazz == ELFCLASS32 \
? sizeof sh32 \ ? sizeof(sh32) \
: sizeof sh64) : sizeof(sh64))
#define xsh_size (clazz == ELFCLASS32 \ #define xsh_size (size_t)(clazz == ELFCLASS32 \
? elf_getu32(swap, sh32.sh_size) \ ? elf_getu32(swap, sh32.sh_size) \
: elf_getu64(swap, sh64.sh_size)) : elf_getu64(swap, sh64.sh_size))
#define xsh_offset (off_t)(clazz == ELFCLASS32 \ #define xsh_offset (off_t)(clazz == ELFCLASS32 \
@ -150,12 +150,15 @@ getu64(int swap, uint64_t value)
#define xsh_type (clazz == ELFCLASS32 \ #define xsh_type (clazz == ELFCLASS32 \
? elf_getu32(swap, sh32.sh_type) \ ? elf_getu32(swap, sh32.sh_type) \
: elf_getu32(swap, sh64.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 \ #define xph_addr (clazz == ELFCLASS32 \
? (void *) &ph32 \ ? (void *) &ph32 \
: (void *) &ph64) : (void *) &ph64)
#define xph_sizeof (clazz == ELFCLASS32 \ #define xph_sizeof (clazz == ELFCLASS32 \
? sizeof ph32 \ ? sizeof(ph32) \
: sizeof ph64) : sizeof(ph64))
#define xph_type (clazz == ELFCLASS32 \ #define xph_type (clazz == ELFCLASS32 \
? elf_getu32(swap, ph32.p_type) \ ? elf_getu32(swap, ph32.p_type) \
: elf_getu32(swap, ph64.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 #endif
private size_t 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) int clazz, int swap, size_t align, int *flags)
{ {
Elf32_Nhdr nh32; 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; int os_style = -1;
#endif #endif
uint32_t namesz, descsz; uint32_t namesz, descsz;
unsigned char *nbuf = CAST(unsigned char *, vbuf);
(void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof); (void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
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)) (FLAGS_DID_NOTE|FLAGS_DID_BUILD_ID))
goto core; 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 && if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
xnh_type == NT_GNU_VERSION && descsz == 16) { xnh_type == NT_GNU_VERSION && descsz == 16) {
uint32_t desc[4]; 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 && if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
xnh_type == NT_GNU_BUILD_ID && (descsz == 16 || descsz == 20)) { xnh_type == NT_GNU_BUILD_ID && (descsz == 16 || descsz == 20)) {
uint32_t desc[5], i; uint8_t desc[20];
if (file_printf(ms, ", BuildID[%s]=0x", descsz == 16 ? "md5/uuid" : uint32_t i;
if (file_printf(ms, ", BuildID[%s]=", descsz == 16 ? "md5/uuid" :
"sha1") == -1) "sha1") == -1)
return size; return size;
(void)memcpy(desc, &nbuf[doff], descsz); (void)memcpy(desc, &nbuf[doff], descsz);
for (i = 0; i < descsz >> 2; i++) for (i = 0; i < descsz; i++)
if (file_printf(ms, "%.8x", desc[i]) == -1) if (file_printf(ms, "%02x", desc[i]) == -1)
return size; return size;
*flags |= FLAGS_DID_BUILD_ID; *flags |= FLAGS_DID_BUILD_ID;
} }
@ -841,15 +850,16 @@ static const cap_desc_t cap_desc_386[] = {
private int private int
doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num, 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; Elf32_Shdr sh32;
Elf64_Shdr sh64; Elf64_Shdr sh64;
int stripped = 1; int stripped = 1;
void *nbuf; 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_hw1 = 0; /* SunOS 5.x hardware capabilites */
uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilites */ uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilites */
char name[50];
if (size != xsh_sizeof) { if (size != xsh_sizeof) {
if (file_printf(ms, ", corrupted section header size") == -1) if (file_printf(ms, ", corrupted section header size") == -1)

View file

@ -32,7 +32,7 @@
#include "file.h" #include "file.h"
#ifndef lint #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 */ #endif /* lint */
#include "magic.h" #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, 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 *, 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 int magiccheck(struct magic_set *, struct magic *);
private int32_t mprint(struct magic_set *, struct magic *); private int32_t mprint(struct magic_set *, struct magic *);
private int32_t moffset(struct magic_set *, struct magic *); private int32_t moffset(struct magic_set *, struct magic *);
private void mdebug(uint32_t, const char *, size_t); private void mdebug(uint32_t, const char *, size_t);
private int mcopy(struct magic_set *, union VALUETYPE *, int, int, private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
const unsigned char *, uint32_t, size_t, size_t); 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 print_sep(struct magic_set *, int);
private int handle_annotation(struct magic_set *, struct magic *); private int handle_annotation(struct magic_set *, struct magic *);
private void cvt_8(union VALUETYPE *, const 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) int mode, int text)
{ {
struct mlist *ml; struct mlist *ml;
int rv; int rv, printed_something = 0, need_separator = 0;
for (ml = ms->mlist->next; ml != ms->mlist; ml = ml->next) for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next)
if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, mode, if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, 0, mode,
text)) != 0) text, 0, 0, &printed_something, &need_separator,
NULL)) != 0)
return rv; return rv;
return 0; return 0;
@ -113,16 +116,19 @@ file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes,
*/ */
private int private int
match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, 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; uint32_t magindex = 0;
unsigned int cont_level = 0; unsigned int cont_level = 0;
int need_separator = 0; int returnvalv = 0, e; /* if a match is found it is set to 1*/
int returnval = 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 firstline = 1; /* a flag to print X\n X\n- X */
int printed_something = 0;
int print = (ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0; int print = (ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0;
if (returnval == NULL)
returnval = &returnvalv;
if (file_check_mem(ms, cont_level) == -1) if (file_check_mem(ms, cont_level) == -1)
return -1; return -1;
@ -130,14 +136,17 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
int flush = 0; int flush = 0;
struct magic *m = &magic[magindex]; struct magic *m = &magic[magindex];
if (m->type != FILE_NAME)
if ((IS_LIBMAGIC_STRING(m->type) && if ((IS_LIBMAGIC_STRING(m->type) &&
((text && (m->str_flags & (STRING_BINTEST | STRING_TEXTTEST)) == STRING_BINTEST) || #define FLT (STRING_BINTEST | STRING_TEXTTEST)
(!text && (m->str_flags & (STRING_TEXTTEST | STRING_BINTEST)) == STRING_TEXTTEST))) || ((text && (m->str_flags & FLT) == STRING_BINTEST) ||
(!text && (m->str_flags & FLT) == STRING_TEXTTEST))) ||
(m->flag & mode) != mode) { (m->flag & mode) != mode) {
/* Skip sub-tests */ /* Skip sub-tests */
while (magindex < nmagic - 1 && magic[magindex + 1].cont_level != 0) { while (magindex + 1 < nmagic &&
magindex++; magic[magindex + 1].cont_level != 0 &&
} ++magindex)
continue;
continue; /* Skip to next top-level test*/ 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; ms->line = m->lineno;
/* if main entry matches, print it... */ /* 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: case -1:
return -1; return -1;
case 0: case 0:
@ -153,7 +164,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
break; break;
default: default:
if (m->type == FILE_INDIRECT) if (m->type == FILE_INDIRECT)
returnval = 1; *returnval = 1;
switch (magiccheck(ms, m)) { switch (magiccheck(ms, m)) {
case -1: case -1:
@ -172,21 +183,23 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
* main entry didn't match, * main entry didn't match,
* flush its continuations * flush its continuations
*/ */
while (magindex < nmagic - 1 && magic[magindex + 1].cont_level != 0) { while (magindex < nmagic - 1 &&
magic[magindex + 1].cont_level != 0)
magindex++; magindex++;
}
continue; continue;
} }
if ((e = handle_annotation(ms, m)) != 0) if ((e = handle_annotation(ms, m)) != 0) {
*returnval = 1;
return e; return e;
}
/* /*
* If we are going to print something, we'll need to print * If we are going to print something, we'll need to print
* a blank before we print something else. * a blank before we print something else.
*/ */
if (*m->desc) { if (*m->desc) {
need_separator = 1; *need_separator = 1;
printed_something = 1; *printed_something = 1;
if (print_sep(ms, firstline) == -1) if (print_sep(ms, firstline) == -1)
return -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) if (file_check_mem(ms, ++cont_level) == -1)
return -1; return -1;
while (magindex < nmagic - 1 && magic[magindex + 1].cont_level != 0) { while (magindex + 1 < nmagic && magic[magindex+1].cont_level != 0 &&
magindex++; ++magindex) {
m = &magic[magindex]; m = &magic[magindex];
ms->line = m->lineno; /* for messages */ 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; ms->offset = m->offset;
if (m->flag & OFFADD) { 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 #ifdef ENABLE_CONDITIONALS
@ -227,7 +241,9 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
continue; continue;
} }
#endif #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: case -1:
return -1; return -1;
case 0: case 0:
@ -237,7 +253,7 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
break; break;
default: default:
if (m->type == FILE_INDIRECT) if (m->type == FILE_INDIRECT)
returnval = 1; *returnval = 1;
flush = 0; flush = 0;
break; break;
} }
@ -260,15 +276,17 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
ms->c.li[cont_level].got_match = 0; ms->c.li[cont_level].got_match = 0;
break; break;
} }
if ((e = handle_annotation(ms, m)) != 0) if ((e = handle_annotation(ms, m)) != 0) {
*returnval = 1;
return e; return e;
}
/* /*
* If we are going to print something, * If we are going to print something,
* make sure that we have a separator first. * make sure that we have a separator first.
*/ */
if (*m->desc) { if (*m->desc) {
if (!printed_something) { if (!*printed_something) {
printed_something = 1; *printed_something = 1;
if (print_sep(ms, firstline) if (print_sep(ms, firstline)
== -1) == -1)
return -1; return -1;
@ -281,13 +299,13 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
* this item isn't empty. * this item isn't empty.
*/ */
/* space if previous printed */ /* space if previous printed */
if (need_separator if (*need_separator
&& ((m->flag & NOSPACE) == 0) && ((m->flag & NOSPACE) == 0)
&& *m->desc) { && *m->desc) {
if (print && if (print &&
file_printf(ms, " ") == -1) file_printf(ms, " ") == -1)
return -1; return -1;
need_separator = 0; *need_separator = 0;
} }
if (print && mprint(ms, m) == -1) if (print && mprint(ms, m) == -1)
return -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); ms->c.li[cont_level].off = moffset(ms, m);
if (*m->desc) if (*m->desc)
need_separator = 1; *need_separator = 1;
/* /*
* If we see any continuations * If we see any continuations
@ -307,16 +325,16 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
break; break;
} }
} }
if (printed_something) { if (*printed_something) {
firstline = 0; firstline = 0;
if (print) if (print)
returnval = 1; *returnval = 1;
} }
if ((ms->flags & MAGIC_CONTINUE) == 0 && printed_something) { if ((ms->flags & MAGIC_CONTINUE) == 0 && *printed_something) {
return returnval; /* don't keep searching */ 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 private int
@ -345,7 +363,7 @@ mprint(struct magic_set *ms, struct magic *m)
float vf; float vf;
double vd; double vd;
int64_t t = 0; int64_t t = 0;
char buf[128]; char buf[128], tbuf[26];
union VALUETYPE *p = &ms->ms_value; union VALUETYPE *p = &ms->ms_value;
switch (m->type) { switch (m->type) {
@ -430,11 +448,30 @@ mprint(struct magic_set *ms, struct magic *m)
t = ms->offset + m->vallen; t = ms->offset + m->vallen;
} }
else { else {
char *str = p->s;
/* compute t before we mangle the string? */
t = ms->offset + strlen(str);
if (*m->value.s == '\0') if (*m->value.s == '\0')
p->s[strcspn(p->s, "\n")] = '\0'; str[strcspn(str, "\n")] = '\0';
if (file_printf(ms, m->desc, p->s) == -1)
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; return -1;
t = ms->offset + strlen(p->s);
if (m->type == FILE_PSTRING) if (m->type == FILE_PSTRING)
t += file_pstring_length_size(m); t += file_pstring_length_size(m);
} }
@ -444,25 +481,26 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_BEDATE: case FILE_BEDATE:
case FILE_LEDATE: case FILE_LEDATE:
case FILE_MEDATE: 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; return -1;
t = ms->offset + sizeof(time_t); t = ms->offset + sizeof(uint32_t);
break; break;
case FILE_LDATE: case FILE_LDATE:
case FILE_BELDATE: case FILE_BELDATE:
case FILE_LELDATE: case FILE_LELDATE:
case FILE_MELDATE: 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; return -1;
t = ms->offset + sizeof(time_t); t = ms->offset + sizeof(uint32_t);
break; break;
case FILE_QDATE: case FILE_QDATE:
case FILE_BEQDATE: case FILE_BEQDATE:
case FILE_LEQDATE: case FILE_LEQDATE:
if (file_printf(ms, m->desc, file_fmttime((uint32_t)p->q, if (file_printf(ms, m->desc, file_fmttime(p->q, FILE_T_LOCAL,
1)) == -1) tbuf)) == -1)
return -1; return -1;
t = ms->offset + sizeof(uint64_t); t = ms->offset + sizeof(uint64_t);
break; break;
@ -470,8 +508,16 @@ mprint(struct magic_set *ms, struct magic *m)
case FILE_QLDATE: case FILE_QLDATE:
case FILE_BEQLDATE: case FILE_BEQLDATE:
case FILE_LEQLDATE: case FILE_LEQLDATE:
if (file_printf(ms, m->desc, file_fmttime((uint32_t)p->q, if (file_printf(ms, m->desc, file_fmttime(p->q, 0, tbuf)) == -1)
0)) == -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; return -1;
t = ms->offset + sizeof(uint64_t); t = ms->offset + sizeof(uint64_t);
break; break;
@ -521,7 +567,10 @@ mprint(struct magic_set *ms, struct magic *m)
int rval; int rval;
cp = estrndup((const char *)ms->search.s, ms->search.rm_len); 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); rval = file_printf(ms, m->desc, cp);
efree(cp); efree(cp);
@ -551,6 +600,8 @@ mprint(struct magic_set *ms, struct magic *m)
break; break;
case FILE_INDIRECT: case FILE_INDIRECT:
case FILE_USE:
case FILE_NAME:
t = ms->offset; t = ms->offset;
break; break;
@ -598,7 +649,7 @@ moffset(struct magic_set *ms, struct magic *m)
p->s[strcspn(p->s, "\n")] = '\0'; p->s[strcspn(p->s, "\n")] = '\0';
t = CAST(uint32_t, (ms->offset + strlen(p->s))); t = CAST(uint32_t, (ms->offset + strlen(p->s)));
if (m->type == FILE_PSTRING) if (m->type == FILE_PSTRING)
t += file_pstring_length_size(m); t += (uint32_t)file_pstring_length_size(m);
return t; return t;
} }
@ -606,13 +657,13 @@ moffset(struct magic_set *ms, struct magic *m)
case FILE_BEDATE: case FILE_BEDATE:
case FILE_LEDATE: case FILE_LEDATE:
case FILE_MEDATE: 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_LDATE:
case FILE_BELDATE: case FILE_BELDATE:
case FILE_LELDATE: case FILE_LELDATE:
case FILE_MELDATE: 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_QDATE:
case FILE_BEQDATE: 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) \ #define DO_CVT(fld, cast) \
if (m->num_mask) \ if (m->num_mask) \
switch (m->mask_op & FILE_OPS_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) * (unless you have a better idea)
*/ */
private int 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; union VALUETYPE *p = &ms->ms_value;
switch (m->type) { switch (cvt_flip(m->type, flip)) {
case FILE_BYTE: case FILE_BYTE:
cvt_8(p, m); cvt_8(p, m);
return 1; return 1;
@ -767,6 +868,7 @@ mconvert(struct magic_set *ms, struct magic *m)
case FILE_QUAD: case FILE_QUAD:
case FILE_QDATE: case FILE_QDATE:
case FILE_QLDATE: case FILE_QLDATE:
case FILE_QWDATE:
cvt_64(p, m); cvt_64(p, m);
return 1; return 1;
case FILE_STRING: case FILE_STRING:
@ -800,6 +902,7 @@ mconvert(struct magic_set *ms, struct magic *m)
case FILE_BEQUAD: case FILE_BEQUAD:
case FILE_BEQDATE: case FILE_BEQDATE:
case FILE_BEQLDATE: case FILE_BEQLDATE:
case FILE_BEQWDATE:
p->q = (uint64_t) p->q = (uint64_t)
(((uint64_t)p->hq[0]<<56)|((uint64_t)p->hq[1]<<48)| (((uint64_t)p->hq[0]<<56)|((uint64_t)p->hq[1]<<48)|
((uint64_t)p->hq[2]<<40)|((uint64_t)p->hq[3]<<32)| ((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_LEQUAD:
case FILE_LEQDATE: case FILE_LEQDATE:
case FILE_LEQLDATE: case FILE_LEQLDATE:
case FILE_LEQWDATE:
p->q = (uint64_t) p->q = (uint64_t)
(((uint64_t)p->hq[7]<<56)|((uint64_t)p->hq[6]<<48)| (((uint64_t)p->hq[7]<<56)|((uint64_t)p->hq[6]<<48)|
((uint64_t)p->hq[5]<<40)|((uint64_t)p->hq[4]<<32)| ((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_REGEX:
case FILE_SEARCH: case FILE_SEARCH:
case FILE_DEFAULT: case FILE_DEFAULT:
case FILE_NAME:
case FILE_USE:
return 1; return 1;
default: default:
file_magerror(ms, "invalid type %d in mconvert()", m->type); file_magerror(ms, "invalid type %d in mconvert()", m->type);
@ -879,7 +985,7 @@ mconvert(struct magic_set *ms, struct magic *m)
private void private void
mdebug(uint32_t offset, const char *str, size_t len) 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); file_showstr(stderr, str, len);
(void) fputc('\n', stderr); (void) fputc('\n', stderr);
(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) if (type == FILE_BESTRING16)
src++; src++;
/* check for pointer overflow */ /* check that offset is within range */
if (src < s) { if (offset >= nbytes) {
file_magerror(ms, "invalid offset %u in mcopy()", file_magerror(ms, "invalid offset %u in mcopy()",
offset); offset);
return -1; return -1;
@ -996,26 +1102,40 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
} }
private int private int
mget(struct magic_set *ms, const unsigned char *s, mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
struct magic *m, size_t nbytes, unsigned int cont_level, int text) 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; uint32_t count = m->str_range;
int rv, oneed_separator;
char *sbuf, *rbuf;
union VALUETYPE *p = &ms->ms_value; 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; return -1;
if ((ms->flags & MAGIC_DEBUG) != 0) { 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)); mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
} }
if (m->flag & INDIR) { if (m->flag & INDIR) {
int off = m->in_offset; int off = m->in_offset;
if (m->in_op & FILE_OPINDIRECT) { if (m->in_op & FILE_OPINDIRECT) {
const union VALUETYPE *q = const union VALUETYPE *q = CAST(const union VALUETYPE *,
((const void *)(s + offset + off)); ((const void *)(s + offset + off)));
switch (m->in_type) { switch (cvt_flip(m->in_type, flip)) {
case FILE_BYTE: case FILE_BYTE:
off = q->b; off = q->b;
break; break;
@ -1046,8 +1166,10 @@ mget(struct magic_set *ms, const unsigned char *s,
(q->hl[3]<<8)|(q->hl[2])); (q->hl[3]<<8)|(q->hl[2]));
break; 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: case FILE_BYTE:
if (nbytes < (offset + 1)) if (nbytes < (offset + 1))
return 0; return 0;
@ -1472,7 +1594,7 @@ mget(struct magic_set *ms, const unsigned char *s,
break; break;
} }
switch (m->in_type) { switch (cvt_flip(m->in_type, flip)) {
case FILE_LEID3: case FILE_LEID3:
case FILE_BEID3: case FILE_BEID3:
offset = ((((offset >> 0) & 0x7f) << 0) | offset = ((((offset >> 0) & 0x7f) << 0) |
@ -1486,6 +1608,14 @@ mget(struct magic_set *ms, const unsigned char *s,
if (m->flag & INDIROFFADD) { if (m->flag & INDIROFFADD) {
offset += ms->c.li[cont_level-1].off; 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) if (mcopy(ms, p, m->type, 0, s, offset, nbytes, count) == -1)
return -1; return -1;
@ -1550,19 +1680,61 @@ mget(struct magic_set *ms, const unsigned char *s,
break; break;
case FILE_INDIRECT: case FILE_INDIRECT:
if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
file_printf(ms, "%s", m->desc) == -1)
return -1;
if (nbytes < offset) if (nbytes < offset)
return 0; 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); 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 */ case FILE_DEFAULT: /* nothing to check */
default: default:
break; break;
} }
if (!mconvert(ms, m)) if (!mconvert(ms, m, flip))
return 0; return 0;
return 1; return 1;
} }
@ -1723,6 +1895,9 @@ magiccheck(struct magic_set *ms, struct magic *m)
case FILE_QLDATE: case FILE_QLDATE:
case FILE_BEQLDATE: case FILE_BEQLDATE:
case FILE_LEQLDATE: case FILE_LEQLDATE:
case FILE_QWDATE:
case FILE_BEQWDATE:
case FILE_LEQWDATE:
v = p->q; v = p->q;
break; break;
@ -1851,11 +2026,7 @@ magiccheck(struct magic_set *ms, struct magic *m)
convert_libmagic_pattern(pattern, options); convert_libmagic_pattern(pattern, options);
l = v = 0; 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) { 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); zval_dtor(pattern);
FREE_ZVAL(pattern); FREE_ZVAL(pattern);
return -1; return -1;
@ -1872,11 +2043,7 @@ magiccheck(struct magic_set *ms, struct magic *m)
haystack = estrndup(ms->search.s, ms->search.s_len); haystack = estrndup(ms->search.s, ms->search.s_len);
/* match v = 0, no match v = 1 */ /* 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); 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 */ /* Free haystack */
efree(haystack); efree(haystack);
@ -1990,6 +2157,8 @@ magiccheck(struct magic_set *ms, struct magic *m)
break; break;
} }
case FILE_INDIRECT: case FILE_INDIRECT:
case FILE_USE:
case FILE_NAME:
return 1; return 1;
default: default:
file_magerror(ms, "invalid type %d in magiccheck()", m->type); 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 *** *** Testing finfo_file() : basic functionality ***
string(28) "text/x-php; charset=us-ascii" string(28) "text/x-php; charset=us-ascii"
string(22) "PHP script, ASCII text" string(22) "PHP script, ASCII text"
string(32) "text/plain; charset=unknown-8bit" string(25) "text/plain; charset=utf-8"
===DONE=== ===DONE===

View file

@ -27,25 +27,25 @@ var_dump( new finfo('foobar') );
--EXPECTF-- --EXPECTF--
*** Testing finfo_open() : error functionality *** *** 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) 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) 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) bool(false)
Notice: finfo_open(): Warning: using regular magic file `%s' in %s on line %d Notice: finfo_open(): Warning: using regular magic file `%smagic' in %sfinfo_open_error.php on line 15
resource(%d) of type (file_info) 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) 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 NULL
===DONE=== ===DONE===

File diff suppressed because it is too large Load diff