summaryrefslogtreecommitdiff
path: root/ext/fileinfo/libmagic/apprentice.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2014-04-26 00:32:51 +0400
committerDmitry Stogov <dmitry@zend.com>2014-04-26 00:32:51 +0400
commitf9927a6c97208c60d922f9a4e98feb8079c57d1f (patch)
tree35815b69d1bf7d47fb41e857ff8d2b024ddac153 /ext/fileinfo/libmagic/apprentice.c
parent4e7cbf3f5842abe6688c11ce3cc11d2eabf0695f (diff)
parentb82d077f988606580e5c06a9da18fe4f60ddb7cb (diff)
downloadphp-git-f9927a6c97208c60d922f9a4e98feb8079c57d1f.tar.gz
Merge mainstream 'master' branch into refactoring
During merge I had to revert: Nikita's patch for php_splice() (it probably needs to be applyed again) Bob Weinand's patches related to constant expression handling (we need to review them carefully) I also reverted all our attempts to support sapi/phpdbg (we didn't test it anyway) Conflicts: Zend/zend.h Zend/zend_API.c Zend/zend_ast.c Zend/zend_compile.c Zend/zend_compile.h Zend/zend_constants.c Zend/zend_exceptions.c Zend/zend_execute.c Zend/zend_execute.h Zend/zend_execute_API.c Zend/zend_hash.c Zend/zend_highlight.c Zend/zend_language_parser.y Zend/zend_language_scanner.c Zend/zend_language_scanner_defs.h Zend/zend_variables.c Zend/zend_vm_def.h Zend/zend_vm_execute.h ext/date/php_date.c ext/dom/documenttype.c ext/hash/hash.c ext/iconv/iconv.c ext/mbstring/tests/zend_multibyte-10.phpt ext/mbstring/tests/zend_multibyte-11.phpt ext/mbstring/tests/zend_multibyte-12.phpt ext/mysql/php_mysql.c ext/mysqli/mysqli.c ext/mysqlnd/mysqlnd_reverse_api.c ext/mysqlnd/php_mysqlnd.c ext/opcache/ZendAccelerator.c ext/opcache/zend_accelerator_util_funcs.c ext/opcache/zend_persist.c ext/opcache/zend_persist_calc.c ext/pcre/php_pcre.c ext/pdo/pdo_dbh.c ext/pdo/pdo_stmt.c ext/pdo_pgsql/pgsql_driver.c ext/pgsql/pgsql.c ext/reflection/php_reflection.c ext/session/session.c ext/spl/spl_array.c ext/spl/spl_observer.c ext/standard/array.c ext/standard/basic_functions.c ext/standard/html.c ext/standard/mail.c ext/standard/php_array.h ext/standard/proc_open.c ext/standard/streamsfuncs.c ext/standard/user_filters.c ext/standard/var_unserializer.c ext/standard/var_unserializer.re main/php_variables.c sapi/phpdbg/phpdbg.c sapi/phpdbg/phpdbg_bp.c sapi/phpdbg/phpdbg_frame.c sapi/phpdbg/phpdbg_help.c sapi/phpdbg/phpdbg_list.c sapi/phpdbg/phpdbg_print.c sapi/phpdbg/phpdbg_prompt.c
Diffstat (limited to 'ext/fileinfo/libmagic/apprentice.c')
-rw-r--r--ext/fileinfo/libmagic/apprentice.c127
1 files changed, 65 insertions, 62 deletions
diff --git a/ext/fileinfo/libmagic/apprentice.c b/ext/fileinfo/libmagic/apprentice.c
index 11920e6589..ce747378aa 100644
--- a/ext/fileinfo/libmagic/apprentice.c
+++ b/ext/fileinfo/libmagic/apprentice.c
@@ -34,7 +34,7 @@
#include "file.h"
#ifndef lint
-FILE_RCSID("@(#)$File: apprentice.c,v 1.191 2013/02/26 21:02:48 christos Exp $")
+FILE_RCSID("@(#)$File: apprentice.c,v 1.196 2013/11/19 21:01:12 christos Exp $")
#endif /* lint */
#include "magic.h"
@@ -94,6 +94,12 @@ struct magic_entry {
uint32_t max_count;
};
+struct magic_entry_set {
+ struct magic_entry *me;
+ uint32_t count;
+ uint32_t max;
+};
+
struct magic_map {
void *p;
size_t len;
@@ -139,7 +145,6 @@ private int parse_strength(struct magic_set *, struct magic_entry *, const char
private int parse_apple(struct magic_set *, struct magic_entry *, const char *);
-private size_t maxmagic[MAGIC_SETS] = { 0 };
private size_t magicsize = sizeof(struct magic);
private const char usg_hdr[] = "cont\toffset\ttype\topcode\tmask\tvalue\tdesc";
@@ -179,7 +184,7 @@ static const struct type_tbl_s type_tbl[] = {
{ XX("invalid"), FILE_INVALID, FILE_FMT_NONE },
{ XX("byte"), FILE_BYTE, FILE_FMT_NUM },
{ XX("short"), FILE_SHORT, FILE_FMT_NUM },
- { XX("default"), FILE_DEFAULT, FILE_FMT_STR },
+ { XX("default"), FILE_DEFAULT, FILE_FMT_NONE },
{ XX("long"), FILE_LONG, FILE_FMT_NUM },
{ XX("string"), FILE_STRING, FILE_FMT_STR },
{ XX("date"), FILE_DATE, FILE_FMT_STR },
@@ -223,6 +228,7 @@ static const struct type_tbl_s type_tbl[] = {
{ XX("beqwdate"), FILE_BEQWDATE, FILE_FMT_STR },
{ XX("name"), FILE_NAME, FILE_FMT_NONE },
{ XX("use"), FILE_USE, FILE_FMT_NONE },
+ { XX("clear"), FILE_CLEAR, FILE_FMT_NONE },
{ XX_NULL, FILE_INVALID, FILE_FMT_NONE },
};
@@ -493,12 +499,14 @@ apprentice_unmap(struct magic_map *map)
if (map == NULL)
return;
if (map->p != php_magic_database) {
- int j;
- for (j = 0; j < MAGIC_SETS; j++) {
- if (map->magic[j])
- efree(map->magic[j]);
- }
- if (map->p != NULL) {
+ if (map->p == NULL) {
+ int j;
+ for (j = 0; j < MAGIC_SETS; j++) {
+ if (map->magic[j]) {
+ efree(map->magic[j]);
+ }
+ }
+ } else {
efree(map->p);
}
}
@@ -541,6 +549,9 @@ file_apprentice(struct magic_set *ms, const char *fn, int action)
char *p, *mfn;
int file_err, errs = -1;
size_t i;
+
+ file_reset(ms);
+
/* XXX disabling default magic loading so the compiled in data is used */
#if 0
if ((fn = magic_getpath(fn, action)) == NULL)
@@ -605,6 +616,10 @@ file_apprentice(struct magic_set *ms, const char *fn, int action)
return -1;
}
+#if 0
+ /*
+ * Always leave the database loaded
+ */
if (action == FILE_LOAD)
return 0;
@@ -612,8 +627,10 @@ file_apprentice(struct magic_set *ms, const char *fn, int action)
mlist_free(ms->mlist[i]);
ms->mlist[i] = NULL;
}
+#endif
switch (action) {
+ case FILE_LOAD:
case FILE_COMPILE:
case FILE_CHECK:
case FILE_LIST:
@@ -906,24 +923,24 @@ set_test_type(struct magic *mstart, struct magic *m)
private int
addentry(struct magic_set *ms, struct magic_entry *me,
- struct magic_entry **mentry, uint32_t *mentrycount)
+ struct magic_entry_set *mset)
{
size_t i = me->mp->type == FILE_NAME ? 1 : 0;
- if (mentrycount[i] == maxmagic[i]) {
+ if (mset[i].count == mset[i].max) {
struct magic_entry *mp;
- maxmagic[i] += ALLOC_INCR;
+ mset[i].max += ALLOC_INCR;
if ((mp = CAST(struct magic_entry *,
- erealloc(mentry[i], sizeof(*mp) * maxmagic[i]))) ==
+ erealloc(mset[i].me, sizeof(*mp) * mset[i].max))) ==
NULL) {
- file_oomem(ms, sizeof(*mp) * maxmagic[i]);
+ file_oomem(ms, sizeof(*mp) * mset[i].max);
return -1;
}
- (void)memset(&mp[mentrycount[i]], 0, sizeof(*mp) *
+ (void)memset(&mp[mset[i].count], 0, sizeof(*mp) *
ALLOC_INCR);
- mentry[i] = mp;
+ mset[i].me = mp;
}
- mentry[i][mentrycount[i]++] = *me;
+ mset[i].me[mset[i].count++] = *me;
memset(me, 0, sizeof(*me));
return 0;
}
@@ -933,7 +950,7 @@ addentry(struct magic_set *ms, struct magic_entry *me,
*/
private void
load_1(struct magic_set *ms, int action, const char *fn, int *errs,
- struct magic_entry **mentry, uint32_t *mentrycount)
+ struct magic_entry_set *mset)
{
char buffer[BUFSIZ + 1];
char *line = NULL;
@@ -946,11 +963,7 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs,
TSRMLS_FETCH();
ms->file = fn;
-#if PHP_API_VERSION < 20100412
- stream = php_stream_open_wrapper((char *)fn, "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL);
-#else
stream = php_stream_open_wrapper((char *)fn, "rb", REPORT_ERRORS, NULL);
-#endif
if (stream == NULL) {
if (errno != ENOENT)
@@ -1010,16 +1023,16 @@ load_1(struct magic_set *ms, int action, const char *fn, int *errs,
case 0:
continue;
case 1:
- (void)addentry(ms, &me, mentry, mentrycount);
+ (void)addentry(ms, &me, mset);
goto again;
default:
(*errs)++;
- break;
+ break;
+ }
}
}
- }
if (me.mp)
- (void)addentry(ms, &me, mentry, mentrycount);
+ (void)addentry(ms, &me, mset);
php_stream_close(stream);
}
@@ -1128,22 +1141,24 @@ magic_entry_free(struct magic_entry *me, uint32_t nme)
private struct magic_map *
apprentice_load(struct magic_set *ms, const char *fn, int action)
{
- int errs = 0;
- struct magic_entry *mentry[MAGIC_SETS] = { NULL };
- uint32_t mentrycount[MAGIC_SETS] = { 0 };
+ int errs = 0;
uint32_t i, j;
size_t files = 0, maxfiles = 0;
char **filearr = NULL;
struct stat st;
struct magic_map *map;
+ struct magic_entry_set mset[MAGIC_SETS];
php_stream *dir;
php_stream_dirent d;
-
+
TSRMLS_FETCH();
+ memset(mset, 0, sizeof(mset));
ms->flags |= MAGIC_CHECK; /* Enable checks for parsed files */
- if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL) {
+
+ if ((map = CAST(struct magic_map *, ecalloc(1, sizeof(*map)))) == NULL)
+ {
file_oomem(ms, sizeof(*map));
return NULL;
}
@@ -1152,16 +1167,6 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)
if (action == FILE_CHECK)
(void)fprintf(stderr, "%s\n", usg_hdr);
- {
- /* XXX the maxmagic has to be reset each time we load some new magic file.
- Where file commando is used it's not essential as the CLI process
- ends, multiple loading within the same process wouldn't work. */
- int k;
- for (k = 0; k < MAGIC_SETS; k++) {
- maxmagic[k] = 0;
- }
- }
-
/* load directory or file */
/* FIXME: Read file names and sort them to prevent
non-determinism. See Debian bug #488562. */
@@ -1192,6 +1197,7 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)
if ((filearr = CAST(char **,
erealloc(filearr, mlen))) == NULL) {
file_oomem(ms, mlen);
+ efree(mfn);
php_stream_closedir(dir);
errs++;
goto out;
@@ -1202,36 +1208,35 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)
php_stream_closedir(dir);
qsort(filearr, files, sizeof(*filearr), cmpstrp);
for (i = 0; i < files; i++) {
- load_1(ms, action, filearr[i], &errs, mentry,
- mentrycount);
+ load_1(ms, action, filearr[i], &errs, mset);
efree(filearr[i]);
}
efree(filearr);
} else
- load_1(ms, action, fn, &errs, mentry, mentrycount);
+ load_1(ms, action, fn, &errs, mset);
if (errs)
goto out;
for (j = 0; j < MAGIC_SETS; j++) {
/* Set types of tests */
- for (i = 0; i < mentrycount[j]; ) {
- if (mentry[j][i].mp->cont_level != 0) {
+ for (i = 0; i < mset[j].count; ) {
+ if (mset[j].me[i].mp->cont_level != 0) {
i++;
continue;
}
- i = set_text_binary(ms, mentry[j], mentrycount[j], i);
+ i = set_text_binary(ms, mset[j].me, mset[j].count, i);
}
- qsort(mentry[j], mentrycount[j], sizeof(*mentry[j]),
+ qsort(mset[j].me, mset[j].count, sizeof(*mset[j].me),
apprentice_sort);
/*
* Make sure that any level 0 "default" line is last
* (if one exists).
*/
- set_last_default(ms, mentry[j], mentrycount[j]);
+ set_last_default(ms, mset[j].me, mset[j].count);
/* coalesce per file arrays into a single one */
- if (coalesce_entries(ms, mentry[j], mentrycount[j],
+ if (coalesce_entries(ms, mset[j].me, mset[j].count,
&map->magic[j], &map->nmagic[j]) == -1) {
errs++;
goto out;
@@ -1240,7 +1245,7 @@ apprentice_load(struct magic_set *ms, const char *fn, int action)
out:
for (j = 0; j < MAGIC_SETS; j++)
- magic_entry_free(mentry[j], mentrycount[j]);
+ magic_entry_free(mset[j].me, mset[j].count);
if (errs) {
for (j = 0; j < MAGIC_SETS; j++) {
@@ -1318,6 +1323,7 @@ file_signextend(struct magic_set *ms, struct magic *m, uint64_t v)
case FILE_INDIRECT:
case FILE_NAME:
case FILE_USE:
+ case FILE_CLEAR:
break;
default:
if (ms->flags & MAGIC_CHECK)
@@ -1735,10 +1741,10 @@ parse(struct magic_set *ms, struct magic_entry *me, const char *line,
if (m->type == FILE_INVALID) {
if (ms->flags & MAGIC_CHECK)
file_magwarn(ms, "type `%s' invalid", l);
- if (me->mp) {
+ /*if (me->mp) {
efree(me->mp);
me->mp = NULL;
- }
+ }*/
return -1;
}
@@ -1969,6 +1975,11 @@ parse_strength(struct magic_set *ms, struct magic_entry *me, const char *line)
m->factor_op, m->factor);
return -1;
}
+ if (m->type == FILE_NAME) {
+ file_magwarn(ms, "%s: Strength setting is not supported in "
+ "\"name\" magic entries", m->value.s);
+ return -1;
+ }
EATAB;
switch (*l) {
case FILE_FACTOR_OP_NONE:
@@ -2624,11 +2635,7 @@ apprentice_map(struct magic_set *ms, const char *fn)
if (dbname == NULL)
goto error;
-#if PHP_API_VERSION < 20100412
- stream = php_stream_open_wrapper((char *)fn, "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL);
-#else
stream = php_stream_open_wrapper((char *)fn, "rb", REPORT_ERRORS, NULL);
-#endif
if (!stream) {
goto error;
@@ -2761,12 +2768,8 @@ apprentice_compile(struct magic_set *ms, struct magic_map *map, const char *fn)
if (dbname == NULL)
goto out;
-/* wb+ == O_WRONLY|O_CREAT|O_TRUNC|O_BINARY */
-#if PHP_API_VERSION < 20100412
- stream = php_stream_open_wrapper((char *)fn, "wb+", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL);
-#else
+ /* wb+ == O_WRONLY|O_CREAT|O_TRUNC|O_BINARY */
stream = php_stream_open_wrapper((char *)fn, "wb+", REPORT_ERRORS, NULL);
-#endif
if (!stream) {
file_error(ms, errno, "cannot open `%s'", dbname);