--- embedaddon/php/ext/fileinfo/libmagic/magic.c 2012/02/21 23:47:56 1.1 +++ embedaddon/php/ext/fileinfo/libmagic/magic.c 2013/07/22 01:31:50 1.1.1.3 @@ -28,7 +28,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: magic.c,v 1.62 2009/03/20 21:25:41 christos Exp $") +FILE_RCSID("@(#)$File: magic.c,v 1.78 2013/01/07 18:20:19 christos Exp $") #endif /* lint */ #include "magic.h" @@ -46,6 +46,10 @@ FILE_RCSID("@(#)$File: magic.c,v 1.62 2009/03/20 21:25 # include "php_config.h" #endif +#ifdef PHP_WIN32 +#include +#endif + #include /* for PIPE_BUF */ #if defined(HAVE_UTIMES) @@ -62,12 +66,6 @@ FILE_RCSID("@(#)$File: magic.c,v 1.62 2009/03/20 21:25 #include /* for read() */ #endif -#ifndef PHP_WIN32 -# include /* for byte swapping */ -#endif - -#include "patchlevel.h" - #ifndef PIPE_BUF /* Get the PIPE_BUF from pathconf */ #ifdef _PC_PIPE_BUF @@ -82,61 +80,156 @@ FILE_RCSID("@(#)$File: magic.c,v 1.62 2009/03/20 21:25 # undef S_IFIFO #endif -private void free_mlist(struct mlist *); private void close_and_restore(const struct magic_set *, const char *, int, const struct stat *); private int unreadable_info(struct magic_set *, mode_t, const char *); +#if 0 +private const char* get_default_magic(void); +#endif private const char *file_or_stream(struct magic_set *, const char *, php_stream *); #ifndef STDIN_FILENO #define STDIN_FILENO 0 #endif -public struct magic_set * -magic_open(int flags) +/* XXX this functionality is excluded in php, enable it in apprentice.c:340 */ +#if 0 +private const char * +get_default_magic(void) { - struct magic_set *ms; + static const char hmagic[] = "/.magic/magic.mgc"; + static char *default_magic; + char *home, *hmagicpath; - ms = ecalloc((size_t)1, sizeof(struct magic_set)); +#ifndef PHP_WIN32 + struct stat st; - if (magic_setflags(ms, flags) == -1) { - errno = EINVAL; - goto free; + if (default_magic) { + free(default_magic); + default_magic = NULL; } + if ((home = getenv("HOME")) == NULL) + return MAGIC; - ms->o.buf = ms->o.pbuf = NULL; + 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) + goto out; + if (S_ISDIR(st.st_mode)) { + free(hmagicpath); + if (asprintf(&hmagicpath, "%s/%s", home, hmagic) < 0) + return MAGIC; + if (access(hmagicpath, R_OK) == -1) + goto out; + } + } - 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; + if (asprintf(&default_magic, "%s:%s", hmagicpath, MAGIC) < 0) + goto out; + free(hmagicpath); + return default_magic; +out: + default_magic = NULL; + free(hmagicpath); + return MAGIC; +#else + char *hmagicp = hmagicpath; + char *tmppath = NULL; + LPTSTR dllpath; + +#define APPENDPATH() \ + do { \ + if (tmppath && access(tmppath, R_OK) != -1) { \ + if (hmagicpath == NULL) \ + hmagicpath = tmppath; \ + else { \ + if (asprintf(&hmagicp, "%s%c%s", hmagicpath, \ + PATHSEP, tmppath) >= 0) { \ + free(hmagicpath); \ + hmagicpath = hmagicp; \ + } \ + free(tmppath); \ + } \ + tmppath = NULL; \ + } \ + } while (/*CONSTCOND*/0) + + if (default_magic) { + free(default_magic); + default_magic = NULL; + } + + /* First, try to get user-specific magic file */ + if ((home = getenv("LOCALAPPDATA")) == NULL) { + if ((home = getenv("USERPROFILE")) != NULL) + if (asprintf(&tmppath, + "%s/Local Settings/Application Data%s", home, + hmagic) < 0) + tmppath = NULL; + } else { + if (asprintf(&tmppath, "%s%s", home, hmagic) < 0) + tmppath = NULL; + } + + APPENDPATH(); + + /* Second, try to get a magic file from Common Files */ + if ((home = getenv("COMMONPROGRAMFILES")) != NULL) { + if (asprintf(&tmppath, "%s%s", home, hmagic) >= 0) + APPENDPATH(); + } + + /* Third, try to get magic file relative to dll location */ + dllpath = malloc(sizeof(*dllpath) * (MAX_PATH + 1)); + dllpath[MAX_PATH] = 0; /* just in case long path gets truncated and not null terminated */ + if (GetModuleFileNameA(NULL, dllpath, MAX_PATH)){ + PathRemoveFileSpecA(dllpath); + if (strlen(dllpath) > 3 && + stricmp(&dllpath[strlen(dllpath) - 3], "bin") == 0) { + if (asprintf(&tmppath, + "%s/../share/misc/magic.mgc", dllpath) >= 0) + APPENDPATH(); + } else { + if (asprintf(&tmppath, + "%s/share/misc/magic.mgc", dllpath) >= 0) + APPENDPATH(); + else if (asprintf(&tmppath, + "%s/magic.mgc", dllpath) >= 0) + APPENDPATH(); + } + } + + /* Don't put MAGIC constant - it likely points to a file within MSys + tree */ + default_magic = hmagicpath; + return default_magic; +#endif } -private void -free_mlist(struct mlist *mlist) +public const char * +magic_getpath(const char *magicfile, int action) { - struct mlist *ml; + if (magicfile != NULL) + return magicfile; - if (mlist == NULL) - return; + magicfile = getenv("MAGIC"); + if (magicfile != NULL) + return magicfile; - 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 action == FILE_LOAD ? get_default_magic() : MAGIC; } +#endif +public struct magic_set * +magic_open(int flags) +{ + return file_ms_alloc(flags); +} + private int unreadable_info(struct magic_set *ms, mode_t md, const char *file) { @@ -158,19 +251,9 @@ unreadable_info(struct magic_set *ms, mode_t md, const 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); } /* @@ -179,23 +262,28 @@ 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) +{ + if (ms == NULL) + return -1; + return file_apprentice(ms, magicfile, FILE_LIST); +} + private void close_and_restore(const struct magic_set *ms, const char *name, int fd, const struct stat *sb) @@ -233,6 +321,8 @@ close_and_restore(const struct magic_set *ms, const ch public const char * magic_descriptor(struct magic_set *ms, int fd) { + if (ms == NULL) + return NULL; return file_or_stream(ms, NULL, NULL); } @@ -242,12 +332,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); } @@ -272,18 +366,17 @@ file_or_stream(struct magic_set *ms, const char *innam #define SLOP (1 + sizeof(union VALUETYPE)) buf = emalloc(HOWMANY + SLOP); - if (file_reset(ms) == -1) { + if (file_reset(ms) == -1) goto done; - } switch (file_fsmagic(ms, inname, &sb, stream)) { - case -1: /* error */ - goto done; - case 0: /* nothing found */ - break; - default: /* matched it and printed type */ - rv = 0; - goto done; + case -1: /* error */ + goto done; + case 0: /* nothing found */ + break; + default: /* matched it and printed type */ + rv = 0; + goto done; } errno = 0; @@ -331,9 +424,12 @@ done: return rv == 0 ? file_getbuffer(ms) : NULL; } + 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; /* @@ -349,22 +445,34 @@ magic_buffer(struct magic_set *ms, const void *buf, si 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; #endif ms->flags = flags; return 0; +} + +public int +magic_version(void) +{ + return MAGIC_VERSION; }