fileinfo: Introduce php_libmagic.* to simplify patch

Signed-off-by: Anatol Belski <ab@php.net>
This commit is contained in:
Anatol Belski 2022-09-15 02:23:39 +02:00
parent a24727a5ca
commit a3dd514d4d
21 changed files with 220 additions and 283 deletions

View file

@ -49,7 +49,7 @@ int main(void)
libmagic_sources="$libmagic_sources libmagic/strcasestr.c"
],[AC_MSG_RESULT([skipped, cross-compiling])])
PHP_NEW_EXTENSION(fileinfo, fileinfo.c $libmagic_sources, $ext_shared,,-I@ext_srcdir@/libmagic)
PHP_NEW_EXTENSION(fileinfo, fileinfo.c php_libmagic.c $libmagic_sources, $ext_shared,,-I@ext_srcdir@/libmagic)
PHP_ADD_BUILD_DIR($ext_builddir/libmagic)
AC_CHECK_FUNCS([utimes strndup])

View file

@ -10,6 +10,6 @@ if (PHP_FILEINFO != 'no') {
readcdf.c softmagic.c der.c \
strcasestr.c buffer.c is_csv.c";
EXTENSION('fileinfo', 'fileinfo.c', true, "/I" + configure_module_dirname + "/libmagic /I" + configure_module_dirname);
EXTENSION('fileinfo', 'fileinfo.c php_libmagic.c', true, "/I" + configure_module_dirname + "/libmagic /I" + configure_module_dirname);
ADD_SOURCES(configure_module_dirname + '\\libmagic', LIBMAGIC_SOURCES, "fileinfo");
}

View file

@ -14,9 +14,6 @@
+----------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "libmagic/magic.h"

View file

@ -29,8 +29,6 @@
* apprentice - make one pass through /etc/magic, learning its secrets.
*/
#include "php.h"
#include "file.h"
#ifndef lint
@ -39,19 +37,6 @@ FILE_RCSID("@(#)$File: apprentice.c,v 1.326 2022/09/13 18:46:07 christos Exp $")
#include "magic.h"
#include <stdlib.h>
#if defined(__hpux) && !defined(HAVE_STRTOULL)
#if SIZEOF_LONG == 8
# define strtoull strtoul
#else
# define strtoull __strtoull
#endif
#endif
#ifdef PHP_WIN32
#include "win32/unistd.h"
#define strtoull _strtoui64
#else
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@ -87,10 +72,6 @@ FILE_RCSID("@(#)$File: apprentice.c,v 1.326 2022/09/13 18:46:07 christos Exp $")
#endif
#endif
#ifndef offsetof
#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))
#endif
#ifndef MAP_FAILED
#define MAP_FAILED (void *) -1
#endif
@ -207,6 +188,39 @@ private struct {
#include "../data_file.c"
#ifdef COMPILE_ONLY
int main(int, char *[]);
int
main(int argc, char *argv[])
{
int ret;
struct magic_set *ms;
char *progname;
if ((progname = strrchr(argv[0], '/')) != NULL)
progname++;
else
progname = argv[0];
if (argc != 2) {
(void)fprintf(stderr, "Usage: %s file\n", progname);
return 1;
}
if ((ms = magic_open(MAGIC_CHECK)) == NULL) {
(void)fprintf(stderr, "%s: %s\n", progname, strerror(errno));
return 1;
}
ret = magic_compile(ms, argv[1]) == -1 ? 1 : 0;
if (ret == 1)
(void)fprintf(stderr, "%s: %s\n", progname, magic_error(ms));
magic_close(ms);
return ret;
}
#endif /* COMPILE_ONLY */
struct type_tbl_s {
const char name[16];
const size_t len;
@ -440,15 +454,7 @@ add_mlist(struct mlist *mlp, struct magic_map *map, size_t idx)
ml->map = idx == 0 ? map : NULL;
ml->magic = map->magic[idx];
ml->nmagic = map->nmagic[idx];
if (ml->nmagic) {
ml->magic_rxcomp = CAST(file_regex_t **,
ecalloc(ml->nmagic, sizeof(*ml->magic_rxcomp)));
if (ml->magic_rxcomp == NULL) {
efree(ml);
return -1;
}
} else
ml->magic_rxcomp = NULL;
mlp->prev->next = ml;
ml->prev = mlp->prev;
ml->next = mlp;
@ -656,51 +662,6 @@ mlist_free(struct mlist *mlist)
mlist_free_one(mlist);
}
#ifndef COMPILE_ONLY
/* void **bufs: an array of compiled magic files */
protected int
buffer_apprentice(struct magic_set *ms, struct magic **bufs,
size_t *sizes, size_t nbufs)
{
size_t i, j;
struct mlist *ml;
struct magic_map *map;
if (nbufs == 0)
return -1;
(void)file_reset(ms, 0);
init_file_tables();
for (i = 0; i < MAGIC_SETS; i++) {
mlist_free(ms->mlist[i]);
if ((ms->mlist[i] = mlist_alloc()) == NULL) {
file_oomem(ms, sizeof(*ms->mlist[i]));
goto fail;
}
}
for (i = 0; i < nbufs; i++) {
map = apprentice_buf(ms, bufs[i], sizes[i]);
if (map == NULL)
goto fail;
for (j = 0; j < MAGIC_SETS; j++) {
if (add_mlist(ms->mlist[j], map, j) == -1) {
file_oomem(ms, sizeof(*ml));
goto fail;
}
}
}
return 0;
fail:
mlist_free_all(ms);
return -1;
}
#endif
/* const char *fn: list of magic files and directories */
protected int
file_apprentice(struct magic_set *ms, const char *fn, int action)
@ -3223,28 +3184,6 @@ eatsize(const char **p)
*p = l;
}
/*
* handle a buffer containing a compiled file.
*/
private struct magic_map *
apprentice_buf(struct magic_set *ms, struct magic *buf, size_t len)
{
struct magic_map *map;
if ((map = CAST(struct magic_map *, calloc(1, sizeof(*map)))) == NULL) {
file_oomem(ms, sizeof(*map));
return NULL;
}
map->len = len;
map->p = buf;
map->type = MAP_TYPE_USER;
if (check_buffer(ms, map, "buffer") != 0) {
apprentice_unmap(map);
return NULL;
}
return map;
}
/*
* handle a compiled file.
*/

View file

@ -31,9 +31,7 @@ FILE_RCSID("@(#)$File: buffer.c,v 1.8 2020/02/16 15:52:49 christos Exp $")
#endif /* lint */
#include "magic.h"
#ifdef PHP_WIN32
#include "win32/unistd.h"
#else
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>

View file

@ -43,17 +43,9 @@ FILE_RCSID("@(#)$File: cdf.c,v 1.121 2021/10/20 13:56:15 christos Exp $")
#include <err.h>
#endif
#include <stdlib.h>
#ifdef PHP_WIN32
#include "win32/unistd.h"
#else
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifndef UINT32_MAX
# define UINT32_MAX (0xffffffff)
#endif
#include <string.h>
#include <time.h>
#include <ctype.h>
@ -101,44 +93,9 @@ static union {
CDF_TOLE8(CAST(uint64_t, x))))
#define CDF_GETUINT32(x, y) cdf_getuint32(x, y)
#define CDF_MALLOC(n) cdf_malloc(__FILE__, __LINE__, (n))
#define CDF_REALLOC(p, n) cdf_realloc(__FILE__, __LINE__, (p), (n))
#define CDF_CALLOC(n, u) cdf_calloc(__FILE__, __LINE__, (n), (u))
/*ARGSUSED*/
static void *
cdf_malloc(const char *file __attribute__((__unused__)),
size_t line __attribute__((__unused__)), size_t n)
{
DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u\n",
file, line, __func__, n));
if (n == 0)
n++;
return malloc(n);
}
/*ARGSUSED*/
static void *
cdf_realloc(const char *file __attribute__((__unused__)),
size_t line __attribute__((__unused__)), void *p, size_t n)
{
DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u\n",
file, line, __func__, n));
return realloc(p, n);
}
/*ARGSUSED*/
static void *
cdf_calloc(const char *file __attribute__((__unused__)),
size_t line __attribute__((__unused__)), size_t n, size_t u)
{
DPRINTF(("%s,%" SIZE_T_FORMAT "u: %s %" SIZE_T_FORMAT "u %"
SIZE_T_FORMAT "u\n", file, line, __func__, n, u));
if (n == 0)
n++;
return calloc(n, u);
}
#define CDF_MALLOC(n) emalloc(n)
#define CDF_REALLOC(p, n) erealloc(p, n)
#define CDF_CALLOC(n, u) ecalloc(n, u)
#if defined(HAVE_BYTESWAP_H)
# define _cdf_tole2(x) bswap_16(x)

View file

@ -35,10 +35,8 @@
#ifndef _H_CDF_
#define _H_CDF_
#ifdef PHP_WIN32
#ifdef WIN32
#include <winsock2.h>
#define asctime_r php_asctime_r
#define ctime_r php_ctime_r
#endif
#ifdef __DJGPP__
#define timespec timeval

View file

@ -23,7 +23,6 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "php.h"
#include "file.h"

View file

@ -1 +1,10 @@
#include "php.h"
#include "php_libmagic.h"
#ifndef HAVE_STDINT_H
#define HAVE_STDINT_H 1
#endif
#ifndef HAVE_STDINT_H
#define HAVE_STDINT_H 1
#endif

View file

@ -54,7 +54,7 @@ FILE_RCSID("@(#)$File: der.c,v 1.24 2022/07/30 18:08:36 christos Exp $")
#include "magic.h"
#include "der.h"
#else
#ifndef PHP_WIN32
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include <sys/stat.h>

View file

@ -175,7 +175,7 @@ file_encoding(struct magic_set *ms, const struct buffer *b,
done:
if (ubuf == &udefbuf)
free(udefbuf);
efree(udefbuf);
return rv;
}

View file

@ -35,12 +35,13 @@
#include "config.h"
#include "php.h"
#include "ext/standard/php_string.h"
#include "ext/pcre/php_pcre.h"
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
@ -78,17 +79,13 @@
#include <fcntl.h> /* For open and flags */
#include <sys/types.h>
#ifdef PHP_WIN32
#include "win32/param.h"
#else
#ifndef WIN32
#include <sys/param.h>
#endif
/* Do this here and now, because struct stat gets re-defined on solaris */
#include <sys/stat.h>
#include <stdarg.h>
#define abort() zend_error_noreturn(E_ERROR, "fatal libmagic error")
#define ENABLE_CONDITIONALS
#ifndef MAGIC
@ -167,6 +164,8 @@
#define FILE_COMPILE 2
#define FILE_LIST 3
typedef void* file_regex_t;
struct buffer {
int fd;
zend_stat_t st;
@ -586,8 +585,6 @@ protected void buffer_init(struct buffer *, int, const zend_stat_t *,
protected void buffer_fini(struct buffer *);
protected int buffer_fill(const struct buffer *);
public zend_string* convert_libmagic_pattern(const char *val, size_t len, uint32_t options);
typedef struct {
char *buf;
size_t blen;
@ -650,16 +647,4 @@ static const char *rcsid(const char *p) { \
#define __RCSID(a)
#endif
#ifdef PHP_WIN32
#ifdef _WIN64
#define FINFO_LSEEK_FUNC _lseeki64
#else
#define FINFO_LSEEK_FUNC _lseek
#endif
#define FINFO_READ_FUNC _read
#else
#define FINFO_LSEEK_FUNC lseek
#define FINFO_READ_FUNC read
#endif
#endif /* __file_h__ */

View file

@ -51,13 +51,6 @@ FILE_RCSID("@(#)$File: funcs.c,v 1.131 2022/09/13 18:46:07 christos Exp $")
#define SIZE_MAX ((size_t)~0)
#endif
#include "php.h"
#include "main/php_network.h"
#ifndef PREG_OFFSET_CAPTURE
# define PREG_OFFSET_CAPTURE (1<<8)
#endif
protected char *
file_copystr(char *buf, size_t blen, size_t width, const char *str)
{
@ -139,7 +132,7 @@ file_checkfmt(char *msg, size_t mlen, const char *fmt)
protected int
file_vprintf(struct magic_set *ms, const char *fmt, va_list ap)
{
size_t len;
int len;
char *buf, *newstr;
char tbuf[1024];

View file

@ -25,6 +25,11 @@
* SUCH DAMAGE.
*/
#ifdef WIN32
#include <windows.h>
#include <shlwapi.h>
#endif
#include "file.h"
#ifndef lint
@ -34,16 +39,12 @@ FILE_RCSID("@(#)$File: magic.c,v 1.117 2021/12/06 15:33:00 christos Exp $")
#include "magic.h"
#include <stdlib.h>
#ifdef PHP_WIN32
#include "win32/unistd.h"
#else
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include "config.h"
#ifdef PHP_WIN32
#include <shlwapi.h>
#ifdef QUICK
#include <sys/mman.h>
#endif
#include <limits.h> /* for PIPE_BUF */

View file

@ -28,7 +28,6 @@
/*
* print.c - debugging printout routines
*/
#include "php.h"
#include "file.h"

View file

@ -31,9 +31,7 @@ FILE_RCSID("@(#)$File: readcdf.c,v 1.76 2022/01/17 16:59:01 christos Exp $")
#include <assert.h>
#include <stdlib.h>
#ifdef PHP_WIN32
#include "win32/unistd.h"
#else
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>

View file

@ -43,10 +43,6 @@ FILE_RCSID("@(#)$File: softmagic.c,v 1.328 2022/09/13 18:46:07 christos Exp $")
#include <time.h>
#include "der.h"
#ifndef PREG_OFFSET_CAPTURE
# define PREG_OFFSET_CAPTURE (1<<8)
#endif
private int match(struct magic_set *, struct magic *, file_regex_t **, size_t,
const struct buffer *, size_t, int, int, int, uint16_t *,
uint16_t *, int *, int *, int *, int *);
@ -2050,81 +2046,6 @@ file_strncmp16(const char *a, const char *b, size_t len, size_t maxlen,
return file_strncmp(a, b, len, maxlen, flags);
}
private file_regex_t *
alloc_regex(struct magic_set *ms, struct magic *m)
{
int rc;
file_regex_t *rx = CAST(file_regex_t *, malloc(sizeof(*rx)));
if (rx == NULL) {
file_error(ms, errno, "can't allocate %" SIZE_T_FORMAT
"u bytes", sizeof(*rx));
return NULL;
}
rc = file_regcomp(ms, rx, m->value.s, REG_EXTENDED | REG_NEWLINE |
((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0));
if (rc == 0)
return rx;
free(rx);
return NULL;
}
public zend_string* convert_libmagic_pattern(const char *val, size_t len, uint32_t options)
{
int i, j;
zend_string *t;
for (i = j = 0; i < len; i++) {
switch (val[i]) {
case '~':
j += 2;
break;
case '\0':
j += 4;
break;
default:
j++;
break;
}
}
t = zend_string_alloc(j + 4, 0);
j = 0;
ZSTR_VAL(t)[j++] = '~';
for (i = 0; i < len; i++, j++) {
switch (val[i]) {
case '~':
ZSTR_VAL(t)[j++] = '\\';
ZSTR_VAL(t)[j] = '~';
break;
case '\0':
ZSTR_VAL(t)[j++] = '\\';
ZSTR_VAL(t)[j++] = 'x';
ZSTR_VAL(t)[j++] = '0';
ZSTR_VAL(t)[j] = '0';
break;
default:
ZSTR_VAL(t)[j] = val[i];
break;
}
}
ZSTR_VAL(t)[j++] = '~';
if (options & PCRE2_CASELESS)
ZSTR_VAL(t)[j++] = 'i';
if (options & PCRE2_MULTILINE)
ZSTR_VAL(t)[j++] = 'm';
ZSTR_VAL(t)[j]='\0';
ZSTR_LEN(t) = j;
return t;
}
private int
magiccheck(struct magic_set *ms, struct magic *m, file_regex_t **m_cache)
{
@ -2297,6 +2218,7 @@ magiccheck(struct magic_set *ms, struct magic *m, file_regex_t **m_cache)
ms->search.rm_len = ms->search.s_len - idx;
break;
}
#endif
for (idx = 0; m->str_range == 0 || idx < m->str_range; idx++) {
if (slen + idx > ms->search.s_len) {
@ -2331,10 +2253,6 @@ magiccheck(struct magic_set *ms, struct magic *m, file_regex_t **m_cache)
if ((pce = pcre_get_compiled_regex_cache(pattern)) == NULL) {
zend_string_release(pattern);
return -1;
}
memcpy(copy, ms->search.s, slen);
copy[--slen] = '\0';
search = copy;
} else {
/* pce now contains the compiled regex */
zval retval;

View file

@ -39,8 +39,6 @@ __RCSID("$NetBSD: strncasecmp.c,v 1.2 2007/06/04 18:19:27 christos Exp $");
#include "file.h"
#include <inttypes.h>
#include <stdint.h>
#include <assert.h>
#include <ctype.h>
#include <string.h>

View file

@ -24,6 +24,8 @@ extern zend_module_entry fileinfo_module_entry;
#ifdef PHP_WIN32
#define PHP_FILEINFO_API __declspec(dllexport)
#elif defined(__GNUC__) && __GNUC__ >= 4
#define PHP_FILEINFO_API __attribute__((visibility("default")))
#else
#define PHP_FILEINFO_API
#endif

View file

@ -0,0 +1,75 @@
/*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| https://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Anatol Belski <ab@php.net> |
+----------------------------------------------------------------------+
*/
#include "php.h"
#include "php_libmagic.h"
zend_string* convert_libmagic_pattern(const char *val, size_t len, uint32_t options)
{
int i, j;
zend_string *t;
for (i = j = 0; i < len; i++) {
switch (val[i]) {
case '~':
j += 2;
break;
case '\0':
j += 4;
break;
default:
j++;
break;
}
}
t = zend_string_alloc(j + 4, 0);
j = 0;
ZSTR_VAL(t)[j++] = '~';
for (i = 0; i < len; i++, j++) {
switch (val[i]) {
case '~':
ZSTR_VAL(t)[j++] = '\\';
ZSTR_VAL(t)[j] = '~';
break;
case '\0':
ZSTR_VAL(t)[j++] = '\\';
ZSTR_VAL(t)[j++] = 'x';
ZSTR_VAL(t)[j++] = '0';
ZSTR_VAL(t)[j] = '0';
break;
default:
ZSTR_VAL(t)[j] = val[i];
break;
}
}
ZSTR_VAL(t)[j++] = '~';
if (options & PCRE2_CASELESS)
ZSTR_VAL(t)[j++] = 'i';
if (options & PCRE2_MULTILINE)
ZSTR_VAL(t)[j++] = 'm';
ZSTR_VAL(t)[j]='\0';
ZSTR_LEN(t) = j;
return t;
}

View file

@ -0,0 +1,71 @@
/*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| https://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Anatol Belski <ab@php.net> |
+----------------------------------------------------------------------+
*/
#ifndef PHP_LIBMAGIC_H
#define PHP_LIBMAGIC_H
#include "php_fileinfo.h"
#include "main/php_network.h"
#include "ext/standard/php_string.h"
#include "ext/pcre/php_pcre.h"
#ifdef PHP_WIN32
#include "win32/param.h"
#include "win32/unistd.h"
#ifdef _WIN64
#define FINFO_LSEEK_FUNC _lseeki64
#else
#define FINFO_LSEEK_FUNC _lseek
#endif
#define FINFO_READ_FUNC _read
#define strtoull _strtoui64
#define asctime_r php_asctime_r
#define ctime_r php_ctime_r
#else
#define FINFO_LSEEK_FUNC lseek
#define FINFO_READ_FUNC read
#endif
#if defined(__hpux) && !defined(HAVE_STRTOULL)
#if SIZEOF_LONG == 8
# define strtoull strtoul
#else
# define strtoull __strtoull
#endif
#endif
#ifndef offsetof
#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))
#endif
#ifndef UINT32_MAX
# define UINT32_MAX (0xffffffff)
#endif
#ifndef PREG_OFFSET_CAPTURE
# define PREG_OFFSET_CAPTURE (1<<8)
#endif
#define abort() zend_error_noreturn(E_ERROR, "fatal libmagic error")
zend_string* convert_libmagic_pattern(const char *val, size_t len, uint32_t options);
#endif /* PHP_LIBMAGIC_H */