summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/exif/exif.c2
-rw-r--r--ext/exif/tests/bug68799.jpgbin0 -> 735 bytes
-rw-r--r--ext/exif/tests/bug68799.phpt63
-rw-r--r--ext/fileinfo/config.m42
-rw-r--r--ext/fileinfo/config.w322
-rw-r--r--ext/fileinfo/libmagic.patch454
-rw-r--r--ext/fileinfo/libmagic/file.h2
-rw-r--r--ext/fileinfo/libmagic/readelf.c1207
-rw-r--r--ext/fileinfo/libmagic/readelf.h333
-rw-r--r--ext/fileinfo/libmagic/softmagic.c7
-rw-r--r--ext/fileinfo/tests/bug68735.jpgbin0 -> 24 bytes
-rw-r--r--ext/fileinfo/tests/bug68735.phpt16
-rwxr-xr-xext/openssl/openssl.c4
-rw-r--r--ext/standard/tests/strings/bug68710.phpt25
-rw-r--r--ext/standard/var_unserializer.c4
-rw-r--r--ext/standard/var_unserializer.re2
16 files changed, 256 insertions, 1867 deletions
diff --git a/ext/exif/exif.c b/ext/exif/exif.c
index 637ebf928..7f95ff43e 100644
--- a/ext/exif/exif.c
+++ b/ext/exif/exif.c
@@ -2702,7 +2702,7 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP
static int exif_process_unicode(image_info_type *ImageInfo, xp_field_type *xp_field, int tag, char *szValuePtr, int ByteCount TSRMLS_DC)
{
xp_field->tag = tag;
-
+ xp_field->value = NULL;
/* XXX this will fail again if encoding_converter returns on error something different than SIZE_MAX */
if (zend_multibyte_encoding_converter(
(unsigned char**)&xp_field->value,
diff --git a/ext/exif/tests/bug68799.jpg b/ext/exif/tests/bug68799.jpg
new file mode 100644
index 000000000..acc326dbb
--- /dev/null
+++ b/ext/exif/tests/bug68799.jpg
Binary files differ
diff --git a/ext/exif/tests/bug68799.phpt b/ext/exif/tests/bug68799.phpt
new file mode 100644
index 000000000..b09f21ca7
--- /dev/null
+++ b/ext/exif/tests/bug68799.phpt
@@ -0,0 +1,63 @@
+--TEST--
+Bug #68799 (Free called on unitialized pointer)
+--SKIPIF--
+<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
+--FILE--
+<?php
+/*
+* Pollute the heap. Helps trigger bug. Sometimes not needed.
+*/
+class A {
+ function __construct() {
+ $a = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa';
+ $this->a = $a . $a . $a . $a . $a . $a;
+ }
+};
+
+function doStuff ($limit) {
+
+ $a = new A;
+
+ $b = array();
+ for ($i = 0; $i < $limit; $i++) {
+ $b[$i] = clone $a;
+ }
+
+ unset($a);
+
+ gc_collect_cycles();
+}
+
+$iterations = 3;
+
+doStuff($iterations);
+doStuff($iterations);
+
+gc_collect_cycles();
+
+print_r(exif_read_data(__DIR__.'/bug68799.jpg'));
+
+?>
+--EXPECTF--
+Array
+(
+ [FileName] => bug68799.jpg
+ [FileDateTime] => %d
+ [FileSize] => 735
+ [FileType] => 2
+ [MimeType] => image/jpeg
+ [SectionsFound] => ANY_TAG, IFD0, WINXP
+ [COMPUTED] => Array
+ (
+ [html] => width="1" height="1"
+ [Height] => 1
+ [Width] => 1
+ [IsColor] => 1
+ [ByteOrderMotorola] => 1
+ )
+
+ [XResolution] => 96/1
+ [YResolution] => 96/1
+ [ResolutionUnit] => 2
+ [Author] =>
+)
diff --git a/ext/fileinfo/config.m4 b/ext/fileinfo/config.m4
index 4f3404125..b8908208b 100644
--- a/ext/fileinfo/config.m4
+++ b/ext/fileinfo/config.m4
@@ -11,7 +11,7 @@ if test "$PHP_FILEINFO" != "no"; then
libmagic/cdf.c libmagic/cdf_time.c libmagic/compress.c \
libmagic/encoding.c libmagic/fsmagic.c libmagic/funcs.c \
libmagic/is_tar.c libmagic/magic.c libmagic/print.c \
- libmagic/readcdf.c libmagic/readelf.c libmagic/softmagic.c"
+ libmagic/readcdf.c libmagic/softmagic.c"
PHP_NEW_EXTENSION(fileinfo, fileinfo.c $libmagic_sources, $ext_shared,,-I@ext_srcdir@/libmagic)
PHP_ADD_BUILD_DIR($ext_builddir/libmagic)
diff --git a/ext/fileinfo/config.w32 b/ext/fileinfo/config.w32
index 873a12c2f..9a1492132 100644
--- a/ext/fileinfo/config.w32
+++ b/ext/fileinfo/config.w32
@@ -8,7 +8,7 @@ if (PHP_FILEINFO != 'no') {
cdf.c cdf_time.c compress.c \
encoding.c fsmagic.c funcs.c \
is_tar.c magic.c print.c \
- readcdf.c readelf.c softmagic.c";
+ readcdf.c softmagic.c";
if (VCVERS < 1500) {
ADD_FLAG('CFLAGS', '/Zm1000');
diff --git a/ext/fileinfo/libmagic.patch b/ext/fileinfo/libmagic.patch
index a91a65839..fe734f30b 100644
--- a/ext/fileinfo/libmagic.patch
+++ b/ext/fileinfo/libmagic.patch
@@ -1,6 +1,6 @@
diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
--- libmagic.orig/apprentice.c Thu Mar 21 18:45:14 2013
-+++ libmagic/apprentice.c Mon Apr 14 23:42:51 2014
++++ libmagic/apprentice.c Sun Jan 4 17:02:29 2015
@@ -29,6 +29,8 @@
* apprentice - make one pass through /etc/magic, learning its secrets.
*/
@@ -479,6 +479,15 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
return NULL;
}
return map;
+@@ -1233,7 +1269,7 @@
+ * the sign extension must have happened.
+ */
+ case FILE_BYTE:
+- v = (char) v;
++ v = (signed char) v;
+ break;
+ case FILE_SHORT:
+ case FILE_BESHORT:
@@ -1500,7 +1536,7 @@
if (me->cont_count == me->max_count) {
struct magic *nm;
@@ -833,7 +842,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
}
diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c
--- libmagic.orig/ascmagic.c Wed Oct 31 18:03:01 2012
-+++ libmagic/ascmagic.c Mon Apr 14 23:42:51 2014
++++ libmagic/ascmagic.c Sun Jan 4 17:02:29 2015
@@ -139,7 +139,7 @@
/* malloc size is a conservative overestimate; could be
improved, or at least realloced after conversion. */
@@ -872,7 +881,7 @@ diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c
}
diff -u libmagic.orig/cdf.c libmagic/cdf.c
--- libmagic.orig/cdf.c Thu Mar 21 18:45:14 2013
-+++ libmagic/cdf.c Tue Jul 1 09:00:09 2014
++++ libmagic/cdf.c Sun Jan 4 17:02:29 2015
@@ -43,7 +43,17 @@
#include <err.h>
#endif
@@ -955,7 +964,7 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c
errno = EFTYPE;
return (size_t)-1;
}
-@@ -796,7 +812,11 @@
+@@ -796,11 +812,15 @@
if (cdf_check_stream_offset(sst, h, e, 0, __LINE__) == -1)
goto out;
for (i = 0; i < sh.sh_properties; i++) {
@@ -968,6 +977,11 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c
q = (const uint8_t *)(const void *)
((const char *)(const void *)p + ofs
- 2 * sizeof(uint32_t));
+- if (q > e) {
++ if (q < p || q > e) {
+ DPRINTF(("Ran of the end %p > %p\n", q, e));
+ goto out;
+ }
@@ -810,6 +830,10 @@
i, inp[i].pi_id, inp[i].pi_type, q - p, offs));
if (inp[i].pi_type & CDF_VECTOR) {
@@ -1056,7 +1070,7 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c
} else {
diff -u libmagic.orig/cdf.h libmagic/cdf.h
--- libmagic.orig/cdf.h Wed Oct 31 18:03:01 2012
-+++ libmagic/cdf.h Mon Apr 14 23:32:55 2014
++++ libmagic/cdf.h Sun Jan 4 17:02:29 2015
@@ -35,10 +35,12 @@
#ifndef _H_CDF_
#define _H_CDF_
@@ -1099,7 +1113,7 @@ diff -u libmagic.orig/cdf.h libmagic/cdf.h
void cdf_unpack_header(cdf_header_t *, char *);
diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c
--- libmagic.orig/cdf_time.c Wed Oct 31 18:03:01 2012
-+++ libmagic/cdf_time.c Mon Apr 14 23:32:55 2014
++++ libmagic/cdf_time.c Sun Nov 9 19:16:18 2014
@@ -96,7 +96,7 @@
}
@@ -1159,7 +1173,7 @@ diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c
static const char *ref = "Sat Apr 23 01:30:00 1977";
diff -u libmagic.orig/compress.c libmagic/compress.c
--- libmagic.orig/compress.c Sun Jan 6 21:35:43 2013
-+++ libmagic/compress.c Mon Apr 14 23:42:51 2014
++++ libmagic/compress.c Sun Jan 4 17:02:29 2015
@@ -32,6 +32,7 @@
* uncompress(method, old, n, newch) - uncompress old into new,
* using method, return sizeof new
@@ -1322,7 +1336,7 @@ diff -u libmagic.orig/compress.c libmagic/compress.c
+#endif /* if PHP_FILEINFO_UNCOMPRESS */
diff -u libmagic.orig/file.h libmagic/file.h
--- libmagic.orig/file.h Mon Feb 18 16:40:59 2013
-+++ libmagic/file.h Mon Apr 14 23:42:51 2014
++++ libmagic/file.h Sun Jan 4 17:02:29 2015
@@ -33,11 +33,9 @@
#ifndef __file_h__
#define __file_h__
@@ -1409,7 +1423,7 @@ diff -u libmagic.orig/file.h libmagic/file.h
void *map; /* internal resources used by entry */
struct mlist *next, *prev;
};
-@@ -411,21 +413,18 @@
+@@ -411,21 +413,16 @@
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 *);
@@ -1426,8 +1440,8 @@ diff -u libmagic.orig/file.h libmagic/file.h
- __attribute__((__format__(__printf__, 2, 3)));
+protected int file_printf(struct magic_set *, const char *, ...);
protected int file_reset(struct magic_set *);
- protected int file_tryelf(struct magic_set *, int, const unsigned char *,
- size_t);
+-protected int file_tryelf(struct magic_set *, int, const unsigned char *,
+- size_t);
protected int file_trycdf(struct magic_set *, int, const unsigned char *,
size_t);
-#if HAVE_FORK
@@ -1435,7 +1449,7 @@ diff -u libmagic.orig/file.h libmagic/file.h
protected int file_zmagic(struct magic_set *, int, const char *,
const unsigned char *, size_t);
#endif
-@@ -438,21 +437,18 @@
+@@ -438,21 +435,18 @@
unichar **, size_t *, const char **, const char **, const char **);
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,
@@ -1462,7 +1476,7 @@ diff -u libmagic.orig/file.h libmagic/file.h
protected void file_showstr(FILE *, const char *, size_t);
protected size_t file_mbswidth(const char *);
protected const char *file_getbuffer(struct magic_set *);
-@@ -462,16 +458,14 @@
+@@ -462,16 +456,14 @@
size_t *);
protected size_t file_pstring_length_size(const struct magic *);
protected size_t file_pstring_get_length(const struct magic *, const char *);
@@ -1480,7 +1494,7 @@ diff -u libmagic.orig/file.h libmagic/file.h
#ifndef HAVE_STRERROR
extern int sys_nerr;
-@@ -484,32 +478,16 @@
+@@ -484,32 +476,16 @@
#define strtoul(a, b, c) strtol(a, b, c)
#endif
@@ -1515,7 +1529,7 @@ diff -u libmagic.orig/file.h libmagic/file.h
#if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK)
#define QUICK
-@@ -531,6 +509,14 @@
+@@ -531,6 +507,14 @@
#endif
#else
#define FILE_RCSID(id)
@@ -1532,7 +1546,7 @@ diff -u libmagic.orig/file.h libmagic/file.h
#endif /* __file_h__ */
diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
--- libmagic.orig/fsmagic.c Thu Mar 21 18:45:14 2013
-+++ libmagic/fsmagic.c Mon Apr 14 23:42:51 2014
++++ libmagic/fsmagic.c Sun Jan 4 17:02:29 2015
@@ -59,27 +59,21 @@
# define minor(dev) ((dev) & 0xff)
#endif
@@ -1899,7 +1913,7 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
}
diff -u libmagic.orig/funcs.c libmagic/funcs.c
--- libmagic.orig/funcs.c Wed Oct 31 18:03:01 2012
-+++ libmagic/funcs.c Mon Apr 14 23:42:51 2014
++++ libmagic/funcs.c Sun Jan 4 17:02:29 2015
@@ -41,52 +41,42 @@
#if defined(HAVE_WCTYPE_H)
#include <wctype.h>
@@ -2193,7 +2207,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
+
diff -u libmagic.orig/magic.c libmagic/magic.c
--- libmagic.orig/magic.c Fri Jan 11 17:43:09 2013
-+++ libmagic/magic.c Mon Apr 14 23:42:51 2014
++++ libmagic/magic.c Sun Jan 4 17:02:29 2015
@@ -25,11 +25,6 @@
* SUCH DAMAGE.
*/
@@ -2537,7 +2551,7 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
magic_error(struct magic_set *ms)
diff -u libmagic.orig/magic.h libmagic/magic.h
--- libmagic.orig/magic.h Thu Mar 21 18:52:42 2013
-+++ libmagic/magic.h Mon Apr 14 23:42:51 2014
++++ libmagic/magic.h Sun Jan 4 17:02:29 2015
@@ -87,6 +87,7 @@
const char *magic_getpath(const char *, int);
@@ -2556,7 +2570,7 @@ diff -u libmagic.orig/magic.h libmagic/magic.h
diff -u libmagic.orig/print.c libmagic/print.c
--- libmagic.orig/print.c Thu Mar 21 18:45:14 2013
-+++ libmagic/print.c Mon Apr 14 23:42:51 2014
++++ libmagic/print.c Sun Jan 4 17:02:29 2015
@@ -29,12 +29,17 @@
* print.c - debugging printout routines
*/
@@ -2787,7 +2801,7 @@ diff -u libmagic.orig/print.c libmagic/print.c
}
diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
--- libmagic.orig/readcdf.c Wed Oct 31 18:03:01 2012
-+++ libmagic/readcdf.c Tue May 27 22:17:37 2014
++++ libmagic/readcdf.c Sun Jan 4 17:02:29 2015
@@ -30,7 +30,11 @@
#endif
@@ -2861,282 +2875,9 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
} else {
if (file_printf(ms, "application/CDFV2-corrupt") == -1)
return -1;
-diff -u libmagic.orig/readelf.c libmagic/readelf.c
---- libmagic.orig/readelf.c Thu Mar 21 18:45:14 2013
-+++ libmagic/readelf.c Mon Apr 14 23:42:51 2014
-@@ -48,8 +48,8 @@
- private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t,
- off_t, int *, int);
- private int doshn(struct magic_set *, int, int, int, off_t, int, size_t,
-- off_t, int *, int, int);
--private size_t donote(struct magic_set *, void *, size_t, size_t, int,
-+ off_t, int *, int);
-+private size_t donote(struct magic_set *, unsigned char *, size_t, size_t, int,
- int, size_t, int *);
-
- #define ELF_ALIGN(a) ((((a) + align - 1) / align) * align)
-@@ -127,11 +127,17 @@
-
- #define elf_getu16(swap, value) getu16(swap, value)
- #define elf_getu32(swap, value) getu32(swap, value)
--#define elf_getu64(swap, value) getu64(swap, value)
-+#ifdef USE_ARRAY_FOR_64BIT_TYPES
-+# define elf_getu64(swap, array) \
-+ ((swap ? ((uint64_t)elf_getu32(swap, array[0])) << 32 : elf_getu32(swap, array[0])) + \
-+ (swap ? elf_getu32(swap, array[1]) : ((uint64_t)elf_getu32(swap, array[1]) << 32)))
-+#else
-+# define elf_getu64(swap, value) getu64(swap, value)
-+#endif
-
- #define xsh_addr (clazz == ELFCLASS32 \
-- ? (void *)&sh32 \
-- : (void *)&sh64)
-+ ? (void *) &sh32 \
-+ : (void *) &sh64)
- #define xsh_sizeof (clazz == ELFCLASS32 \
- ? sizeof(sh32) \
- : sizeof(sh64))
-@@ -168,8 +174,8 @@
- ? elf_getu32(swap, ph32.p_filesz) \
- : elf_getu64(swap, ph64.p_filesz)))
- #define xnh_addr (clazz == ELFCLASS32 \
-- ? (void *)&nh32 \
-- : (void *)&nh64)
-+ ? (void *) &nh32 \
-+ : (void *) &nh64)
- #define xph_memsz (size_t)((clazz == ELFCLASS32 \
- ? elf_getu32(swap, ph32.p_memsz) \
- : elf_getu64(swap, ph64.p_memsz)))
-@@ -189,8 +195,8 @@
- ? prpsoffsets32[i] \
- : prpsoffsets64[i])
- #define xcap_addr (clazz == ELFCLASS32 \
-- ? (void *)&cap32 \
-- : (void *)&cap64)
-+ ? (void *) &cap32 \
-+ : (void *) &cap64)
- #define xcap_sizeof (clazz == ELFCLASS32 \
- ? sizeof cap32 \
- : sizeof cap64)
-@@ -292,7 +298,7 @@
- {
- Elf32_Phdr ph32;
- Elf64_Phdr ph64;
-- size_t offset, len;
-+ size_t offset;
- unsigned char nbuf[BUFSIZ];
- ssize_t bufsize;
-
-@@ -306,7 +312,11 @@
- * Loop through all the program headers.
- */
- for ( ; num; num--) {
-- if (pread(fd, xph_addr, xph_sizeof, off) == -1) {
-+ if (FINFO_LSEEK_FUNC(fd, off, SEEK_SET) == (off_t)-1) {
-+ file_badseek(ms);
-+ return -1;
-+ }
-+ if (FINFO_READ_FUNC(fd, xph_addr, xph_sizeof) == -1) {
- file_badread(ms);
- return -1;
- }
-@@ -324,8 +334,13 @@
- * This is a PT_NOTE section; loop through all the notes
- * in the section.
- */
-- len = xph_filesz < sizeof(nbuf) ? xph_filesz : sizeof(nbuf);
-- if ((bufsize = pread(fd, nbuf, len, xph_offset)) == -1) {
-+ if (FINFO_LSEEK_FUNC(fd, xph_offset, SEEK_SET) == (off_t)-1) {
-+ file_badseek(ms);
-+ return -1;
-+ }
-+ bufsize = FINFO_READ_FUNC(fd, nbuf,
-+ ((xph_filesz < sizeof(nbuf)) ? xph_filesz : sizeof(nbuf)));
-+ if (bufsize == -1) {
- file_badread(ms);
- return -1;
- }
-@@ -852,24 +867,12 @@
- return 0;
- }
-
-- /* Read offset of name section to be able to read section names later */
-- if (pread(fd, xsh_addr, xsh_sizeof, off + size * strtab) == -1) {
-- file_badread(ms);
-- return -1;
-- }
-- name_off = xsh_offset;
--
- for ( ; num; num--) {
-- /* Read the name of this section. */
-- if (pread(fd, name, sizeof(name), name_off + xsh_name) == -1) {
-- file_badread(ms);
-+ if (FINFO_LSEEK_FUNC(fd, off, SEEK_SET) == (off_t)-1) {
-+ file_badseek(ms);
- return -1;
- }
-- name[sizeof(name) - 1] = '\0';
-- if (strcmp(name, ".debug_info") == 0)
-- stripped = 0;
--
-- if (pread(fd, xsh_addr, xsh_sizeof, off) == -1) {
-+ if (FINFO_READ_FUNC(fd, xsh_addr, xsh_sizeof) == -1) {
- file_badread(ms);
- return -1;
- }
-@@ -894,14 +897,17 @@
- /* Things we can determine when we seek */
- switch (xsh_type) {
- case SHT_NOTE:
-- if ((nbuf = malloc(xsh_size)) == NULL) {
-- file_error(ms, errno, "Cannot allocate memory"
-- " for note");
-+ nbuf = emalloc((size_t)xsh_size);
-+ if ((noff = FINFO_LSEEK_FUNC(fd, (off_t)xsh_offset, SEEK_SET)) ==
-+ (off_t)-1) {
-+ file_badread(ms);
-+ efree(nbuf);
- return -1;
- }
-- if (pread(fd, nbuf, xsh_size, xsh_offset) == -1) {
-+ if (FINFO_READ_FUNC(fd, nbuf, (size_t)xsh_size) !=
-+ (ssize_t)xsh_size) {
-+ efree(nbuf);
- file_badread(ms);
-- free(nbuf);
- return -1;
- }
-
-@@ -910,25 +916,16 @@
- if (noff >= (off_t)xsh_size)
- break;
- noff = donote(ms, nbuf, (size_t)noff,
-- xsh_size, clazz, swap, 4, flags);
-+ (size_t)xsh_size, clazz, swap, 4,
-+ flags);
- if (noff == 0)
- break;
- }
-- free(nbuf);
-+ efree(nbuf);
- break;
- case SHT_SUNW_cap:
-- switch (mach) {
-- case EM_SPARC:
-- case EM_SPARCV9:
-- case EM_IA_64:
-- case EM_386:
-- case EM_AMD64:
-- break;
-- default:
-- goto skip;
-- }
--
-- if (lseek(fd, xsh_offset, SEEK_SET) == (off_t)-1) {
-+ if (FINFO_LSEEK_FUNC(fd, (off_t)xsh_offset, SEEK_SET) ==
-+ (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
-@@ -940,7 +937,7 @@
- MAX(sizeof cap32, sizeof cap64)];
- if ((coff += xcap_sizeof) > (off_t)xsh_size)
- break;
-- if (read(fd, cbuf, (size_t)xcap_sizeof) !=
-+ if (FINFO_READ_FUNC(fd, cbuf, (size_t)xcap_sizeof) !=
- (ssize_t)xcap_sizeof) {
- file_badread(ms);
- return -1;
-@@ -966,13 +963,12 @@
- break;
- }
- }
-- /*FALLTHROUGH*/
-- skip:
-+ break;
-+
- default:
- break;
- }
- }
--
- if (file_printf(ms, ", %sstripped", stripped ? "" : "not ") == -1)
- return -1;
- if (cap_hw1) {
-@@ -1051,7 +1047,7 @@
- const char *shared_libraries = "";
- unsigned char nbuf[BUFSIZ];
- ssize_t bufsize;
-- size_t offset, align, len;
-+ size_t offset, align;
-
- if (size != xph_sizeof) {
- if (file_printf(ms, ", corrupted program header size") == -1)
-@@ -1060,8 +1056,13 @@
- }
-
- for ( ; num; num--) {
-- if (pread(fd, xph_addr, xph_sizeof, off) == -1) {
-- file_badread(ms);
-+ if (FINFO_LSEEK_FUNC(fd, off, SEEK_SET) == (off_t)-1) {
-+ file_badseek(ms);
-+ return -1;
-+ }
-+
-+ if (FINFO_READ_FUNC(fd, xph_addr, xph_sizeof) == -1) {
-+ file_badread(ms);
- return -1;
- }
-
-@@ -1099,9 +1100,12 @@
- * This is a PT_NOTE section; loop through all the notes
- * in the section.
- */
-- len = xph_filesz < sizeof(nbuf) ? xph_filesz
-- : sizeof(nbuf);
-- bufsize = pread(fd, nbuf, len, xph_offset);
-+ if (FINFO_LSEEK_FUNC(fd, xph_offset, SEEK_SET) == (off_t)-1) {
-+ file_badseek(ms);
-+ return -1;
-+ }
-+ bufsize = FINFO_READ_FUNC(fd, nbuf, ((xph_filesz < sizeof(nbuf)) ?
-+ xph_filesz : sizeof(nbuf)));
- if (bufsize == -1) {
- file_badread(ms);
- return -1;
-@@ -1162,7 +1166,7 @@
- /*
- * If we cannot seek, it must be a pipe, socket or fifo.
- */
-- if((lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE))
-+ if((FINFO_LSEEK_FUNC(fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE))
- fd = file_pipe2file(ms, fd, buf, nbytes);
-
- if (fstat(fd, &st) == -1) {
-diff -u libmagic.orig/readelf.h libmagic/readelf.h
---- libmagic.orig/readelf.h Thu Mar 21 18:45:14 2013
-+++ libmagic/readelf.h Mon Apr 14 23:42:51 2014
-@@ -44,9 +44,17 @@
- typedef uint32_t Elf32_Word;
- typedef uint8_t Elf32_Char;
-
-+#if SIZEOF_LONG_LONG != 8
-+#define USE_ARRAY_FOR_64BIT_TYPES
-+typedef uint32_t Elf64_Addr[2];
-+typedef uint32_t Elf64_Off[2];
-+typedef uint32_t Elf64_Xword[2];
-+#else
-+#undef USE_ARRAY_FOR_64BIT_TYPES
- typedef uint64_t Elf64_Addr;
- typedef uint64_t Elf64_Off;
- typedef uint64_t Elf64_Xword;
-+#endif
- typedef uint16_t Elf64_Half;
- typedef uint32_t Elf64_Word;
- typedef uint8_t Elf64_Char;
diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
--- libmagic.orig/softmagic.c Thu Mar 21 18:45:14 2013
-+++ libmagic/softmagic.c Tue Jul 1 09:00:09 2014
++++ libmagic/softmagic.c Sun Jan 4 17:02:29 2015
@@ -41,6 +41,11 @@
#include <stdlib.h>
#include <time.h>
@@ -3149,6 +2890,15 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
private int match(struct magic_set *, struct magic *, uint32_t,
const unsigned char *, size_t, size_t, int, int, int, int, int *, int *,
+@@ -53,7 +58,7 @@
+ private int32_t moffset(struct magic_set *, struct magic *);
+ private void mdebug(uint32_t, const char *, size_t);
+ private int mcopy(struct magic_set *, union VALUETYPE *, int, int,
+- const unsigned char *, uint32_t, size_t, size_t);
++ const unsigned char *, uint32_t, size_t, struct magic *);
+ private int mconvert(struct magic_set *, struct magic *, int);
+ private int print_sep(struct magic_set *, int);
+ private int handle_annotation(struct magic_set *, struct magic *);
@@ -62,6 +67,8 @@
private void cvt_32(union VALUETYPE *, const struct magic *);
private void cvt_64(union VALUETYPE *, const struct magic *);
@@ -3286,7 +3036,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
break; \
} \
-@@ -896,10 +881,18 @@
+@@ -896,10 +881,21 @@
return 1;
}
case FILE_PSTRING: {
@@ -3296,21 +3046,87 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
size_t len = file_pstring_get_length(m, ptr1);
- if (len >= sizeof(p->s))
- len = sizeof(p->s) - 1;
-+ if (len >= sizeof(p->s)) {
++ sz = sizeof(p->s) - sz; /* maximum length of string */
++ if (len >= sz) {
+ /*
+ * The size of the pascal string length (sz)
+ * is 1, 2, or 4. We need at least 1 byte for NUL
+ * termination, but we've already truncated the
+ * string by p->s, so we need to deduct sz.
++ * Because we can use one of the bytes of the length
++ * after we shifted as NUL termination.
+ */
-+ len = sizeof(p->s) - sz;
++ len = sz;
+ }
while (len--)
*ptr1++ = *ptr2++;
*ptr1 = '\0';
-@@ -1145,9 +1138,6 @@
- "nbytes=%zu, count=%u)\n", m->type, m->flag, offset, o,
- nbytes, count);
+@@ -1010,7 +1006,7 @@
+
+ private int
+ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
+- const unsigned char *s, uint32_t offset, size_t nbytes, size_t linecnt)
++ const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m)
+ {
+ /*
+ * Note: FILE_SEARCH and FILE_REGEX do not actually copy
+@@ -1030,15 +1026,24 @@
+ const char *last; /* end of search region */
+ const char *buf; /* start of search region */
+ const char *end;
+- size_t lines;
++ size_t lines, linecnt, bytecnt;
++
++ linecnt = m->str_range;
++ bytecnt = linecnt * 80;
+
++ if (bytecnt == 0) {
++ bytecnt = 8192;
++ }
++ if (bytecnt > nbytes) {
++ bytecnt = nbytes;
++ }
+ if (s == NULL) {
+ ms->search.s_len = 0;
+ ms->search.s = NULL;
+ return 0;
+ }
+ buf = RCAST(const char *, s) + offset;
+- end = last = RCAST(const char *, s) + nbytes;
++ end = last = RCAST(const char *, s) + bytecnt;
+ /* mget() guarantees buf <= last */
+ for (lines = linecnt, b = buf; lines && b < end &&
+ ((b = CAST(const char *,
+@@ -1051,7 +1056,7 @@
+ b++;
+ }
+ if (lines)
+- last = RCAST(const char *, s) + nbytes;
++ last = RCAST(const char *, s) + bytecnt;
+
+ ms->search.s = buf;
+ ms->search.s_len = last - buf;
+@@ -1125,7 +1130,6 @@
+ int *need_separator, int *returnval)
+ {
+ uint32_t soffset, offset = ms->offset;
+- uint32_t count = m->str_range;
+ int rv, oneed_separator;
+ char *sbuf, *rbuf;
+ union VALUETYPE *p = &ms->ms_value;
+@@ -1137,17 +1141,13 @@
+ }
+
+ if (mcopy(ms, p, m->type, m->flag & INDIR, s, (uint32_t)(offset + o),
+- (uint32_t)nbytes, count) == -1)
++ (uint32_t)nbytes, m) == -1)
+ return -1;
+
+ if ((ms->flags & MAGIC_DEBUG) != 0) {
+ fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, o=%zu, "
+- "nbytes=%zu, count=%u)\n", m->type, m->flag, offset, o,
+- nbytes, count);
++ "nbytes=%zu)\n", m->type, m->flag, offset, o, nbytes);
mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
-#ifndef COMPILE_ONLY
- file_mdump(m);
@@ -3318,7 +3134,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
}
if (m->flag & INDIR) {
-@@ -1191,7 +1181,7 @@
+@@ -1191,7 +1191,7 @@
}
switch (cvt_flip(m->in_type, flip)) {
case FILE_BYTE:
@@ -3327,7 +3143,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
return 0;
if (off) {
switch (m->in_op & FILE_OPS_MASK) {
-@@ -1226,7 +1216,7 @@
+@@ -1226,7 +1226,7 @@
offset = ~offset;
break;
case FILE_BESHORT:
@@ -3336,7 +3152,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
return 0;
if (off) {
switch (m->in_op & FILE_OPS_MASK) {
-@@ -1278,7 +1268,7 @@
+@@ -1278,7 +1278,7 @@
offset = ~offset;
break;
case FILE_LESHORT:
@@ -3345,7 +3161,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
return 0;
if (off) {
switch (m->in_op & FILE_OPS_MASK) {
-@@ -1330,7 +1320,7 @@
+@@ -1330,7 +1330,7 @@
offset = ~offset;
break;
case FILE_SHORT:
@@ -3354,7 +3170,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
return 0;
if (off) {
switch (m->in_op & FILE_OPS_MASK) {
-@@ -1367,7 +1357,7 @@
+@@ -1367,7 +1367,7 @@
break;
case FILE_BELONG:
case FILE_BEID3:
@@ -3363,7 +3179,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
return 0;
if (off) {
switch (m->in_op & FILE_OPS_MASK) {
-@@ -1438,7 +1428,7 @@
+@@ -1438,7 +1438,7 @@
break;
case FILE_LELONG:
case FILE_LEID3:
@@ -3372,7 +3188,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
return 0;
if (off) {
switch (m->in_op & FILE_OPS_MASK) {
-@@ -1508,7 +1498,7 @@
+@@ -1508,7 +1508,7 @@
offset = ~offset;
break;
case FILE_MELONG:
@@ -3381,7 +3197,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
return 0;
if (off) {
switch (m->in_op & FILE_OPS_MASK) {
-@@ -1578,7 +1568,7 @@
+@@ -1578,7 +1578,7 @@
offset = ~offset;
break;
case FILE_LONG:
@@ -3390,7 +3206,15 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
return 0;
if (off) {
switch (m->in_op & FILE_OPS_MASK) {
-@@ -1644,23 +1634,20 @@
+@@ -1637,30 +1637,27 @@
+ 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, m) == -1)
+ return -1;
+ ms->offset = offset;
+
if ((ms->flags & MAGIC_DEBUG) != 0) {
mdebug(offset, (char *)(void *)p,
sizeof(union VALUETYPE));
@@ -3416,7 +3240,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
return 0;
break;
-@@ -1679,38 +1666,40 @@
+@@ -1679,38 +1676,40 @@
case FILE_FLOAT:
case FILE_BEFLOAT:
case FILE_LEFLOAT:
@@ -3463,7 +3287,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
if ((ms->flags & MAGIC_DEBUG) != 0)
fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
rbuf = ms->o.buf;
-@@ -1718,16 +1707,26 @@
+@@ -1718,16 +1717,26 @@
ms->offset = soffset;
if (rv == 1) {
if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
@@ -3494,7 +3318,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
return 0;
sbuf = m->value.s;
if (*sbuf == '^') {
-@@ -1837,6 +1836,42 @@
+@@ -1837,6 +1846,42 @@
return file_strncmp(a, b, len, flags);
}
@@ -3537,7 +3361,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
private int
magiccheck(struct magic_set *ms, struct magic *m)
{
-@@ -1996,69 +2031,157 @@
+@@ -1996,69 +2041,157 @@
break;
}
case FILE_REGEX: {
@@ -3608,7 +3432,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
+ zval *retval;
+ zval *subpats;
+ char *haystack;
-+
++
+ MAKE_STD_ZVAL(retval);
+ ALLOC_INIT_ZVAL(subpats);
+
diff --git a/ext/fileinfo/libmagic/file.h b/ext/fileinfo/libmagic/file.h
index ab5082d75..a0976cdea 100644
--- a/ext/fileinfo/libmagic/file.h
+++ b/ext/fileinfo/libmagic/file.h
@@ -420,8 +420,6 @@ protected int file_pipe2file(struct magic_set *, int, const void *, size_t);
protected int file_replace(struct magic_set *, const char *, const char *);
protected int file_printf(struct magic_set *, const char *, ...);
protected int file_reset(struct magic_set *);
-protected int file_tryelf(struct magic_set *, int, const unsigned char *,
- size_t);
protected int file_trycdf(struct magic_set *, int, const unsigned char *,
size_t);
#ifdef PHP_FILEINFO_UNCOMPRESS
diff --git a/ext/fileinfo/libmagic/readelf.c b/ext/fileinfo/libmagic/readelf.c
deleted file mode 100644
index bb6f70fb8..000000000
--- a/ext/fileinfo/libmagic/readelf.c
+++ /dev/null
@@ -1,1207 +0,0 @@
-/*
- * Copyright (c) Christos Zoulas 2003.
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#include "file.h"
-
-#ifndef lint
-FILE_RCSID("@(#)$File: readelf.c,v 1.97 2013/03/06 03:35:30 christos Exp $")
-#endif
-
-#ifdef BUILTIN_ELF
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "readelf.h"
-#include "magic.h"
-
-#ifdef ELFCORE
-private int dophn_core(struct magic_set *, int, int, int, off_t, int, size_t,
- off_t, int *);
-#endif
-private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t,
- off_t, int *, int);
-private int doshn(struct magic_set *, int, int, int, off_t, int, size_t,
- off_t, int *, int);
-private size_t donote(struct magic_set *, unsigned char *, size_t, size_t, int,
- int, size_t, int *);
-
-#define ELF_ALIGN(a) ((((a) + align - 1) / align) * align)
-
-#define isquote(c) (strchr("'\"`", (c)) != NULL)
-
-private uint16_t getu16(int, uint16_t);
-private uint32_t getu32(int, uint32_t);
-private uint64_t getu64(int, uint64_t);
-
-private uint16_t
-getu16(int swap, uint16_t value)
-{
- union {
- uint16_t ui;
- char c[2];
- } retval, tmpval;
-
- if (swap) {
- tmpval.ui = value;
-
- retval.c[0] = tmpval.c[1];
- retval.c[1] = tmpval.c[0];
-
- return retval.ui;
- } else
- return value;
-}
-
-private uint32_t
-getu32(int swap, uint32_t value)
-{
- union {
- uint32_t ui;
- char c[4];
- } retval, tmpval;
-
- if (swap) {
- tmpval.ui = value;
-
- retval.c[0] = tmpval.c[3];
- retval.c[1] = tmpval.c[2];
- retval.c[2] = tmpval.c[1];
- retval.c[3] = tmpval.c[0];
-
- return retval.ui;
- } else
- return value;
-}
-
-private uint64_t
-getu64(int swap, uint64_t value)
-{
- union {
- uint64_t ui;
- char c[8];
- } retval, tmpval;
-
- if (swap) {
- tmpval.ui = value;
-
- retval.c[0] = tmpval.c[7];
- retval.c[1] = tmpval.c[6];
- retval.c[2] = tmpval.c[5];
- retval.c[3] = tmpval.c[4];
- retval.c[4] = tmpval.c[3];
- retval.c[5] = tmpval.c[2];
- retval.c[6] = tmpval.c[1];
- retval.c[7] = tmpval.c[0];
-
- return retval.ui;
- } else
- return value;
-}
-
-#define elf_getu16(swap, value) getu16(swap, value)
-#define elf_getu32(swap, value) getu32(swap, value)
-#ifdef USE_ARRAY_FOR_64BIT_TYPES
-# define elf_getu64(swap, array) \
- ((swap ? ((uint64_t)elf_getu32(swap, array[0])) << 32 : elf_getu32(swap, array[0])) + \
- (swap ? elf_getu32(swap, array[1]) : ((uint64_t)elf_getu32(swap, array[1]) << 32)))
-#else
-# define elf_getu64(swap, value) getu64(swap, value)
-#endif
-
-#define xsh_addr (clazz == ELFCLASS32 \
- ? (void *) &sh32 \
- : (void *) &sh64)
-#define xsh_sizeof (clazz == ELFCLASS32 \
- ? sizeof(sh32) \
- : sizeof(sh64))
-#define xsh_size (size_t)(clazz == ELFCLASS32 \
- ? elf_getu32(swap, sh32.sh_size) \
- : elf_getu64(swap, sh64.sh_size))
-#define xsh_offset (off_t)(clazz == ELFCLASS32 \
- ? elf_getu32(swap, sh32.sh_offset) \
- : elf_getu64(swap, sh64.sh_offset))
-#define xsh_type (clazz == ELFCLASS32 \
- ? elf_getu32(swap, sh32.sh_type) \
- : elf_getu32(swap, sh64.sh_type))
-#define xsh_name (clazz == ELFCLASS32 \
- ? elf_getu32(swap, sh32.sh_name) \
- : elf_getu32(swap, sh64.sh_name))
-#define xph_addr (clazz == ELFCLASS32 \
- ? (void *) &ph32 \
- : (void *) &ph64)
-#define xph_sizeof (clazz == ELFCLASS32 \
- ? sizeof(ph32) \
- : sizeof(ph64))
-#define xph_type (clazz == ELFCLASS32 \
- ? elf_getu32(swap, ph32.p_type) \
- : elf_getu32(swap, ph64.p_type))
-#define xph_offset (off_t)(clazz == ELFCLASS32 \
- ? elf_getu32(swap, ph32.p_offset) \
- : elf_getu64(swap, ph64.p_offset))
-#define xph_align (size_t)((clazz == ELFCLASS32 \
- ? (off_t) (ph32.p_align ? \
- elf_getu32(swap, ph32.p_align) : 4) \
- : (off_t) (ph64.p_align ? \
- elf_getu64(swap, ph64.p_align) : 4)))
-#define xph_filesz (size_t)((clazz == ELFCLASS32 \
- ? elf_getu32(swap, ph32.p_filesz) \
- : elf_getu64(swap, ph64.p_filesz)))
-#define xnh_addr (clazz == ELFCLASS32 \
- ? (void *) &nh32 \
- : (void *) &nh64)
-#define xph_memsz (size_t)((clazz == ELFCLASS32 \
- ? elf_getu32(swap, ph32.p_memsz) \
- : elf_getu64(swap, ph64.p_memsz)))
-#define xnh_sizeof (clazz == ELFCLASS32 \
- ? sizeof nh32 \
- : sizeof nh64)
-#define xnh_type (clazz == ELFCLASS32 \
- ? elf_getu32(swap, nh32.n_type) \
- : elf_getu32(swap, nh64.n_type))
-#define xnh_namesz (clazz == ELFCLASS32 \
- ? elf_getu32(swap, nh32.n_namesz) \
- : elf_getu32(swap, nh64.n_namesz))
-#define xnh_descsz (clazz == ELFCLASS32 \
- ? elf_getu32(swap, nh32.n_descsz) \
- : elf_getu32(swap, nh64.n_descsz))
-#define prpsoffsets(i) (clazz == ELFCLASS32 \
- ? prpsoffsets32[i] \
- : prpsoffsets64[i])
-#define xcap_addr (clazz == ELFCLASS32 \
- ? (void *) &cap32 \
- : (void *) &cap64)
-#define xcap_sizeof (clazz == ELFCLASS32 \
- ? sizeof cap32 \
- : sizeof cap64)
-#define xcap_tag (clazz == ELFCLASS32 \
- ? elf_getu32(swap, cap32.c_tag) \
- : elf_getu64(swap, cap64.c_tag))
-#define xcap_val (clazz == ELFCLASS32 \
- ? elf_getu32(swap, cap32.c_un.c_val) \
- : elf_getu64(swap, cap64.c_un.c_val))
-
-#ifdef ELFCORE
-/*
- * Try larger offsets first to avoid false matches
- * from earlier data that happen to look like strings.
- */
-static const size_t prpsoffsets32[] = {
-#ifdef USE_NT_PSINFO
- 104, /* SunOS 5.x (command line) */
- 88, /* SunOS 5.x (short name) */
-#endif /* USE_NT_PSINFO */
-
- 100, /* SunOS 5.x (command line) */
- 84, /* SunOS 5.x (short name) */
-
- 44, /* Linux (command line) */
- 28, /* Linux 2.0.36 (short name) */
-
- 8, /* FreeBSD */
-};
-
-static const size_t prpsoffsets64[] = {
-#ifdef USE_NT_PSINFO
- 152, /* SunOS 5.x (command line) */
- 136, /* SunOS 5.x (short name) */
-#endif /* USE_NT_PSINFO */
-
- 136, /* SunOS 5.x, 64-bit (command line) */
- 120, /* SunOS 5.x, 64-bit (short name) */
-
- 56, /* Linux (command line) */
- 40, /* Linux (tested on core from 2.4.x, short name) */
-
- 16, /* FreeBSD, 64-bit */
-};
-
-#define NOFFSETS32 (sizeof prpsoffsets32 / sizeof prpsoffsets32[0])
-#define NOFFSETS64 (sizeof prpsoffsets64 / sizeof prpsoffsets64[0])
-
-#define NOFFSETS (clazz == ELFCLASS32 ? NOFFSETS32 : NOFFSETS64)
-
-/*
- * Look through the program headers of an executable image, searching
- * for a PT_NOTE section of type NT_PRPSINFO, with a name "CORE" or
- * "FreeBSD"; if one is found, try looking in various places in its
- * contents for a 16-character string containing only printable
- * characters - if found, that string should be the name of the program
- * that dropped core. Note: right after that 16-character string is,
- * at least in SunOS 5.x (and possibly other SVR4-flavored systems) and
- * Linux, a longer string (80 characters, in 5.x, probably other
- * SVR4-flavored systems, and Linux) containing the start of the
- * command line for that program.
- *
- * SunOS 5.x core files contain two PT_NOTE sections, with the types
- * NT_PRPSINFO (old) and NT_PSINFO (new). These structs contain the
- * same info about the command name and command line, so it probably
- * isn't worthwhile to look for NT_PSINFO, but the offsets are provided
- * above (see USE_NT_PSINFO), in case we ever decide to do so. The
- * NT_PRPSINFO and NT_PSINFO sections are always in order and adjacent;
- * the SunOS 5.x file command relies on this (and prefers the latter).
- *
- * The signal number probably appears in a section of type NT_PRSTATUS,
- * but that's also rather OS-dependent, in ways that are harder to
- * dissect with heuristics, so I'm not bothering with the signal number.
- * (I suppose the signal number could be of interest in situations where
- * you don't have the binary of the program that dropped core; if you
- * *do* have that binary, the debugger will probably tell you what
- * signal it was.)
- */
-
-#define OS_STYLE_SVR4 0
-#define OS_STYLE_FREEBSD 1
-#define OS_STYLE_NETBSD 2
-
-private const char os_style_names[][8] = {
- "SVR4",
- "FreeBSD",
- "NetBSD",
-};
-
-#define FLAGS_DID_CORE 0x01
-#define FLAGS_DID_NOTE 0x02
-#define FLAGS_DID_BUILD_ID 0x04
-#define FLAGS_DID_CORE_STYLE 0x08
-#define FLAGS_IS_CORE 0x10
-
-private int
-dophn_core(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
- int num, size_t size, off_t fsize, int *flags)
-{
- Elf32_Phdr ph32;
- Elf64_Phdr ph64;
- size_t offset;
- unsigned char nbuf[BUFSIZ];
- ssize_t bufsize;
-
- if (size != xph_sizeof) {
- if (file_printf(ms, ", corrupted program header size") == -1)
- return -1;
- return 0;
- }
-
- /*
- * Loop through all the program headers.
- */
- for ( ; num; num--) {
- if (FINFO_LSEEK_FUNC(fd, off, SEEK_SET) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
- if (FINFO_READ_FUNC(fd, xph_addr, xph_sizeof) == -1) {
- file_badread(ms);
- return -1;
- }
- off += size;
-
- if (xph_offset > fsize) {
- /* Perhaps warn here */
- continue;
- }
-
- if (xph_type != PT_NOTE)
- continue;
-
- /*
- * This is a PT_NOTE section; loop through all the notes
- * in the section.
- */
- if (FINFO_LSEEK_FUNC(fd, xph_offset, SEEK_SET) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
- bufsize = FINFO_READ_FUNC(fd, nbuf,
- ((xph_filesz < sizeof(nbuf)) ? xph_filesz : sizeof(nbuf)));
- if (bufsize == -1) {
- file_badread(ms);
- return -1;
- }
- offset = 0;
- for (;;) {
- if (offset >= (size_t)bufsize)
- break;
- offset = donote(ms, nbuf, offset, (size_t)bufsize,
- clazz, swap, 4, flags);
- if (offset == 0)
- break;
-
- }
- }
- return 0;
-}
-#endif
-
-private size_t
-donote(struct magic_set *ms, void *vbuf, size_t offset, size_t size,
- int clazz, int swap, size_t align, int *flags)
-{
- Elf32_Nhdr nh32;
- Elf64_Nhdr nh64;
- size_t noff, doff;
-#ifdef ELFCORE
- int os_style = -1;
-#endif
- uint32_t namesz, descsz;
- unsigned char *nbuf = CAST(unsigned char *, vbuf);
-
- if (xnh_sizeof + offset > size) {
- /*
- * We're out of note headers.
- */
- return xnh_sizeof + offset;
- }
-
- (void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
- offset += xnh_sizeof;
-
- namesz = xnh_namesz;
- descsz = xnh_descsz;
- if ((namesz == 0) && (descsz == 0)) {
- /*
- * We're out of note headers.
- */
- return (offset >= size) ? offset : size;
- }
-
- if (namesz & 0x80000000) {
- (void)file_printf(ms, ", bad note name size 0x%lx",
- (unsigned long)namesz);
- return offset;
- }
-
- if (descsz & 0x80000000) {
- (void)file_printf(ms, ", bad note description size 0x%lx",
- (unsigned long)descsz);
- return offset;
- }
-
-
- noff = offset;
- doff = ELF_ALIGN(offset + namesz);
-
- if (offset + namesz > size) {
- /*
- * We're past the end of the buffer.
- */
- return doff;
- }
-
- offset = ELF_ALIGN(doff + descsz);
- if (doff + descsz > size) {
- /*
- * We're past the end of the buffer.
- */
- return (offset >= size) ? offset : size;
- }
-
- if ((*flags & (FLAGS_DID_NOTE|FLAGS_DID_BUILD_ID)) ==
- (FLAGS_DID_NOTE|FLAGS_DID_BUILD_ID))
- goto core;
-
- if (namesz == 5 && strcmp((char *)&nbuf[noff], "SuSE") == 0 &&
- xnh_type == NT_GNU_VERSION && descsz == 2) {
- file_printf(ms, ", for SuSE %d.%d", nbuf[doff], nbuf[doff + 1]);
- }
- if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
- xnh_type == NT_GNU_VERSION && descsz == 16) {
- uint32_t desc[4];
- (void)memcpy(desc, &nbuf[doff], sizeof(desc));
-
- if (file_printf(ms, ", for GNU/") == -1)
- return size;
- switch (elf_getu32(swap, desc[0])) {
- case GNU_OS_LINUX:
- if (file_printf(ms, "Linux") == -1)
- return size;
- break;
- case GNU_OS_HURD:
- if (file_printf(ms, "Hurd") == -1)
- return size;
- break;
- case GNU_OS_SOLARIS:
- if (file_printf(ms, "Solaris") == -1)
- return size;
- break;
- case GNU_OS_KFREEBSD:
- if (file_printf(ms, "kFreeBSD") == -1)
- return size;
- break;
- case GNU_OS_KNETBSD:
- if (file_printf(ms, "kNetBSD") == -1)
- return size;
- break;
- default:
- if (file_printf(ms, "<unknown>") == -1)
- return size;
- }
- if (file_printf(ms, " %d.%d.%d", elf_getu32(swap, desc[1]),
- elf_getu32(swap, desc[2]), elf_getu32(swap, desc[3])) == -1)
- return size;
- *flags |= FLAGS_DID_NOTE;
- return size;
- }
-
- if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
- xnh_type == NT_GNU_BUILD_ID && (descsz == 16 || descsz == 20)) {
- uint8_t desc[20];
- uint32_t i;
- if (file_printf(ms, ", BuildID[%s]=", descsz == 16 ? "md5/uuid" :
- "sha1") == -1)
- return size;
- (void)memcpy(desc, &nbuf[doff], descsz);
- for (i = 0; i < descsz; i++)
- if (file_printf(ms, "%02x", desc[i]) == -1)
- return size;
- *flags |= FLAGS_DID_BUILD_ID;
- }
-
- if (namesz == 7 && strcmp((char *)&nbuf[noff], "NetBSD") == 0 &&
- xnh_type == NT_NETBSD_VERSION && descsz == 4) {
- uint32_t desc;
- (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
- desc = elf_getu32(swap, desc);
-
- if (file_printf(ms, ", for NetBSD") == -1)
- return size;
- /*
- * The version number used to be stuck as 199905, and was thus
- * basically content-free. Newer versions of NetBSD have fixed
- * this and now use the encoding of __NetBSD_Version__:
- *
- * MMmmrrpp00
- *
- * M = major version
- * m = minor version
- * r = release ["",A-Z,Z[A-Z] but numeric]
- * p = patchlevel
- */
- if (desc > 100000000U) {
- uint32_t ver_patch = (desc / 100) % 100;
- uint32_t ver_rel = (desc / 10000) % 100;
- uint32_t ver_min = (desc / 1000000) % 100;
- uint32_t ver_maj = desc / 100000000;
-
- if (file_printf(ms, " %u.%u", ver_maj, ver_min) == -1)
- return size;
- if (ver_rel == 0 && ver_patch != 0) {
- if (file_printf(ms, ".%u", ver_patch) == -1)
- return size;
- } else if (ver_rel != 0) {
- while (ver_rel > 26) {
- if (file_printf(ms, "Z") == -1)
- return size;
- ver_rel -= 26;
- }
- if (file_printf(ms, "%c", 'A' + ver_rel - 1)
- == -1)
- return size;
- }
- }
- *flags |= FLAGS_DID_NOTE;
- return size;
- }
-
- if (namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0 &&
- xnh_type == NT_FREEBSD_VERSION && descsz == 4) {
- uint32_t desc;
- (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
- desc = elf_getu32(swap, desc);
- if (file_printf(ms, ", for FreeBSD") == -1)
- return size;
-
- /*
- * Contents is __FreeBSD_version, whose relation to OS
- * versions is defined by a huge table in the Porter's
- * Handbook. This is the general scheme:
- *
- * Releases:
- * Mmp000 (before 4.10)
- * Mmi0p0 (before 5.0)
- * Mmm0p0
- *
- * Development branches:
- * Mmpxxx (before 4.6)
- * Mmp1xx (before 4.10)
- * Mmi1xx (before 5.0)
- * M000xx (pre-M.0)
- * Mmm1xx
- *
- * M = major version
- * m = minor version
- * i = minor version increment (491000 -> 4.10)
- * p = patchlevel
- * x = revision
- *
- * The first release of FreeBSD to use ELF by default
- * was version 3.0.
- */
- if (desc == 460002) {
- if (file_printf(ms, " 4.6.2") == -1)
- return size;
- } else if (desc < 460100) {
- if (file_printf(ms, " %d.%d", desc / 100000,
- desc / 10000 % 10) == -1)
- return size;
- if (desc / 1000 % 10 > 0)
- if (file_printf(ms, ".%d", desc / 1000 % 10)
- == -1)
- return size;
- if ((desc % 1000 > 0) || (desc % 100000 == 0))
- if (file_printf(ms, " (%d)", desc) == -1)
- return size;
- } else if (desc < 500000) {
- if (file_printf(ms, " %d.%d", desc / 100000,
- desc / 10000 % 10 + desc / 1000 % 10) == -1)
- return size;
- if (desc / 100 % 10 > 0) {
- if (file_printf(ms, " (%d)", desc) == -1)
- return size;
- } else if (desc / 10 % 10 > 0) {
- if (file_printf(ms, ".%d", desc / 10 % 10)
- == -1)
- return size;
- }
- } else {
- if (file_printf(ms, " %d.%d", desc / 100000,
- desc / 1000 % 100) == -1)
- return size;
- if ((desc / 100 % 10 > 0) ||
- (desc % 100000 / 100 == 0)) {
- if (file_printf(ms, " (%d)", desc) == -1)
- return size;
- } else if (desc / 10 % 10 > 0) {
- if (file_printf(ms, ".%d", desc / 10 % 10)
- == -1)
- return size;
- }
- }
- *flags |= FLAGS_DID_NOTE;
- return size;
- }
-
- if (namesz == 8 && strcmp((char *)&nbuf[noff], "OpenBSD") == 0 &&
- xnh_type == NT_OPENBSD_VERSION && descsz == 4) {
- if (file_printf(ms, ", for OpenBSD") == -1)
- return size;
- /* Content of note is always 0 */
- *flags |= FLAGS_DID_NOTE;
- return size;
- }
-
- if (namesz == 10 && strcmp((char *)&nbuf[noff], "DragonFly") == 0 &&
- xnh_type == NT_DRAGONFLY_VERSION && descsz == 4) {
- uint32_t desc;
- if (file_printf(ms, ", for DragonFly") == -1)
- return size;
- (void)memcpy(&desc, &nbuf[doff], sizeof(desc));
- desc = elf_getu32(swap, desc);
- if (file_printf(ms, " %d.%d.%d", desc / 100000,
- desc / 10000 % 10, desc % 10000) == -1)
- return size;
- *flags |= FLAGS_DID_NOTE;
- return size;
- }
-
-core:
- /*
- * Sigh. The 2.0.36 kernel in Debian 2.1, at
- * least, doesn't correctly implement name
- * sections, in core dumps, as specified by
- * the "Program Linking" section of "UNIX(R) System
- * V Release 4 Programmer's Guide: ANSI C and
- * Programming Support Tools", because my copy
- * clearly says "The first 'namesz' bytes in 'name'
- * contain a *null-terminated* [emphasis mine]
- * character representation of the entry's owner
- * or originator", but the 2.0.36 kernel code
- * doesn't include the terminating null in the
- * name....
- */
- if ((namesz == 4 && strncmp((char *)&nbuf[noff], "CORE", 4) == 0) ||
- (namesz == 5 && strcmp((char *)&nbuf[noff], "CORE") == 0)) {
- os_style = OS_STYLE_SVR4;
- }
-
- if ((namesz == 8 && strcmp((char *)&nbuf[noff], "FreeBSD") == 0)) {
- os_style = OS_STYLE_FREEBSD;
- }
-
- if ((namesz >= 11 && strncmp((char *)&nbuf[noff], "NetBSD-CORE", 11)
- == 0)) {
- os_style = OS_STYLE_NETBSD;
- }
-
-#ifdef ELFCORE
- if ((*flags & FLAGS_DID_CORE) != 0)
- return size;
-
- if (os_style != -1 && (*flags & FLAGS_DID_CORE_STYLE) == 0) {
- if (file_printf(ms, ", %s-style", os_style_names[os_style])
- == -1)
- return size;
- *flags |= FLAGS_DID_CORE_STYLE;
- }
-
- switch (os_style) {
- case OS_STYLE_NETBSD:
- if (xnh_type == NT_NETBSD_CORE_PROCINFO) {
- uint32_t signo;
- /*
- * Extract the program name. It is at
- * offset 0x7c, and is up to 32-bytes,
- * including the terminating NUL.
- */
- if (file_printf(ms, ", from '%.31s'",
- &nbuf[doff + 0x7c]) == -1)
- return size;
-
- /*
- * Extract the signal number. It is at
- * offset 0x08.
- */
- (void)memcpy(&signo, &nbuf[doff + 0x08],
- sizeof(signo));
- if (file_printf(ms, " (signal %u)",
- elf_getu32(swap, signo)) == -1)
- return size;
- *flags |= FLAGS_DID_CORE;
- return size;
- }
- break;
-
- default:
- if (xnh_type == NT_PRPSINFO && *flags & FLAGS_IS_CORE) {
- size_t i, j;
- unsigned char c;
- /*
- * Extract the program name. We assume
- * it to be 16 characters (that's what it
- * is in SunOS 5.x and Linux).
- *
- * Unfortunately, it's at a different offset
- * in various OSes, so try multiple offsets.
- * If the characters aren't all printable,
- * reject it.
- */
- for (i = 0; i < NOFFSETS; i++) {
- unsigned char *cname, *cp;
- size_t reloffset = prpsoffsets(i);
- size_t noffset = doff + reloffset;
- size_t k;
- for (j = 0; j < 16; j++, noffset++,
- reloffset++) {
- /*
- * Make sure we're not past
- * the end of the buffer; if
- * we are, just give up.
- */
- if (noffset >= size)
- goto tryanother;
-
- /*
- * Make sure we're not past
- * the end of the contents;
- * if we are, this obviously
- * isn't the right offset.
- */
- if (reloffset >= descsz)
- goto tryanother;
-
- c = nbuf[noffset];
- if (c == '\0') {
- /*
- * A '\0' at the
- * beginning is
- * obviously wrong.
- * Any other '\0'
- * means we're done.
- */
- if (j == 0)
- goto tryanother;
- else
- break;
- } else {
- /*
- * A nonprintable
- * character is also
- * wrong.
- */
- if (!isprint(c) || isquote(c))
- goto tryanother;
- }
- }
- /*
- * Well, that worked.
- */
-
- /*
- * Try next offsets, in case this match is
- * in the middle of a string.
- */
- for (k = i + 1 ; k < NOFFSETS ; k++) {
- size_t no;
- int adjust = 1;
- if (prpsoffsets(k) >= prpsoffsets(i))
- continue;
- for (no = doff + prpsoffsets(k);
- no < doff + prpsoffsets(i); no++)
- adjust = adjust
- && isprint(nbuf[no]);
- if (adjust)
- i = k;
- }
-
- cname = (unsigned char *)
- &nbuf[doff + prpsoffsets(i)];
- for (cp = cname; *cp && isprint(*cp); cp++)
- continue;
- /*
- * Linux apparently appends a space at the end
- * of the command line: remove it.
- */
- while (cp > cname && isspace(cp[-1]))
- cp--;
- if (file_printf(ms, ", from '%.*s'",
- (int)(cp - cname), cname) == -1)
- return size;
- *flags |= FLAGS_DID_CORE;
- return size;
-
- tryanother:
- ;
- }
- }
- break;
- }
-#endif
- return offset;
-}
-
-/* SunOS 5.x hardware capability descriptions */
-typedef struct cap_desc {
- uint64_t cd_mask;
- const char *cd_name;
-} cap_desc_t;
-
-static const cap_desc_t cap_desc_sparc[] = {
- { AV_SPARC_MUL32, "MUL32" },
- { AV_SPARC_DIV32, "DIV32" },
- { AV_SPARC_FSMULD, "FSMULD" },
- { AV_SPARC_V8PLUS, "V8PLUS" },
- { AV_SPARC_POPC, "POPC" },
- { AV_SPARC_VIS, "VIS" },
- { AV_SPARC_VIS2, "VIS2" },
- { AV_SPARC_ASI_BLK_INIT, "ASI_BLK_INIT" },
- { AV_SPARC_FMAF, "FMAF" },
- { AV_SPARC_FJFMAU, "FJFMAU" },
- { AV_SPARC_IMA, "IMA" },
- { 0, NULL }
-};
-
-static const cap_desc_t cap_desc_386[] = {
- { AV_386_FPU, "FPU" },
- { AV_386_TSC, "TSC" },
- { AV_386_CX8, "CX8" },
- { AV_386_SEP, "SEP" },
- { AV_386_AMD_SYSC, "AMD_SYSC" },
- { AV_386_CMOV, "CMOV" },
- { AV_386_MMX, "MMX" },
- { AV_386_AMD_MMX, "AMD_MMX" },
- { AV_386_AMD_3DNow, "AMD_3DNow" },
- { AV_386_AMD_3DNowx, "AMD_3DNowx" },
- { AV_386_FXSR, "FXSR" },
- { AV_386_SSE, "SSE" },
- { AV_386_SSE2, "SSE2" },
- { AV_386_PAUSE, "PAUSE" },
- { AV_386_SSE3, "SSE3" },
- { AV_386_MON, "MON" },
- { AV_386_CX16, "CX16" },
- { AV_386_AHF, "AHF" },
- { AV_386_TSCP, "TSCP" },
- { AV_386_AMD_SSE4A, "AMD_SSE4A" },
- { AV_386_POPCNT, "POPCNT" },
- { AV_386_AMD_LZCNT, "AMD_LZCNT" },
- { AV_386_SSSE3, "SSSE3" },
- { AV_386_SSE4_1, "SSE4.1" },
- { AV_386_SSE4_2, "SSE4.2" },
- { 0, NULL }
-};
-
-private int
-doshn(struct magic_set *ms, int clazz, int swap, int fd, off_t off, int num,
- size_t size, off_t fsize, int *flags, int mach, int strtab)
-{
- Elf32_Shdr sh32;
- Elf64_Shdr sh64;
- int stripped = 1;
- void *nbuf;
- off_t noff, coff, name_off;
- uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */
- uint64_t cap_sf1 = 0; /* SunOS 5.x software capabilites */
- char name[50];
-
- if (size != xsh_sizeof) {
- if (file_printf(ms, ", corrupted section header size") == -1)
- return -1;
- return 0;
- }
-
- for ( ; num; num--) {
- if (FINFO_LSEEK_FUNC(fd, off, SEEK_SET) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
- if (FINFO_READ_FUNC(fd, xsh_addr, xsh_sizeof) == -1) {
- file_badread(ms);
- return -1;
- }
- off += size;
-
- /* Things we can determine before we seek */
- switch (xsh_type) {
- case SHT_SYMTAB:
-#if 0
- case SHT_DYNSYM:
-#endif
- stripped = 0;
- break;
- default:
- if (xsh_offset > fsize) {
- /* Perhaps warn here */
- continue;
- }
- break;
- }
-
- /* Things we can determine when we seek */
- switch (xsh_type) {
- case SHT_NOTE:
- nbuf = emalloc((size_t)xsh_size);
- if ((noff = FINFO_LSEEK_FUNC(fd, (off_t)xsh_offset, SEEK_SET)) ==
- (off_t)-1) {
- file_badread(ms);
- efree(nbuf);
- return -1;
- }
- if (FINFO_READ_FUNC(fd, nbuf, (size_t)xsh_size) !=
- (ssize_t)xsh_size) {
- efree(nbuf);
- file_badread(ms);
- return -1;
- }
-
- noff = 0;
- for (;;) {
- if (noff >= (off_t)xsh_size)
- break;
- noff = donote(ms, nbuf, (size_t)noff,
- (size_t)xsh_size, clazz, swap, 4,
- flags);
- if (noff == 0)
- break;
- }
- efree(nbuf);
- break;
- case SHT_SUNW_cap:
- if (FINFO_LSEEK_FUNC(fd, (off_t)xsh_offset, SEEK_SET) ==
- (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
- coff = 0;
- for (;;) {
- Elf32_Cap cap32;
- Elf64_Cap cap64;
- char cbuf[/*CONSTCOND*/
- MAX(sizeof cap32, sizeof cap64)];
- if ((coff += xcap_sizeof) > (off_t)xsh_size)
- break;
- if (FINFO_READ_FUNC(fd, cbuf, (size_t)xcap_sizeof) !=
- (ssize_t)xcap_sizeof) {
- file_badread(ms);
- return -1;
- }
- (void)memcpy(xcap_addr, cbuf, xcap_sizeof);
- switch (xcap_tag) {
- case CA_SUNW_NULL:
- break;
- case CA_SUNW_HW_1:
- cap_hw1 |= xcap_val;
- break;
- case CA_SUNW_SF_1:
- cap_sf1 |= xcap_val;
- break;
- default:
- if (file_printf(ms,
- ", with unknown capability "
- "0x%" INT64_T_FORMAT "x = 0x%"
- INT64_T_FORMAT "x",
- (unsigned long long)xcap_tag,
- (unsigned long long)xcap_val) == -1)
- return -1;
- break;
- }
- }
- break;
-
- default:
- break;
- }
- }
- if (file_printf(ms, ", %sstripped", stripped ? "" : "not ") == -1)
- return -1;
- if (cap_hw1) {
- const cap_desc_t *cdp;
- switch (mach) {
- case EM_SPARC:
- case EM_SPARC32PLUS:
- case EM_SPARCV9:
- cdp = cap_desc_sparc;
- break;
- case EM_386:
- case EM_IA_64:
- case EM_AMD64:
- cdp = cap_desc_386;
- break;
- default:
- cdp = NULL;
- break;
- }
- if (file_printf(ms, ", uses") == -1)
- return -1;
- if (cdp) {
- while (cdp->cd_name) {
- if (cap_hw1 & cdp->cd_mask) {
- if (file_printf(ms,
- " %s", cdp->cd_name) == -1)
- return -1;
- cap_hw1 &= ~cdp->cd_mask;
- }
- ++cdp;
- }
- if (cap_hw1)
- if (file_printf(ms,
- " unknown hardware capability 0x%"
- INT64_T_FORMAT "x",
- (unsigned long long)cap_hw1) == -1)
- return -1;
- } else {
- if (file_printf(ms,
- " hardware capability 0x%" INT64_T_FORMAT "x",
- (unsigned long long)cap_hw1) == -1)
- return -1;
- }
- }
- if (cap_sf1) {
- if (cap_sf1 & SF1_SUNW_FPUSED) {
- if (file_printf(ms,
- (cap_sf1 & SF1_SUNW_FPKNWN)
- ? ", uses frame pointer"
- : ", not known to use frame pointer") == -1)
- return -1;
- }
- cap_sf1 &= ~SF1_SUNW_MASK;
- if (cap_sf1)
- if (file_printf(ms,
- ", with unknown software capability 0x%"
- INT64_T_FORMAT "x",
- (unsigned long long)cap_sf1) == -1)
- return -1;
- }
- return 0;
-}
-
-/*
- * Look through the program headers of an executable image, searching
- * for a PT_INTERP section; if one is found, it's dynamically linked,
- * otherwise it's statically linked.
- */
-private int
-dophn_exec(struct magic_set *ms, int clazz, int swap, int fd, off_t off,
- int num, size_t size, off_t fsize, int *flags, int sh_num)
-{
- Elf32_Phdr ph32;
- Elf64_Phdr ph64;
- const char *linking_style = "statically";
- const char *shared_libraries = "";
- unsigned char nbuf[BUFSIZ];
- ssize_t bufsize;
- size_t offset, align;
-
- if (size != xph_sizeof) {
- if (file_printf(ms, ", corrupted program header size") == -1)
- return -1;
- return 0;
- }
-
- for ( ; num; num--) {
- if (FINFO_LSEEK_FUNC(fd, off, SEEK_SET) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
-
- if (FINFO_READ_FUNC(fd, xph_addr, xph_sizeof) == -1) {
- file_badread(ms);
- return -1;
- }
-
- off += size;
-
- /* Things we can determine before we seek */
- switch (xph_type) {
- case PT_DYNAMIC:
- linking_style = "dynamically";
- break;
- case PT_INTERP:
- shared_libraries = " (uses shared libs)";
- break;
- default:
- if (xph_offset > fsize) {
- /* Maybe warn here? */
- continue;
- }
- break;
- }
-
- /* Things we can determine when we seek */
- switch (xph_type) {
- case PT_NOTE:
- if ((align = xph_align) & 0x80000000UL) {
- if (file_printf(ms,
- ", invalid note alignment 0x%lx",
- (unsigned long)align) == -1)
- return -1;
- align = 4;
- }
- if (sh_num)
- break;
- /*
- * This is a PT_NOTE section; loop through all the notes
- * in the section.
- */
- if (FINFO_LSEEK_FUNC(fd, xph_offset, SEEK_SET) == (off_t)-1) {
- file_badseek(ms);
- return -1;
- }
- bufsize = FINFO_READ_FUNC(fd, nbuf, ((xph_filesz < sizeof(nbuf)) ?
- xph_filesz : sizeof(nbuf)));
- if (bufsize == -1) {
- file_badread(ms);
- return -1;
- }
- offset = 0;
- for (;;) {
- if (offset >= (size_t)bufsize)
- break;
- offset = donote(ms, nbuf, offset,
- (size_t)bufsize, clazz, swap, align,
- flags);
- if (offset == 0)
- break;
- }
- break;
- default:
- break;
- }
- }
- if (file_printf(ms, ", %s linked%s", linking_style, shared_libraries)
- == -1)
- return -1;
- return 0;
-}
-
-
-protected int
-file_tryelf(struct magic_set *ms, int fd, const unsigned char *buf,
- size_t nbytes)
-{
- union {
- int32_t l;
- char c[sizeof (int32_t)];
- } u;
- int clazz;
- int swap;
- struct stat st;
- off_t fsize;
- int flags = 0;
- Elf32_Ehdr elf32hdr;
- Elf64_Ehdr elf64hdr;
- uint16_t type;
-
- if (ms->flags & (MAGIC_MIME|MAGIC_APPLE))
- return 0;
- /*
- * ELF executables have multiple section headers in arbitrary
- * file locations and thus file(1) cannot determine it from easily.
- * Instead we traverse thru all section headers until a symbol table
- * one is found or else the binary is stripped.
- * Return immediately if it's not ELF (so we avoid pipe2file unless needed).
- */
- if (buf[EI_MAG0] != ELFMAG0
- || (buf[EI_MAG1] != ELFMAG1 && buf[EI_MAG1] != OLFMAG1)
- || buf[EI_MAG2] != ELFMAG2 || buf[EI_MAG3] != ELFMAG3)
- return 0;
-
- /*
- * If we cannot seek, it must be a pipe, socket or fifo.
- */
- if((FINFO_LSEEK_FUNC(fd, (off_t)0, SEEK_SET) == (off_t)-1) && (errno == ESPIPE))
- fd = file_pipe2file(ms, fd, buf, nbytes);
-
- if (fstat(fd, &st) == -1) {
- file_badread(ms);
- return -1;
- }
- fsize = st.st_size;
-
- clazz = buf[EI_CLASS];
-
- switch (clazz) {
- case ELFCLASS32:
-#undef elf_getu
-#define elf_getu(a, b) elf_getu32(a, b)
-#undef elfhdr
-#define elfhdr elf32hdr
-#include "elfclass.h"
- case ELFCLASS64:
-#undef elf_getu
-#define elf_getu(a, b) elf_getu64(a, b)
-#undef elfhdr
-#define elfhdr elf64hdr
-#include "elfclass.h"
- default:
- if (file_printf(ms, ", unknown class %d", clazz) == -1)
- return -1;
- break;
- }
- return 0;
-}
-#endif
diff --git a/ext/fileinfo/libmagic/readelf.h b/ext/fileinfo/libmagic/readelf.h
deleted file mode 100644
index 4308e6ac4..000000000
--- a/ext/fileinfo/libmagic/readelf.h
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright (c) Christos Zoulas 2003.
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-/*
- * @(#)Id: readelf.h,v 1.9 2002/05/16 18:45:56 christos Exp
- *
- * Provide elf data structures for non-elf machines, allowing file
- * non-elf hosts to determine if an elf binary is stripped.
- * Note: cobbled from the linux header file, with modifications
- */
-#ifndef __fake_elf_h__
-#define __fake_elf_h__
-
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-typedef uint32_t Elf32_Addr;
-typedef uint32_t Elf32_Off;
-typedef uint16_t Elf32_Half;
-typedef uint32_t Elf32_Word;
-typedef uint8_t Elf32_Char;
-
-#if SIZEOF_LONG_LONG != 8
-#define USE_ARRAY_FOR_64BIT_TYPES
-typedef uint32_t Elf64_Addr[2];
-typedef uint32_t Elf64_Off[2];
-typedef uint32_t Elf64_Xword[2];
-#else
-#undef USE_ARRAY_FOR_64BIT_TYPES
-typedef uint64_t Elf64_Addr;
-typedef uint64_t Elf64_Off;
-typedef uint64_t Elf64_Xword;
-#endif
-typedef uint16_t Elf64_Half;
-typedef uint32_t Elf64_Word;
-typedef uint8_t Elf64_Char;
-
-#define EI_NIDENT 16
-
-typedef struct {
- Elf32_Char e_ident[EI_NIDENT];
- Elf32_Half e_type;
- Elf32_Half e_machine;
- Elf32_Word e_version;
- Elf32_Addr e_entry; /* Entry point */
- Elf32_Off e_phoff;
- Elf32_Off e_shoff;
- Elf32_Word e_flags;
- Elf32_Half e_ehsize;
- Elf32_Half e_phentsize;
- Elf32_Half e_phnum;
- Elf32_Half e_shentsize;
- Elf32_Half e_shnum;
- Elf32_Half e_shstrndx;
-} Elf32_Ehdr;
-
-typedef struct {
- Elf64_Char e_ident[EI_NIDENT];
- Elf64_Half e_type;
- Elf64_Half e_machine;
- Elf64_Word e_version;
- Elf64_Addr e_entry; /* Entry point */
- Elf64_Off e_phoff;
- Elf64_Off e_shoff;
- Elf64_Word e_flags;
- Elf64_Half e_ehsize;
- Elf64_Half e_phentsize;
- Elf64_Half e_phnum;
- Elf64_Half e_shentsize;
- Elf64_Half e_shnum;
- Elf64_Half e_shstrndx;
-} Elf64_Ehdr;
-
-/* e_type */
-#define ET_REL 1
-#define ET_EXEC 2
-#define ET_DYN 3
-#define ET_CORE 4
-
-/* e_machine (used only for SunOS 5.x hardware capabilities) */
-#define EM_SPARC 2
-#define EM_386 3
-#define EM_SPARC32PLUS 18
-#define EM_SPARCV9 43
-#define EM_IA_64 50
-#define EM_AMD64 62
-
-/* sh_type */
-#define SHT_SYMTAB 2
-#define SHT_NOTE 7
-#define SHT_DYNSYM 11
-#define SHT_SUNW_cap 0x6ffffff5 /* SunOS 5.x hw/sw capabilites */
-
-/* elf type */
-#define ELFDATANONE 0 /* e_ident[EI_DATA] */
-#define ELFDATA2LSB 1
-#define ELFDATA2MSB 2
-
-/* elf class */
-#define ELFCLASSNONE 0
-#define ELFCLASS32 1
-#define ELFCLASS64 2
-
-/* magic number */
-#define EI_MAG0 0 /* e_ident[] indexes */
-#define EI_MAG1 1
-#define EI_MAG2 2
-#define EI_MAG3 3
-#define EI_CLASS 4
-#define EI_DATA 5
-#define EI_VERSION 6
-#define EI_PAD 7
-
-#define ELFMAG0 0x7f /* EI_MAG */
-#define ELFMAG1 'E'
-#define ELFMAG2 'L'
-#define ELFMAG3 'F'
-#define ELFMAG "\177ELF"
-
-#define OLFMAG1 'O'
-#define OLFMAG "\177OLF"
-
-typedef struct {
- Elf32_Word p_type;
- Elf32_Off p_offset;
- Elf32_Addr p_vaddr;
- Elf32_Addr p_paddr;
- Elf32_Word p_filesz;
- Elf32_Word p_memsz;
- Elf32_Word p_flags;
- Elf32_Word p_align;
-} Elf32_Phdr;
-
-typedef struct {
- Elf64_Word p_type;
- Elf64_Word p_flags;
- Elf64_Off p_offset;
- Elf64_Addr p_vaddr;
- Elf64_Addr p_paddr;
- Elf64_Xword p_filesz;
- Elf64_Xword p_memsz;
- Elf64_Xword p_align;
-} Elf64_Phdr;
-
-#define PT_NULL 0 /* p_type */
-#define PT_LOAD 1
-#define PT_DYNAMIC 2
-#define PT_INTERP 3
-#define PT_NOTE 4
-#define PT_SHLIB 5
-#define PT_PHDR 6
-#define PT_NUM 7
-
-typedef struct {
- Elf32_Word sh_name;
- Elf32_Word sh_type;
- Elf32_Word sh_flags;
- Elf32_Addr sh_addr;
- Elf32_Off sh_offset;
- Elf32_Word sh_size;
- Elf32_Word sh_link;
- Elf32_Word sh_info;
- Elf32_Word sh_addralign;
- Elf32_Word sh_entsize;
-} Elf32_Shdr;
-
-typedef struct {
- Elf64_Word sh_name;
- Elf64_Word sh_type;
- Elf64_Off sh_flags;
- Elf64_Addr sh_addr;
- Elf64_Off sh_offset;
- Elf64_Off sh_size;
- Elf64_Word sh_link;
- Elf64_Word sh_info;
- Elf64_Off sh_addralign;
- Elf64_Off sh_entsize;
-} Elf64_Shdr;
-
-#define NT_NETBSD_CORE_PROCINFO 1
-
-/* Note header in a PT_NOTE section */
-typedef struct elf_note {
- Elf32_Word n_namesz; /* Name size */
- Elf32_Word n_descsz; /* Content size */
- Elf32_Word n_type; /* Content type */
-} Elf32_Nhdr;
-
-typedef struct {
- Elf64_Word n_namesz;
- Elf64_Word n_descsz;
- Elf64_Word n_type;
-} Elf64_Nhdr;
-
-/* Notes used in ET_CORE */
-#define NT_PRSTATUS 1
-#define NT_PRFPREG 2
-#define NT_PRPSINFO 3
-#define NT_PRXREG 4
-#define NT_TASKSTRUCT 4
-#define NT_PLATFORM 5
-#define NT_AUXV 6
-
-/* Note types used in executables */
-/* NetBSD executables (name = "NetBSD") */
-#define NT_NETBSD_VERSION 1
-#define NT_NETBSD_EMULATION 2
-#define NT_FREEBSD_VERSION 1
-#define NT_OPENBSD_VERSION 1
-#define NT_DRAGONFLY_VERSION 1
-/*
- * GNU executables (name = "GNU")
- * word[0]: GNU OS tags
- * word[1]: major version
- * word[2]: minor version
- * word[3]: tiny version
- */
-#define NT_GNU_VERSION 1
-
-/* GNU OS tags */
-#define GNU_OS_LINUX 0
-#define GNU_OS_HURD 1
-#define GNU_OS_SOLARIS 2
-#define GNU_OS_KFREEBSD 3
-#define GNU_OS_KNETBSD 4
-
-/*
- * GNU Hardware capability information
- * word[0]: Number of entries
- * word[1]: Bitmask of enabled entries
- * Followed by a byte id, and a NUL terminated string per entry
- */
-#define NT_GNU_HWCAP 2
-
-/*
- * GNU Build ID generated by ld
- * 160 bit SHA1 [default]
- * 128 bit md5 or uuid
- */
-#define NT_GNU_BUILD_ID 3
-
-/* SunOS 5.x hardware/software capabilities */
-typedef struct {
- Elf32_Word c_tag;
- union {
- Elf32_Word c_val;
- Elf32_Addr c_ptr;
- } c_un;
-} Elf32_Cap;
-
-typedef struct {
- Elf64_Xword c_tag;
- union {
- Elf64_Xword c_val;
- Elf64_Addr c_ptr;
- } c_un;
-} Elf64_Cap;
-
-/* SunOS 5.x hardware/software capability tags */
-#define CA_SUNW_NULL 0
-#define CA_SUNW_HW_1 1
-#define CA_SUNW_SF_1 2
-
-/* SunOS 5.x software capabilities */
-#define SF1_SUNW_FPKNWN 0x01
-#define SF1_SUNW_FPUSED 0x02
-#define SF1_SUNW_MASK 0x03
-
-/* SunOS 5.x hardware capabilities: sparc */
-#define AV_SPARC_MUL32 0x0001
-#define AV_SPARC_DIV32 0x0002
-#define AV_SPARC_FSMULD 0x0004
-#define AV_SPARC_V8PLUS 0x0008
-#define AV_SPARC_POPC 0x0010
-#define AV_SPARC_VIS 0x0020
-#define AV_SPARC_VIS2 0x0040
-#define AV_SPARC_ASI_BLK_INIT 0x0080
-#define AV_SPARC_FMAF 0x0100
-#define AV_SPARC_FJFMAU 0x4000
-#define AV_SPARC_IMA 0x8000
-
-/* SunOS 5.x hardware capabilities: 386 */
-#define AV_386_FPU 0x00000001
-#define AV_386_TSC 0x00000002
-#define AV_386_CX8 0x00000004
-#define AV_386_SEP 0x00000008
-#define AV_386_AMD_SYSC 0x00000010
-#define AV_386_CMOV 0x00000020
-#define AV_386_MMX 0x00000040
-#define AV_386_AMD_MMX 0x00000080
-#define AV_386_AMD_3DNow 0x00000100
-#define AV_386_AMD_3DNowx 0x00000200
-#define AV_386_FXSR 0x00000400
-#define AV_386_SSE 0x00000800
-#define AV_386_SSE2 0x00001000
-#define AV_386_PAUSE 0x00002000
-#define AV_386_SSE3 0x00004000
-#define AV_386_MON 0x00008000
-#define AV_386_CX16 0x00010000
-#define AV_386_AHF 0x00020000
-#define AV_386_TSCP 0x00040000
-#define AV_386_AMD_SSE4A 0x00080000
-#define AV_386_POPCNT 0x00100000
-#define AV_386_AMD_LZCNT 0x00200000
-#define AV_386_SSSE3 0x00400000
-#define AV_386_SSE4_1 0x00800000
-#define AV_386_SSE4_2 0x01000000
-
-#endif
diff --git a/ext/fileinfo/libmagic/softmagic.c b/ext/fileinfo/libmagic/softmagic.c
index 7e0c8560e..e7b7855ee 100644
--- a/ext/fileinfo/libmagic/softmagic.c
+++ b/ext/fileinfo/libmagic/softmagic.c
@@ -884,14 +884,17 @@ mconvert(struct magic_set *ms, struct magic *m, int flip)
size_t sz = file_pstring_length_size(m);
char *ptr1 = p->s, *ptr2 = ptr1 + sz;
size_t len = file_pstring_get_length(m, ptr1);
- if (len >= sizeof(p->s)) {
+ sz = sizeof(p->s) - sz; /* maximum length of string */
+ if (len >= sz) {
/*
* The size of the pascal string length (sz)
* is 1, 2, or 4. We need at least 1 byte for NUL
* termination, but we've already truncated the
* string by p->s, so we need to deduct sz.
+ * Because we can use one of the bytes of the length
+ * after we shifted as NUL termination.
*/
- len = sizeof(p->s) - sz;
+ len = sz;
}
while (len--)
*ptr1++ = *ptr2++;
diff --git a/ext/fileinfo/tests/bug68735.jpg b/ext/fileinfo/tests/bug68735.jpg
new file mode 100644
index 000000000..633bdb93e
--- /dev/null
+++ b/ext/fileinfo/tests/bug68735.jpg
Binary files differ
diff --git a/ext/fileinfo/tests/bug68735.phpt b/ext/fileinfo/tests/bug68735.phpt
new file mode 100644
index 000000000..f86109cb8
--- /dev/null
+++ b/ext/fileinfo/tests/bug68735.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Bug #68735 fileinfo out-of-bounds memory access
+--SKIPIF--
+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
+--FILE--
+<?php
+ $test_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . "bug68735.jpg";
+ $f = new finfo;
+
+ var_dump($f->file($test_file));
+
+?>
+===DONE===
+--EXPECTF--
+string(%d) "JPEG image data, JFIF standard 1.01, comment: "%S""
+===DONE===
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index 05d946a54..216a56a59 100755
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -4556,14 +4556,14 @@ int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
return FAILURE;
}
- match = strcmp(cnmatch, buf) == 0;
+ match = strcasecmp(cnmatch, buf) == 0;
if (!match && strlen(buf) > 3 && buf[0] == '*' && buf[1] == '.') {
/* Try wildcard */
if (strchr(buf+2, '.')) {
char *tmp = strstr(cnmatch, buf+1);
- match = tmp && strcmp(tmp, buf+2) && tmp == strchr(cnmatch, '.');
+ match = tmp && strcasecmp(tmp, buf+2) && tmp == strchr(cnmatch, '.');
}
}
diff --git a/ext/standard/tests/strings/bug68710.phpt b/ext/standard/tests/strings/bug68710.phpt
new file mode 100644
index 000000000..729a12011
--- /dev/null
+++ b/ext/standard/tests/strings/bug68710.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Bug #68710 Use after free vulnerability in unserialize() (bypassing the
+CVE-2014-8142 fix)
+--FILE--
+<?php
+for ($i=4; $i<100; $i++) {
+ $m = new StdClass();
+
+ $u = array(1);
+
+ $m->aaa = array(1,2,&$u,4,5);
+ $m->bbb = 1;
+ $m->ccc = &$u;
+ $m->ddd = str_repeat("A", $i);
+
+ $z = serialize($m);
+ $z = str_replace("aaa", "123", $z);
+ $z = str_replace("bbb", "123", $z);
+ $y = unserialize($z);
+ $z = serialize($y);
+}
+?>
+===DONE===
+--EXPECTF--
+===DONE===
diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c
index 25c25ab2d..e728d588c 100644
--- a/ext/standard/var_unserializer.c
+++ b/ext/standard/var_unserializer.c
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.7.5 on Thu Dec 11 19:26:19 2014 */
+/* Generated by re2c 0.13.7.5 on Thu Jan 1 14:43:18 2015 */
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
@@ -341,7 +341,7 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long
} else {
/* object properties should include no integers */
convert_to_string(key);
- if (zend_symtable_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)==SUCCESS) {
+ if (zend_hash_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)==SUCCESS) {
var_push_dtor(var_hash, old_data);
}
zend_hash_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data,
diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re
index 4cf1d1083..f04fc74c3 100644
--- a/ext/standard/var_unserializer.re
+++ b/ext/standard/var_unserializer.re
@@ -347,7 +347,7 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long
} else {
/* object properties should include no integers */
convert_to_string(key);
- if (zend_symtable_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)==SUCCESS) {
+ if (zend_hash_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)==SUCCESS) {
var_push_dtor(var_hash, old_data);
}
zend_hash_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data,