summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2016-07-19 00:53:08 -0700
committerFerenc Kovacs <tyra3l@gmail.com>2016-07-21 00:47:35 +0200
commitb1734d79a76b165365afb74716c592c3b9cbd0ca (patch)
treeac261a3739b95e06e2740d77b4c4abfac32a5045
parent0ca1698cf961d7064deb4c4598048bdca4af0b56 (diff)
downloadphp-git-b1734d79a76b165365afb74716c592c3b9cbd0ca.tar.gz
Merge branch 'PHP-5.5' into PHP-5.6
* PHP-5.5: fix #72519, possible OOB using imagegif fix #72512, invalid read or write for palette image when invalid transparent index is used Apparently some envs miss SIZE_MAX Fix tests Fix bug #72618: NULL Pointer Dereference in exif_process_user_comment Partial fix for bug #72613 - do not treat negative returns from bz2 as size_t Fix bug #72606: heap-buffer-overflow (write) simplestring_addn simplestring.c Fix for bug #72558, Integer overflow error within _gdContributionsAlloc() Fix bug #72603: Out of bound read in exif_process_IFD_in_MAKERNOTE Fix bug #72562 - destroy var_hash properly Fix bug #72533 (locale_accept_from_http out-of-bounds access) Fix fir bug #72520 Fix for bug #72513 CS fix and comments with bug ID Fix for HTTP_PROXY issue. add tests for bug #72512 Fixed bug #72512 gdImageTrueColorToPaletteBody allows arbitrary write/read access Fixed bug #72479 - same as #72434 Conflicts: ext/bz2/bz2.c main/SAPI.c main/php_variables.c
-rw-r--r--Zend/zend_virtual_cwd.c6
-rw-r--r--ext/bz2/bz2.c78
-rw-r--r--ext/bz2/tests/72613.bz2bin0 -> 351 bytes
-rw-r--r--ext/bz2/tests/bug72613.phpt23
-rw-r--r--ext/exif/exif.c39
-rw-r--r--ext/exif/tests/bug54002.phpt6
-rw-r--r--ext/exif/tests/bug62523_2.phpt6
-rw-r--r--ext/exif/tests/bug72603.jpegbin0 -> 3711 bytes
-rw-r--r--ext/exif/tests/bug72603.phpt11
-rw-r--r--ext/exif/tests/bug72618.jpgbin0 -> 3711 bytes
-rw-r--r--ext/exif/tests/bug72618.phpt11
-rw-r--r--ext/gd/libgd/gd.c2
-rw-r--r--ext/gd/libgd/gd_interpolation.c116
-rw-r--r--ext/gd/tests/bug72512_0.phpt18
-rw-r--r--ext/gd/tests/bug72512_1.phpt18
-rw-r--r--ext/intl/locale/locale_methods.c18
-rw-r--r--ext/intl/tests/bug72533.phpt30
-rw-r--r--ext/session/session.c3
-rw-r--r--ext/session/tests/bug72562.phpt44
-rw-r--r--ext/snmp/snmp.c89
-rw-r--r--ext/snmp/tests/bug72479.phpt35
-rw-r--r--ext/standard/basic_functions.c15
-rw-r--r--ext/xmlrpc/libxmlrpc/simplestring.c64
-rw-r--r--ext/xmlrpc/libxmlrpc/simplestring.h2
-rw-r--r--ext/zip/zip_stream.c8
-rw-r--r--main/SAPI.c40
-rw-r--r--main/php_variables.c55
27 files changed, 522 insertions, 215 deletions
diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c
index c8e42ddc60..a143842143 100644
--- a/Zend/zend_virtual_cwd.c
+++ b/Zend/zend_virtual_cwd.c
@@ -651,14 +651,14 @@ CWD_API void realpath_cache_del(const char *path, int path_len TSRMLS_DC) /* {{{
memcmp(path, (*bucket)->path, path_len) == 0) {
realpath_cache_bucket *r = *bucket;
*bucket = (*bucket)->next;
-
+
/* if the pointers match then only subtract the length of the path */
if(r->path == r->realpath) {
CWDG(realpath_cache_size) -= sizeof(realpath_cache_bucket) + r->path_len + 1;
} else {
CWDG(realpath_cache_size) -= sizeof(realpath_cache_bucket) + r->path_len + 1 + r->realpath_len + 1;
}
-
+
free(r);
return;
} else {
@@ -734,7 +734,7 @@ static inline realpath_cache_bucket* realpath_cache_find(const char *path, int p
realpath_cache_bucket *r = *bucket;
*bucket = (*bucket)->next;
- /* if the pointers match then only subtract the length of the path */
+ /* if the pointers match then only subtract the length of the path */
if(r->path == r->realpath) {
CWDG(realpath_cache_size) -= sizeof(realpath_cache_bucket) + r->path_len + 1;
} else {
diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c
index a93493fd3e..54b59f75d4 100644
--- a/ext/bz2/bz2.c
+++ b/ext/bz2/bz2.c
@@ -15,7 +15,7 @@
| Author: Sterling Hughes <sterling@php.net> |
+----------------------------------------------------------------------+
*/
-
+
/* $Id$ */
#ifdef HAVE_CONFIG_H
@@ -138,29 +138,33 @@ struct php_bz2_stream_data_t {
static size_t php_bz2iop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
{
struct php_bz2_stream_data_t *self = (struct php_bz2_stream_data_t *) stream->abstract;
- size_t ret;
-
- ret = BZ2_bzread(self->bz_file, buf, count);
+ int bz2_ret;
+
+ bz2_ret = BZ2_bzread(self->bz_file, buf, count);
- if (ret == 0) {
+ if (bz2_ret < 0) {
+ stream->eof = 1;
+ return -1;
+ }
+ if (bz2_ret == 0) {
stream->eof = 1;
}
- return ret;
+ return (size_t)bz2_ret;
}
static size_t php_bz2iop_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC)
{
struct php_bz2_stream_data_t *self = (struct php_bz2_stream_data_t *) stream->abstract;
- return BZ2_bzwrite(self->bz_file, (char*)buf, count);
+ return BZ2_bzwrite(self->bz_file, (char*)buf, count);
}
static int php_bz2iop_close(php_stream *stream, int close_handle TSRMLS_DC)
{
struct php_bz2_stream_data_t *self = (struct php_bz2_stream_data_t *)stream->abstract;
int ret = EOF;
-
+
if (close_handle) {
BZ2_bzclose(self->bz_file);
}
@@ -196,7 +200,7 @@ PHP_BZ2_API php_stream *_php_stream_bz2open_from_BZFILE(BZFILE *bz,
const char *mode, php_stream *innerstream STREAMS_DC TSRMLS_DC)
{
struct php_bz2_stream_data_t *self;
-
+
self = emalloc(sizeof(*self));
self->stream = innerstream;
@@ -227,7 +231,7 @@ PHP_BZ2_API php_stream *_php_stream_bz2open(php_stream_wrapper *wrapper,
virtual_filepath_ex(path, &path_copy, NULL TSRMLS_CC);
#else
path_copy = path;
-#endif
+#endif
if (php_check_open_basedir(path_copy TSRMLS_CC)) {
#ifdef VIRTUAL_DIR
@@ -235,7 +239,7 @@ PHP_BZ2_API php_stream *_php_stream_bz2open(php_stream_wrapper *wrapper,
#endif
return NULL;
}
-
+
/* try and open it directly first */
bz_file = BZ2_bzopen(path_copy, mode);
@@ -246,11 +250,11 @@ PHP_BZ2_API php_stream *_php_stream_bz2open(php_stream_wrapper *wrapper,
efree(path_copy);
#endif
path_copy = NULL;
-
+
if (bz_file == NULL) {
/* that didn't work, so try and get something from the network/wrapper */
stream = php_stream_open_wrapper(path, mode, options | STREAM_WILL_CAST, opened_path);
-
+
if (stream) {
php_socket_t fd;
if (SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD, (void **) &fd, REPORT_ERRORS)) {
@@ -265,7 +269,7 @@ PHP_BZ2_API php_stream *_php_stream_bz2open(php_stream_wrapper *wrapper,
VCWD_UNLINK(*opened_path);
}
}
-
+
if (bz_file) {
retstream = _php_stream_bz2open_from_BZFILE(bz_file, mode, stream STREAMS_REL_CC TSRMLS_CC);
if (retstream) {
@@ -341,7 +345,7 @@ static PHP_FUNCTION(bzread)
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &bz, &len)) {
RETURN_FALSE;
}
-
+
php_stream_from_zval(stream, &bz);
if ((len + 1) < 1) {
@@ -351,13 +355,13 @@ static PHP_FUNCTION(bzread)
Z_STRVAL_P(return_value) = emalloc(len + 1);
Z_STRLEN_P(return_value) = php_stream_read(stream, Z_STRVAL_P(return_value), len);
-
+
if (Z_STRLEN_P(return_value) < 0) {
efree(Z_STRVAL_P(return_value));
php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not read valid bz2 data from stream");
- RETURN_FALSE;
+ RETURN_FALSE;
}
-
+
Z_STRVAL_P(return_value)[Z_STRLEN_P(return_value)] = 0;
Z_TYPE_P(return_value) = IS_STRING;
}
@@ -373,7 +377,7 @@ static PHP_FUNCTION(bzopen)
BZFILE *bz; /* The compressed file stream */
php_stream *stream = NULL;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zs", &file, &mode, &mode_len) == FAILURE) {
return;
}
@@ -389,15 +393,15 @@ static PHP_FUNCTION(bzopen)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "filename cannot be empty");
RETURN_FALSE;
}
-
+
if (CHECK_ZVAL_NULL_PATH(*file)) {
RETURN_FALSE;
}
stream = php_stream_bz2open(NULL,
- Z_STRVAL_PP(file),
- mode,
- REPORT_ERRORS,
+ Z_STRVAL_PP(file),
+ mode,
+ REPORT_ERRORS,
NULL);
} else if (Z_TYPE_PP(file) == IS_RESOURCE) {
/* If it is a resource, than its a stream resource */
@@ -406,7 +410,7 @@ static PHP_FUNCTION(bzopen)
php_stream_from_zval(stream, file);
stream_mode_len = strlen(stream->mode);
-
+
if (stream_mode_len != 1 && !(stream_mode_len == 2 && memchr(stream->mode, 'b', 2))) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot use stream opened in mode '%s'", stream->mode);
RETURN_FALSE;
@@ -440,7 +444,7 @@ static PHP_FUNCTION(bzopen)
if (FAILURE == php_stream_cast(stream, PHP_STREAM_AS_FD, (void *) &fd, REPORT_ERRORS)) {
RETURN_FALSE;
}
-
+
bz = BZ2_bzdopen(fd, mode);
stream = php_stream_bz2open_from_BZFILE(bz, mode, stream);
@@ -494,7 +498,7 @@ static PHP_FUNCTION(bzcompress)
work_factor = 0, /* Work factor for compression algorithm */
argc; /* Argument count */
int source_len; /* Length of the source data */
- unsigned int dest_len; /* Length of the destination buffer */
+ unsigned int dest_len; /* Length of the destination buffer */
argc = ZEND_NUM_ARGS();
@@ -503,19 +507,19 @@ static PHP_FUNCTION(bzcompress)
}
/* Assign them to easy to use variables, dest_len is initially the length of the data
- + .01 x length of data + 600 which is the largest size the results of the compression
- could possibly be, at least that's what the libbz2 docs say (thanks to jeremy@nirvani.net
+ + .01 x length of data + 600 which is the largest size the results of the compression
+ could possibly be, at least that's what the libbz2 docs say (thanks to jeremy@nirvani.net
for pointing this out). */
dest_len = (unsigned int) (source_len + (0.01 * source_len) + 600);
-
+
/* Allocate the destination buffer */
dest = emalloc(dest_len + 1);
-
+
/* Handle the optional arguments */
if (argc > 1) {
block_size = zblock_size;
}
-
+
if (argc > 2) {
work_factor = zwork_factor;
}
@@ -565,7 +569,7 @@ static PHP_FUNCTION(bzdecompress)
/* in most cases bz2 offers at least 2:1 compression, so we use that as our base */
bzs.avail_out = source_len * 2;
bzs.next_out = dest = emalloc(bzs.avail_out + 1);
-
+
while ((error = BZ2_bzDecompress(&bzs)) == BZ_OK && bzs.avail_in > 0) {
/* compression is better then 2:1, need to allocate more memory */
bzs.avail_out = source_len;
@@ -591,13 +595,13 @@ static PHP_FUNCTION(bzdecompress)
/* {{{ php_bz2_error()
The central error handling interface, does the work for bzerrno, bzerrstr and bzerror */
static void php_bz2_error(INTERNAL_FUNCTION_PARAMETERS, int opt)
-{
+{
zval *bzp; /* BZip2 Resource Pointer */
php_stream *stream;
const char *errstr; /* Error string */
int errnum; /* Error number */
struct php_bz2_stream_data_t *self;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &bzp) == FAILURE) {
return;
}
@@ -609,10 +613,10 @@ static void php_bz2_error(INTERNAL_FUNCTION_PARAMETERS, int opt)
}
self = (struct php_bz2_stream_data_t *) stream->abstract;
-
+
/* Fetch the error information */
errstr = BZ2_bzerror(self->bz_file, &errnum);
-
+
/* Determine what to return */
switch (opt) {
case PHP_BZ_ERRNO:
@@ -623,7 +627,7 @@ static void php_bz2_error(INTERNAL_FUNCTION_PARAMETERS, int opt)
break;
case PHP_BZ_ERRBOTH:
array_init(return_value);
-
+
add_assoc_long (return_value, "errno", errnum);
add_assoc_string(return_value, "errstr", (char*)errstr, 1);
break;
diff --git a/ext/bz2/tests/72613.bz2 b/ext/bz2/tests/72613.bz2
new file mode 100644
index 0000000000..0b932f8d91
--- /dev/null
+++ b/ext/bz2/tests/72613.bz2
Binary files differ
diff --git a/ext/bz2/tests/bug72613.phpt b/ext/bz2/tests/bug72613.phpt
new file mode 100644
index 0000000000..82547e6ae0
--- /dev/null
+++ b/ext/bz2/tests/bug72613.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Bug #72613 (Inadequate error handling in bzread())
+--SKIPIF--
+<?php if (!extension_loaded("bz2")) print "skip"; ?>
+--FILE--
+<?php
+$fp = bzopen(__DIR__.'/72613.bz2', 'r');
+if ($fp === FALSE) {
+ exit("ERROR: bzopen()");
+}
+$data = "";
+while (!feof($fp)) {
+ $res = bzread($fp);
+ if ($res === FALSE) {
+ exit("ERROR: bzread()");
+ }
+ $data .= $res;
+}
+bzclose($fp);
+?>
+DONE
+--EXPECT--
+DONE \ No newline at end of file
diff --git a/ext/exif/exif.c b/ext/exif/exif.c
index 1ff4b4b14e..5564de4b4a 100644
--- a/ext/exif/exif.c
+++ b/ext/exif/exif.c
@@ -2613,6 +2613,7 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP
*pszEncoding = NULL;
/* Copy the comment */
if (ByteCount>=8) {
+ const zend_encoding *from, *to;
if (!memcmp(szValuePtr, "UNICODE\0", 8)) {
*pszEncoding = estrdup((const char*)szValuePtr);
szValuePtr = szValuePtr+8;
@@ -2633,14 +2634,16 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP
} else {
decode = ImageInfo->decode_unicode_le;
}
+ to = zend_multibyte_fetch_encoding(ImageInfo->encode_unicode TSRMLS_CC);
+ from = zend_multibyte_fetch_encoding(decode TSRMLS_CC);
/* XXX this will fail again if encoding_converter returns on error something different than SIZE_MAX */
- if (zend_multibyte_encoding_converter(
+ if (!to || !from || zend_multibyte_encoding_converter(
(unsigned char**)pszInfoPtr,
&len,
(unsigned char*)szValuePtr,
ByteCount,
- zend_multibyte_fetch_encoding(ImageInfo->encode_unicode TSRMLS_CC),
- zend_multibyte_fetch_encoding(decode TSRMLS_CC)
+ to,
+ from
TSRMLS_CC) == (size_t)-1) {
len = exif_process_string_raw(pszInfoPtr, szValuePtr, ByteCount);
}
@@ -2655,13 +2658,15 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP
szValuePtr = szValuePtr+8;
ByteCount -= 8;
/* XXX this will fail again if encoding_converter returns on error something different than SIZE_MAX */
- if (zend_multibyte_encoding_converter(
+ to = zend_multibyte_fetch_encoding(ImageInfo->encode_jis TSRMLS_CC);
+ from = zend_multibyte_fetch_encoding(ImageInfo->motorola_intel ? ImageInfo->decode_jis_be : ImageInfo->decode_jis_le TSRMLS_CC);
+ if (!to || !from || zend_multibyte_encoding_converter(
(unsigned char**)pszInfoPtr,
&len,
(unsigned char*)szValuePtr,
ByteCount,
- zend_multibyte_fetch_encoding(ImageInfo->encode_jis TSRMLS_CC),
- zend_multibyte_fetch_encoding(ImageInfo->motorola_intel ? ImageInfo->decode_jis_be : ImageInfo->decode_jis_le TSRMLS_CC)
+ to,
+ from
TSRMLS_CC) == (size_t)-1) {
len = exif_process_string_raw(pszInfoPtr, szValuePtr, ByteCount);
}
@@ -2732,6 +2737,12 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
break;
}
+ if (maker_note->offset >= value_len) {
+ /* Do not go past the value end */
+ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "IFD data too short: 0x%04X offset 0x%04X", value_len, maker_note->offset);
+ return FALSE;
+ }
+
dir_start = value_ptr + maker_note->offset;
#ifdef EXIF_DEBUG
@@ -2760,10 +2771,19 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
offset_base = value_ptr;
break;
case MN_OFFSET_GUESS:
+ if (maker_note->offset + 10 + 4 >= value_len) {
+ /* Can not read dir_start+10 since it's beyond value end */
+ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "IFD data too short: 0x%04X", value_len);
+ return FALSE;
+ }
offset_diff = 2 + NumDirEntries*12 + 4 - php_ifd_get32u(dir_start+10, ImageInfo->motorola_intel);
#ifdef EXIF_DEBUG
exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Using automatic offset correction: 0x%04X", ((int)dir_start-(int)offset_base+maker_note->offset+displacement) + offset_diff);
#endif
+ if (offset_diff < 0 || offset_diff >= value_len ) {
+ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "IFD data bad offset: 0x%04X length 0x%04X", offset_diff, value_len);
+ return FALSE;
+ }
offset_base = value_ptr + offset_diff;
break;
default:
@@ -2772,7 +2792,7 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
}
if ((2+NumDirEntries*12) > value_len) {
- exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size: 2 + x%04X*12 = x%04X > x%04X", NumDirEntries, 2+NumDirEntries*12, value_len);
+ exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size: 2 + 0x%04X*12 = 0x%04X > 0x%04X", NumDirEntries, 2+NumDirEntries*12, value_len);
return FALSE;
}
@@ -3058,7 +3078,10 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
break;
case TAG_MAKER_NOTE:
- exif_process_IFD_in_MAKERNOTE(ImageInfo, value_ptr, byte_count, offset_base, IFDlength, displacement TSRMLS_CC);
+ if (!exif_process_IFD_in_MAKERNOTE(ImageInfo, value_ptr, byte_count, offset_base, IFDlength, displacement TSRMLS_CC)) {
+ EFREE_IF(outside);
+ return FALSE;
+ }
break;
case TAG_EXIF_IFD_POINTER:
diff --git a/ext/exif/tests/bug54002.phpt b/ext/exif/tests/bug54002.phpt
index c51fa58897..8f85339190 100644
--- a/ext/exif/tests/bug54002.phpt
+++ b/ext/exif/tests/bug54002.phpt
@@ -13,8 +13,4 @@ exif_read_data(__DIR__ . '/bug54002_2.jpeg');
--EXPECTF--
Warning: exif_read_data(bug54002_1.jpeg): Process tag(x0205=UndefinedTa): Illegal byte_count in %sbug54002.php on line %d
-Warning: exif_read_data(bug54002_1.jpeg): Process tag(xA000=FlashPixVer): Illegal pointer offset(%s) in %sbug54002.php on line %d
-
-Warning: exif_read_data(bug54002_2.jpeg): Process tag(x0205=UndefinedTa): Illegal byte_count in %sbug54002.php on line %d
-
-Warning: exif_read_data(bug54002_2.jpeg): Process tag(xA000=FlashPixVer): Illegal pointer offset(%s) in %sbug54002.php on line %d
+Warning: exif_read_data(bug54002_2.jpeg): Process tag(x0205=UndefinedTa): Illegal byte_count in %sbug54002.php on line %d \ No newline at end of file
diff --git a/ext/exif/tests/bug62523_2.phpt b/ext/exif/tests/bug62523_2.phpt
index ddc8ae824e..c533d42652 100644
--- a/ext/exif/tests/bug62523_2.phpt
+++ b/ext/exif/tests/bug62523_2.phpt
@@ -10,7 +10,9 @@ echo "Test\n";
var_dump(count(exif_read_data(__DIR__."/bug62523_2.jpg")));
?>
Done
---EXPECT--
+--EXPECTF--
Test
-int(76)
+
+Warning: exif_read_data(bug62523_2.jpg): IFD data bad offset: 0xADB23672 length 0x0D94 in %s/bug62523_2.php on line %d
+int(30)
Done
diff --git a/ext/exif/tests/bug72603.jpeg b/ext/exif/tests/bug72603.jpeg
new file mode 100644
index 0000000000..1764c805fb
--- /dev/null
+++ b/ext/exif/tests/bug72603.jpeg
Binary files differ
diff --git a/ext/exif/tests/bug72603.phpt b/ext/exif/tests/bug72603.phpt
new file mode 100644
index 0000000000..a4295f9848
--- /dev/null
+++ b/ext/exif/tests/bug72603.phpt
@@ -0,0 +1,11 @@
+--TEST--
+Bug #72603 (Out of bound read in exif_process_IFD_in_MAKERNOTE)
+--SKIPIF--
+<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
+--FILE--
+<?php
+var_dump(count(exif_read_data(dirname(__FILE__) . "/bug72603.jpeg")));
+?>
+--EXPECTF--
+Warning: exif_read_data(bug72603.jpeg): IFD data bad offset: 0x058C length 0x001C in %s/bug72603.php on line %d
+int(13) \ No newline at end of file
diff --git a/ext/exif/tests/bug72618.jpg b/ext/exif/tests/bug72618.jpg
new file mode 100644
index 0000000000..0a61ae2e02
--- /dev/null
+++ b/ext/exif/tests/bug72618.jpg
Binary files differ
diff --git a/ext/exif/tests/bug72618.phpt b/ext/exif/tests/bug72618.phpt
new file mode 100644
index 0000000000..424c0ec402
--- /dev/null
+++ b/ext/exif/tests/bug72618.phpt
@@ -0,0 +1,11 @@
+--TEST--
+Bug 72618 (NULL Pointer Dereference in exif_process_user_comment)
+--SKIPIF--
+<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
+--FILE--
+<?php
+var_dump(count(exif_read_data(dirname(__FILE__) . "/bug72618.jpg")));
+?>
+--EXPECTF--
+Warning: exif_read_data(bug72618.jpg): IFD data bad offset: 0x058E length 0x0030 in %s/bug72618.php on line %d
+int(13) \ No newline at end of file
diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c
index a5799c59d5..3a7ca3639f 100644
--- a/ext/gd/libgd/gd.c
+++ b/ext/gd/libgd/gd.c
@@ -190,7 +190,7 @@ gdImagePtr gdImageCreateTrueColor (int sx, int sy)
return NULL;
}
- if (overflow2(sizeof(int), sx)) {
+ if (overflow2(sizeof(int *), sx)) {
return NULL;
}
diff --git a/ext/gd/libgd/gd_interpolation.c b/ext/gd/libgd/gd_interpolation.c
index 83319966f9..8162b7e113 100644
--- a/ext/gd/libgd/gd_interpolation.c
+++ b/ext/gd/libgd/gd_interpolation.c
@@ -879,20 +879,39 @@ int getPixelInterpolated(gdImagePtr im, const double x, const double y, const in
static inline LineContribType * _gdContributionsAlloc(unsigned int line_length, unsigned int windows_size)
{
unsigned int u = 0;
- LineContribType *res;
+ LineContribType *res;
+ int overflow_error = 0;
res = (LineContribType *) gdMalloc(sizeof(LineContribType));
if (!res) {
return NULL;
}
- res->WindowSize = windows_size;
- res->LineLength = line_length;
- res->ContribRow = (ContributionType *) gdMalloc(line_length * sizeof(ContributionType));
-
- for (u = 0 ; u < line_length ; u++) {
- res->ContribRow[u].Weights = (double *) gdMalloc(windows_size * sizeof(double));
- }
- return res;
+ res->WindowSize = windows_size;
+ res->LineLength = line_length;
+ if (overflow2(line_length, sizeof(ContributionType))) {
+ return NULL;
+ }
+ res->ContribRow = (ContributionType *) gdMalloc(line_length * sizeof(ContributionType));
+ if (res->ContribRow == NULL) {
+ gdFree(res);
+ return NULL;
+ }
+ for (u = 0 ; u < line_length ; u++) {
+ if (overflow2(windows_size, sizeof(double))) {
+ overflow_error = 1;
+ } else {
+ res->ContribRow[u].Weights = (double *) gdMalloc(windows_size * sizeof(double));
+ }
+ if (overflow_error == 1 || res->ContribRow[u].Weights == NULL) {
+ u--;
+ while (u >= 0) {
+ gdFree(res->ContribRow[u].Weights);
+ u--;
+ }
+ return NULL;
+ }
+ }
+ return res;
}
static inline void _gdContributionsFree(LineContribType * p)
@@ -907,59 +926,62 @@ static inline void _gdContributionsFree(LineContribType * p)
static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsigned int src_size, double scale_d, const interpolation_method pFilter)
{
- double width_d;
- double scale_f_d = 1.0;
- const double filter_width_d = DEFAULT_BOX_RADIUS;
+ double width_d;
+ double scale_f_d = 1.0;
+ const double filter_width_d = DEFAULT_BOX_RADIUS;
int windows_size;
unsigned int u;
LineContribType *res;
+ int overflow_error = 0;
- if (scale_d < 1.0) {
- width_d = filter_width_d / scale_d;
- scale_f_d = scale_d;
- } else {
- width_d= filter_width_d;
- }
-
- windows_size = 2 * (int)ceil(width_d) + 1;
- res = _gdContributionsAlloc(line_size, windows_size);
+ if (scale_d < 1.0) {
+ width_d = filter_width_d / scale_d;
+ scale_f_d = scale_d;
+ } else {
+ width_d= filter_width_d;
+ }
- for (u = 0; u < line_size; u++) {
- const double dCenter = (double)u / scale_d;
- /* get the significant edge points affecting the pixel */
- register int iLeft = MAX(0, (int)floor (dCenter - width_d));
- int iRight = MIN((int)ceil(dCenter + width_d), (int)src_size - 1);
- double dTotalWeight = 0.0;
+ windows_size = 2 * (int)ceil(width_d) + 1;
+ res = _gdContributionsAlloc(line_size, windows_size);
+ if (res == NULL) {
+ return NULL;
+ }
+ for (u = 0; u < line_size; u++) {
+ const double dCenter = (double)u / scale_d;
+ /* get the significant edge points affecting the pixel */
+ register int iLeft = MAX(0, (int)floor (dCenter - width_d));
+ int iRight = MIN((int)ceil(dCenter + width_d), (int)src_size - 1);
+ double dTotalWeight = 0.0;
int iSrc;
- /* Cut edge points to fit in filter window in case of spill-off */
- if (iRight - iLeft + 1 > windows_size) {
- if (iLeft < ((int)src_size - 1 / 2)) {
- iLeft++;
- } else {
- iRight--;
- }
- }
+ /* Cut edge points to fit in filter window in case of spill-off */
+ if (iRight - iLeft + 1 > windows_size) {
+ if (iLeft < ((int)src_size - 1 / 2)) {
+ iLeft++;
+ } else {
+ iRight--;
+ }
+ }
- res->ContribRow[u].Left = iLeft;
- res->ContribRow[u].Right = iRight;
+ res->ContribRow[u].Left = iLeft;
+ res->ContribRow[u].Right = iRight;
- for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
- dTotalWeight += (res->ContribRow[u].Weights[iSrc-iLeft] = scale_f_d * (*pFilter)(scale_f_d * (dCenter - (double)iSrc)));
- }
+ for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
+ dTotalWeight += (res->ContribRow[u].Weights[iSrc-iLeft] = scale_f_d * (*pFilter)(scale_f_d * (dCenter - (double)iSrc)));
+ }
if (dTotalWeight < 0.0) {
_gdContributionsFree(res);
return NULL;
}
- if (dTotalWeight > 0.0) {
- for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
- res->ContribRow[u].Weights[iSrc-iLeft] /= dTotalWeight;
- }
- }
- }
- return res;
+ if (dTotalWeight > 0.0) {
+ for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
+ res->ContribRow[u].Weights[iSrc-iLeft] /= dTotalWeight;
+ }
+ }
+ }
+ return res;
}
static inline void _gdScaleRow(gdImagePtr pSrc, unsigned int src_width, gdImagePtr dst, unsigned int dst_width, unsigned int row, LineContribType *contrib)
diff --git a/ext/gd/tests/bug72512_0.phpt b/ext/gd/tests/bug72512_0.phpt
new file mode 100644
index 0000000000..5f98662d45
--- /dev/null
+++ b/ext/gd/tests/bug72512_0.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Bug #72512 gdImageTrueColorToPaletteBody allows arbitrary write/read access, var 0
+--SKIPIF--
+<?php
+ if (!extension_loaded('gd')) die("skip gd extension not available\n");
+?>
+--FILE--
+<?php
+
+$img = imagecreatetruecolor(13, 1007);
+
+imagecolortransparent($img, -10066304);
+imagetruecolortopalette($img, TRUE, 3);
+imagescale($img, 1, 65535);
+?>
+==DONE==
+--EXPECT--
+==DONE==
diff --git a/ext/gd/tests/bug72512_1.phpt b/ext/gd/tests/bug72512_1.phpt
new file mode 100644
index 0000000000..bba01a7118
--- /dev/null
+++ b/ext/gd/tests/bug72512_1.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Bug #72512 gdImageTrueColorToPaletteBody allows arbitrary write/read access, var 1
+--SKIPIF--
+<?php
+ if (!extension_loaded('gd')) die("skip gd extension not available\n");
+?>
+--FILE--
+<?php
+
+$img = imagecreatetruecolor(100, 100);
+imagecolortransparent($img, -1000000);
+imagetruecolortopalette($img, TRUE, 3);
+imagecolortransparent($img, 9);
+
+?>
+==DONE==
+--EXPECT--
+==DONE==
diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c
index 31f60b39a4..443856ff5e 100644
--- a/ext/intl/locale/locale_methods.c
+++ b/ext/intl/locale/locale_methods.c
@@ -1591,6 +1591,24 @@ PHP_FUNCTION(locale_accept_from_http)
"locale_accept_from_http: unable to parse input parameters", 0 TSRMLS_CC );
RETURN_FALSE;
}
+ if(http_accept_len > ULOC_FULLNAME_CAPACITY) {
+ /* check each fragment, if any bigger than capacity, can't do it due to bug #72533 */
+ char *start = http_accept;
+ char *end;
+ size_t len;
+ do {
+ end = strchr(start, ',');
+ len = end ? end-start : http_accept_len-(start-http_accept);
+ if(len > ULOC_FULLNAME_CAPACITY) {
+ intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "locale_accept_from_http: locale string too long", 0 TSRMLS_CC );
+ RETURN_FALSE;
+ }
+ if(end) {
+ start = end+1;
+ }
+ } while(end != NULL);
+ }
available = ures_openAvailableLocales(NULL, &status);
INTL_CHECK_STATUS(status, "locale_accept_from_http: failed to retrieve locale list");
diff --git a/ext/intl/tests/bug72533.phpt b/ext/intl/tests/bug72533.phpt
new file mode 100644
index 0000000000..c7fcba39d0
--- /dev/null
+++ b/ext/intl/tests/bug72533.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Bug #72533 (locale_accept_from_http out-of-bounds access)
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+--FILE--
+<?php
+
+function ut_main()
+{
+ $ret = var_export(ut_loc_accept_http(str_repeat('x', 256)), true);
+ $ret .= "\n";
+ if(intl_is_failure(intl_get_error_code())) {
+ $ret .= var_export(intl_get_error_message(), true);
+ }
+ $ret .= "\n";
+ $ret .= var_export(ut_loc_accept_http(str_repeat('en,', 256)), true);
+ $ret .= "\n";
+ if(intl_is_failure(intl_get_error_code())) {
+ $ret .= var_export(intl_get_error_message(), true);
+ }
+ return $ret;
+}
+
+include_once( 'ut_common.inc' );
+ut_run();
+?>
+--EXPECTF--
+false
+'locale_accept_from_http: locale string too long: U_ILLEGAL_ARGUMENT_ERROR'
+'en' \ No newline at end of file
diff --git a/ext/session/session.c b/ext/session/session.c
index b4e5a327c1..c668bb7b2a 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -867,7 +867,7 @@ PS_SERIALIZER_DECODE_FUNC(php_serialize) /* {{{ */
if (php_var_unserialize(&session_vars, &val, endptr, &var_hash TSRMLS_CC)) {
var_push_dtor(&var_hash, &session_vars);
}
-
+
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
if (PS(http_session_vars)) {
zval_ptr_dtor(&PS(http_session_vars));
@@ -932,6 +932,7 @@ PS_SERIALIZER_DECODE_FUNC(php_binary) /* {{{ */
namelen = ((unsigned char)(*p)) & (~PS_BIN_UNDEF);
if (namelen < 0 || namelen > PS_BIN_MAX || (p + namelen) >= endptr) {
+ PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return FAILURE;
}
diff --git a/ext/session/tests/bug72562.phpt b/ext/session/tests/bug72562.phpt
new file mode 100644
index 0000000000..d85e48b069
--- /dev/null
+++ b/ext/session/tests/bug72562.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Bug #72562: Use After Free in unserialize() with Unexpected Session Deserialization
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--FILE--
+<?php
+
+ini_set('session.serialize_handler', 'php_binary');
+session_start();
+$sess = "\x1xi:1;\x2y";
+session_decode($sess);
+$uns_1 = '{';
+$out_1[] = unserialize($uns_1);
+unset($out_1);
+$fakezval = ptr2str(1122334455);
+$fakezval .= ptr2str(0);
+$fakezval .= "\x00\x00\x00\x00";
+$fakezval .= "\x01";
+$fakezval .= "\x00";
+$fakezval .= "\x00\x00";
+for ($i = 0; $i < 5; $i++) {
+ $v[$i] = $fakezval.$i;
+}
+$uns_2 = 'R:2;';
+$out_2 = unserialize($uns_2);
+var_dump($out_2);
+
+function ptr2str($ptr)
+{
+ $out = '';
+ for ($i = 0; $i < 8; $i++) {
+ $out .= chr($ptr & 0xff);
+ $ptr >>= 8;
+ }
+ return $out;
+}
+?>
+--EXPECTF--
+Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/bug72562.php on line %d
+
+Notice: unserialize(): Error at offset 0 of 1 bytes in %s/bug72562.php on line %d
+
+Notice: unserialize(): Error at offset 4 of 4 bytes in %s/bug72562.php on line %d
+bool(false)
diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c
index d5e21f911c..b88cdcd14c 100644
--- a/ext/snmp/snmp.c
+++ b/ext/snmp/snmp.c
@@ -473,7 +473,7 @@ static void php_snmp_session_destructor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
static void php_snmp_object_free_storage(void *object TSRMLS_DC)
{
php_snmp_object *intern = (php_snmp_object *)object;
-
+
if (!intern) {
return;
}
@@ -481,7 +481,7 @@ static void php_snmp_object_free_storage(void *object TSRMLS_DC)
netsnmp_session_free(&(intern->session));
zend_object_std_dtor(&intern->zo TSRMLS_CC);
-
+
efree(intern);
}
@@ -501,7 +501,7 @@ static zend_object_value php_snmp_object_new(zend_class_entry *class_type TSRMLS
retval.handlers = (zend_object_handlers *) &php_snmp_object_handlers;
return retval;
-
+
}
/* {{{ php_snmp_error
@@ -554,7 +554,7 @@ static void php_snmp_getvalue(struct variable_list *vars, zval *snmpval TSRMLS_D
char *dbuf = (char *)NULL;
int buflen = sizeof(sbuf) - 1;
int val_len = vars->val_len;
-
+
/* use emalloc() for large values, use static array otherwize */
/* There is no way to know the size of buffer snprint_value() needs in order to print a value there.
@@ -700,7 +700,7 @@ static void php_snmp_getvalue(struct variable_list *vars, zval *snmpval TSRMLS_D
* SNMP object fetcher/setter for all SNMP versions
*
*/
-static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st,
+static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st,
struct snmp_session *session,
struct objid_query *objid_query)
{
@@ -719,7 +719,7 @@ static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st,
/* we start with retval=FALSE. If any actual data is acquired, retval will be set to appropriate type */
RETVAL_FALSE;
-
+
/* reset errno and errstr */
php_snmp_error(getThis(), NULL TSRMLS_CC, PHP_SNMP_ERRNO_NOERROR, "");
@@ -803,8 +803,8 @@ retry:
}
for (vars = response->variables; vars; vars = vars->next_variable) {
/* do not output errors as values */
- if ( vars->type == SNMP_ENDOFMIBVIEW ||
- vars->type == SNMP_NOSUCHOBJECT ||
+ if ( vars->type == SNMP_ENDOFMIBVIEW ||
+ vars->type == SNMP_NOSUCHOBJECT ||
vars->type == SNMP_NOSUCHINSTANCE ) {
if ((st & SNMP_CMD_WALK) && Z_TYPE_P(return_value) == IS_ARRAY) {
break;
@@ -814,8 +814,8 @@ retry:
php_snmp_error(getThis(), NULL TSRMLS_CC, PHP_SNMP_ERRNO_ERROR_IN_REPLY, "Error in packet at '%s': %s", buf, buf2);
continue;
}
-
- if ((st & SNMP_CMD_WALK) &&
+
+ if ((st & SNMP_CMD_WALK) &&
(vars->name_length < rootlen || memcmp(root, vars->name, rootlen * sizeof(oid)))) { /* not part of this subtree */
if (Z_TYPE_P(return_value) == IS_ARRAY) { /* some records are fetched already, shut down further lookup */
keepwalking = 0;
@@ -1099,7 +1099,7 @@ static int php_snmp_parse_oid(zval *object, int st, struct objid_query *objid_qu
efree(objid_query->vars);
return FALSE;
}
- } else {
+ } else {
memmove((char *)objid_query->vars[0].name, (char *)objid_mib, sizeof(objid_mib));
objid_query->vars[0].name_length = sizeof(objid_mib) / sizeof(oid);
}
@@ -1435,7 +1435,7 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
int session_less_mode = (getThis() == NULL);
php_snmp_object *snmp_object;
php_snmp_object glob_snmp_object;
-
+
objid_query.max_repetitions = -1;
objid_query.non_repeaters = 0;
objid_query.valueretrieval = SNMP_G(valueretrieval);
@@ -1548,7 +1548,7 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
}
php_snmp_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU, st, session, &objid_query);
-
+
efree(objid_query.vars);
if (session_less_mode) {
@@ -1561,7 +1561,7 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
}
/* }}} */
-/* {{{ proto mixed snmpget(string host, string community, mixed object_id [, int timeout [, int retries]])
+/* {{{ proto mixed snmpget(string host, string community, mixed object_id [, int timeout [, int retries]])
Fetch a SNMP object */
PHP_FUNCTION(snmpget)
{
@@ -1569,7 +1569,7 @@ PHP_FUNCTION(snmpget)
}
/* }}} */
-/* {{{ proto mixed snmpgetnext(string host, string community, mixed object_id [, int timeout [, int retries]])
+/* {{{ proto mixed snmpgetnext(string host, string community, mixed object_id [, int timeout [, int retries]])
Fetch a SNMP object */
PHP_FUNCTION(snmpgetnext)
{
@@ -1577,7 +1577,7 @@ PHP_FUNCTION(snmpgetnext)
}
/* }}} */
-/* {{{ proto mixed snmpwalk(string host, string community, mixed object_id [, int timeout [, int retries]])
+/* {{{ proto mixed snmpwalk(string host, string community, mixed object_id [, int timeout [, int retries]])
Return all objects under the specified object id */
PHP_FUNCTION(snmpwalk)
{
@@ -1593,7 +1593,7 @@ PHP_FUNCTION(snmprealwalk)
}
/* }}} */
-/* {{{ proto bool snmpset(string host, string community, mixed object_id, mixed type, mixed value [, int timeout [, int retries]])
+/* {{{ proto bool snmpset(string host, string community, mixed object_id, mixed type, mixed value [, int timeout [, int retries]])
Set the value of a SNMP object */
PHP_FUNCTION(snmpset)
{
@@ -1640,7 +1640,7 @@ PHP_FUNCTION(snmp_set_enum_print)
netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM, (int) a1);
RETURN_TRUE;
-}
+}
/* }}} */
/* {{{ proto bool snmp_set_oid_output_format(int oid_format)
@@ -1668,10 +1668,10 @@ PHP_FUNCTION(snmp_set_oid_output_format)
RETURN_FALSE;
break;
}
-}
+}
/* }}} */
-/* {{{ proto mixed snmp2_get(string host, string community, mixed object_id [, int timeout [, int retries]])
+/* {{{ proto mixed snmp2_get(string host, string community, mixed object_id [, int timeout [, int retries]])
Fetch a SNMP object */
PHP_FUNCTION(snmp2_get)
{
@@ -1679,7 +1679,7 @@ PHP_FUNCTION(snmp2_get)
}
/* }}} */
-/* {{{ proto mixed snmp2_getnext(string host, string community, mixed object_id [, int timeout [, int retries]])
+/* {{{ proto mixed snmp2_getnext(string host, string community, mixed object_id [, int timeout [, int retries]])
Fetch a SNMP object */
PHP_FUNCTION(snmp2_getnext)
{
@@ -1687,7 +1687,7 @@ PHP_FUNCTION(snmp2_getnext)
}
/* }}} */
-/* {{{ proto mixed snmp2_walk(string host, string community, mixed object_id [, int timeout [, int retries]])
+/* {{{ proto mixed snmp2_walk(string host, string community, mixed object_id [, int timeout [, int retries]])
Return all objects under the specified object id */
PHP_FUNCTION(snmp2_walk)
{
@@ -1703,7 +1703,7 @@ PHP_FUNCTION(snmp2_real_walk)
}
/* }}} */
-/* {{{ proto bool snmp2_set(string host, string community, mixed object_id, mixed type, mixed value [, int timeout [, int retries]])
+/* {{{ proto bool snmp2_set(string host, string community, mixed object_id, mixed type, mixed value [, int timeout [, int retries]])
Set the value of a SNMP object */
PHP_FUNCTION(snmp2_set)
{
@@ -1819,7 +1819,7 @@ PHP_METHOD(snmp, __construct)
snmp_object = (php_snmp_object *)zend_object_store_get_object(object TSRMLS_CC);
zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
-
+
if (zend_parse_parameters(argc TSRMLS_CC, "lss|ll", &version, &a1, &a1_len, &a2, &a2_len, &timeout, &retries) == FAILURE) {
zend_restore_error_handling(&error_handling TSRMLS_CC);
return;
@@ -1841,7 +1841,7 @@ PHP_METHOD(snmp, __construct)
if (snmp_object->session) {
netsnmp_session_free(&(snmp_object->session));
}
-
+
if (netsnmp_session_init(&(snmp_object->session), version, a1, a2, timeout, retries TSRMLS_CC)) {
return;
}
@@ -1855,7 +1855,7 @@ PHP_METHOD(snmp, __construct)
}
/* }}} */
-/* {{{ proto bool SNMP::close()
+/* {{{ proto bool SNMP::close()
Close SNMP session */
PHP_METHOD(snmp, close)
{
@@ -1898,7 +1898,7 @@ PHP_METHOD(snmp, walk)
}
/* }}} */
-/* {{{ proto bool SNMP::set(mixed object_id, mixed type, mixed value)
+/* {{{ proto bool SNMP::set(mixed object_id, mixed type, mixed value)
Set the value of a SNMP object */
PHP_METHOD(snmp, set)
{
@@ -1916,7 +1916,7 @@ PHP_METHOD(snmp, setSecurity)
int argc = ZEND_NUM_ARGS();
snmp_object = (php_snmp_object *)zend_object_store_get_object(object TSRMLS_CC);
-
+
if (zend_parse_parameters(argc TSRMLS_CC, "s|ssssss", &a1, &a1_len, &a2, &a2_len, &a3, &a3_len,
&a4, &a4_len, &a5, &a5_len, &a6, &a6_len, &a7, &a7_len) == FAILURE) {
RETURN_FALSE;
@@ -1930,7 +1930,7 @@ PHP_METHOD(snmp, setSecurity)
}
/* }}} */
-/* {{{ proto long SNMP::getErrno()
+/* {{{ proto long SNMP::getErrno()
Get last error code number */
PHP_METHOD(snmp, getErrno)
{
@@ -1944,7 +1944,7 @@ PHP_METHOD(snmp, getErrno)
}
/* }}} */
-/* {{{ proto long SNMP::getError()
+/* {{{ proto long SNMP::getError()
Get last error message */
PHP_METHOD(snmp, getError)
{
@@ -2093,6 +2093,14 @@ static int php_snmp_has_property(zval *object, zval *member, int has_set_exists,
}
/* }}} */
+static HashTable *php_snmp_get_gc(zval *object, zval ***gc_data, int *gc_data_count TSRMLS_DC) /* {{{ */
+{
+ *gc_data = NULL;
+ *gc_data_count = 0;
+ return zend_std_get_properties(object TSRMLS_CC);
+}
+/* }}} */
+
/* {{{ php_snmp_get_properties(zval *object)
Returns all object properties. Injects SNMP properties into object on first call */
static HashTable *php_snmp_get_properties(zval *object TSRMLS_DC)
@@ -2135,23 +2143,23 @@ static int php_snmp_read_info(php_snmp_object *snmp_object, zval **retval TSRMLS
if (snmp_object->session == NULL) {
return SUCCESS;
}
-
+
MAKE_STD_ZVAL(val);
ZVAL_STRINGL(val, snmp_object->session->peername, strlen(snmp_object->session->peername), 1);
add_assoc_zval(*retval, "hostname", val);
-
+
MAKE_STD_ZVAL(val);
ZVAL_LONG(val, snmp_object->session->remote_port);
add_assoc_zval(*retval, "port", val);
-
+
MAKE_STD_ZVAL(val);
ZVAL_LONG(val, snmp_object->session->timeout);
add_assoc_zval(*retval, "timeout", val);
-
+
MAKE_STD_ZVAL(val);
ZVAL_LONG(val, snmp_object->session->retries);
add_assoc_zval(*retval, "retries", val);
-
+
return SUCCESS;
}
/* }}} */
@@ -2224,7 +2232,7 @@ static int php_snmp_write_max_oids(php_snmp_object *snmp_object, zval *newval TS
} else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "max_oids should be positive integer or NULL, got %ld", Z_LVAL_P(newval));
}
-
+
if (newval == &ztmp) {
zval_dtor(newval);
}
@@ -2252,7 +2260,7 @@ static int php_snmp_write_valueretrieval(php_snmp_object *snmp_object, zval *new
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown SNMP value retrieval method '%ld'", Z_LVAL_P(newval));
ret = FAILURE;
}
-
+
if (newval == &ztmp) {
zval_dtor(newval);
}
@@ -2295,7 +2303,7 @@ static int php_snmp_write_oid_output_format(php_snmp_object *snmp_object, zval *
convert_to_long(&ztmp);
newval = &ztmp;
}
-
+
switch(Z_LVAL_P(newval)) {
case NETSNMP_OID_OUTPUT_SUFFIX:
case NETSNMP_OID_OUTPUT_MODULE:
@@ -2330,7 +2338,7 @@ static int php_snmp_write_exceptions_enabled(php_snmp_object *snmp_object, zval
newval = &ztmp;
}
- snmp_object->exceptions_enabled = Z_LVAL_P(newval);
+ snmp_object->exceptions_enabled = Z_LVAL_P(newval);
if (newval == &ztmp) {
zval_dtor(newval);
@@ -2399,6 +2407,7 @@ PHP_MINIT_FUNCTION(snmp)
php_snmp_object_handlers.write_property = php_snmp_write_property;
php_snmp_object_handlers.has_property = php_snmp_has_property;
php_snmp_object_handlers.get_properties = php_snmp_get_properties;
+ php_snmp_object_handlers.get_gc = php_snmp_get_gc;
/* Register SNMP Class */
INIT_CLASS_ENTRY(ce, "SNMP", php_snmp_class_methods);
@@ -2465,7 +2474,7 @@ PHP_MINIT_FUNCTION(snmp)
PHP_MSHUTDOWN_FUNCTION(snmp)
{
snmp_shutdown("snmpapp");
-
+
zend_hash_destroy(&php_snmp_properties);
return SUCCESS;
diff --git a/ext/snmp/tests/bug72479.phpt b/ext/snmp/tests/bug72479.phpt
new file mode 100644
index 0000000000..0308754360
--- /dev/null
+++ b/ext/snmp/tests/bug72479.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Bug #72479: Use After Free Vulnerability in SNMP with GC and unserialize()
+--SKIPIF--
+<?php
+require_once(dirname(__FILE__).'/skipif.inc');
+?>
+--FILE--
+<?php
+$arr = [1, [1, 2, 3, 4, 5], 3, 4, 5];
+$poc = 'a:3:{i:1;N;i:2;O:4:"snmp":1:{s:11:"quick_print";'.serialize($arr).'}i:1;R:7;}';
+$out = unserialize($poc);
+gc_collect_cycles();
+$fakezval = ptr2str(1122334455);
+$fakezval .= ptr2str(0);
+$fakezval .= "\x00\x00\x00\x00";
+$fakezval .= "\x01";
+$fakezval .= "\x00";
+$fakezval .= "\x00\x00";
+for ($i = 0; $i < 5; $i++) {
+ $v[$i] = $fakezval.$i;
+}
+var_dump($out[1]);
+
+function ptr2str($ptr)
+{
+ $out = '';
+ for ($i = 0; $i < 8; $i++) {
+ $out .= chr($ptr & 0xff);
+ $ptr >>= 8;
+ }
+ return $out;
+}
+?>
+--EXPECT--
+int(1) \ No newline at end of file
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index 57de98b15d..f7776d6e5b 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -3986,21 +3986,24 @@ PHP_FUNCTION(long2ip)
* System Functions *
********************/
-/* {{{ proto string getenv(string varname)
+/* {{{ proto string getenv(string varname[, bool local_only])
Get the value of an environment variable */
PHP_FUNCTION(getenv)
{
char *ptr, *str;
int str_len;
+ zend_bool local_only = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &str, &str_len, &local_only) == FAILURE) {
RETURN_FALSE;
}
- /* SAPI method returns an emalloc()'d string */
- ptr = sapi_getenv(str, str_len TSRMLS_CC);
- if (ptr) {
- RETURN_STRING(ptr, 0);
+ if (!local_only) {
+ /* SAPI method returns an emalloc()'d string */
+ ptr = sapi_getenv(str, str_len TSRMLS_CC);
+ if (ptr) {
+ RETURN_STRING(ptr, 0);
+ }
}
#ifdef PHP_WIN32
{
diff --git a/ext/xmlrpc/libxmlrpc/simplestring.c b/ext/xmlrpc/libxmlrpc/simplestring.c
index a084d0e64f..c88754fb9a 100644
--- a/ext/xmlrpc/libxmlrpc/simplestring.c
+++ b/ext/xmlrpc/libxmlrpc/simplestring.c
@@ -5,28 +5,28 @@
Epinions.com may be contacted at feedback@epinions-inc.com
*/
-/*
- Copyright 2000 Epinions, Inc.
+/*
+ Copyright 2000 Epinions, Inc.
- Subject to the following 3 conditions, Epinions, Inc. permits you, free
- of charge, to (a) use, copy, distribute, modify, perform and display this
- software and associated documentation files (the "Software"), and (b)
- permit others to whom the Software is furnished to do so as well.
+ Subject to the following 3 conditions, Epinions, Inc. permits you, free
+ of charge, to (a) use, copy, distribute, modify, perform and display this
+ software and associated documentation files (the "Software"), and (b)
+ permit others to whom the Software is furnished to do so as well.
- 1) The above copyright notice and this permission notice shall be included
- without modification in all copies or substantial portions of the
- Software.
+ 1) The above copyright notice and this permission notice shall be included
+ without modification in all copies or substantial portions of the
+ Software.
- 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF
- ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY
- IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR
- PURPOSE OR NONINFRINGEMENT.
+ 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF
+ ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY
+ IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ PURPOSE OR NONINFRINGEMENT.
- 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
- SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
- OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING
- NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH
- DAMAGES.
+ 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
+ SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT
+ OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING
+ NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH
+ DAMAGES.
*/
@@ -71,7 +71,7 @@ static const char rcsid[] = "#(@) $Id$";
*
* Oh, and it is also binary safe, ie it can handle strings with embedded NULLs,
* so long as the real length is passed in.
- *
+ *
* And the masses rejoiced.
*
* BUGS
@@ -136,7 +136,7 @@ static void simplestring_init_str(simplestring* string) {
* NOTES
* This function is very fast as it does not de-allocate any memory.
* SEE ALSO
- *
+ *
* SOURCE
*/
void simplestring_clear(simplestring* string) {
@@ -172,6 +172,9 @@ void simplestring_free(simplestring* string) {
}
/******/
+#ifndef SIZE_MAX
+#define SIZE_MAX ((size_t)-1)
+#endif
/****f* FUNC/simplestring_addn
* NAME
* simplestring_addn
@@ -190,18 +193,31 @@ void simplestring_free(simplestring* string) {
* simplestring_add ()
* SOURCE
*/
-void simplestring_addn(simplestring* target, const char* source, int add_len) {
+void simplestring_addn(simplestring* target, const char* source, size_t add_len) {
+ size_t newsize = target->size, incr = 0;
if(target && source) {
if(!target->str) {
simplestring_init_str(target);
}
+
+ if((SIZE_MAX - add_len) < target->len || (SIZE_MAX - add_len - 1) < target->len) {
+ /* check for overflows, if there's a potential overflow do nothing */
+ return;
+ }
+
if(target->len + add_len + 1 > target->size) {
/* newsize is current length + new length */
- int newsize = target->len + add_len + 1;
- int incr = target->size * 2;
+ newsize = target->len + add_len + 1;
+ incr = target->size * 2;
/* align to SIMPLESTRING_INCR increments */
- newsize = newsize - (newsize % incr) + incr;
+ if (incr) {
+ newsize = newsize - (newsize % incr) + incr;
+ }
+ if(newsize < (target->len + add_len + 1)) {
+ /* some kind of overflow happened */
+ return;
+ }
target->str = (char*)realloc(target->str, newsize);
target->size = target->str ? newsize : 0;
diff --git a/ext/xmlrpc/libxmlrpc/simplestring.h b/ext/xmlrpc/libxmlrpc/simplestring.h
index c5d98cf1d8..7e88cd0ef0 100644
--- a/ext/xmlrpc/libxmlrpc/simplestring.h
+++ b/ext/xmlrpc/libxmlrpc/simplestring.h
@@ -63,7 +63,7 @@ void simplestring_init(simplestring* string);
void simplestring_clear(simplestring* string);
void simplestring_free(simplestring* string);
void simplestring_add(simplestring* string, const char* add);
-void simplestring_addn(simplestring* string, const char* add, int add_len);
+void simplestring_addn(simplestring* string, const char* add, size_t add_len);
#ifdef __cplusplus
}
diff --git a/ext/zip/zip_stream.c b/ext/zip/zip_stream.c
index 1cd134ecfb..2095ddf838 100644
--- a/ext/zip/zip_stream.c
+++ b/ext/zip/zip_stream.c
@@ -229,7 +229,7 @@ php_stream *php_stream_zip_open(const char *filename, const char *path, const ch
self = emalloc(sizeof(*self));
self->za = stream_za;
- self->zf = zf;
+ self->zf = zf;
self->stream = NULL;
self->cursor = 0;
stream = php_stream_alloc(&php_stream_zipio_ops, self, NULL, mode);
@@ -256,7 +256,7 @@ php_stream *php_stream_zip_opener(php_stream_wrapper *wrapper,
char **opened_path,
php_stream_context *context STREAMS_DC TSRMLS_DC)
{
- int path_len;
+ size_t path_len;
char *file_basename;
size_t file_basename_len;
@@ -265,7 +265,7 @@ php_stream *php_stream_zip_opener(php_stream_wrapper *wrapper,
struct zip *za;
struct zip_file *zf = NULL;
char *fragment;
- int fragment_len;
+ size_t fragment_len;
int err;
php_stream *stream = NULL;
@@ -308,7 +308,7 @@ php_stream *php_stream_zip_opener(php_stream_wrapper *wrapper,
self = emalloc(sizeof(*self));
self->za = za;
- self->zf = zf;
+ self->zf = zf;
self->stream = NULL;
self->cursor = 0;
stream = php_stream_alloc(&php_stream_zipio_ops, self, NULL, mode);
diff --git a/main/SAPI.c b/main/SAPI.c
index eebf1f0757..49ffc1c9a4 100644
--- a/main/SAPI.c
+++ b/main/SAPI.c
@@ -1,4 +1,4 @@
-/*
+/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
@@ -128,7 +128,7 @@ PHP_FUNCTION(header_register_callback)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &callback_func) == FAILURE) {
return;
}
-
+
if (!zend_is_callable(callback_func, 0, &callback_name TSRMLS_CC)) {
efree(callback_name);
RETURN_FALSE;
@@ -156,10 +156,10 @@ static void sapi_run_header_callback(TSRMLS_D)
char *callback_name = NULL;
char *callback_error = NULL;
zval *retval_ptr = NULL;
-
+
if (zend_fcall_info_init(SG(callback_func), 0, &fci, &SG(fci_cache), &callback_name, &callback_error TSRMLS_CC) == SUCCESS) {
fci.retval_ptr_ptr = &retval_ptr;
-
+
error = zend_call_function(&fci, &SG(fci_cache) TSRMLS_CC);
if (error == FAILURE) {
goto callback_failed;
@@ -170,13 +170,13 @@ static void sapi_run_header_callback(TSRMLS_D)
callback_failed:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the sapi_header_callback");
}
-
+
if (callback_name) {
efree(callback_name);
}
if (callback_error) {
efree(callback_error);
- }
+ }
}
SAPI_API void sapi_handle_post(void *arg TSRMLS_DC)
@@ -407,11 +407,11 @@ SAPI_API void sapi_activate_headers_only(TSRMLS_D)
if (SG(request_info).headers_read == 1)
return;
SG(request_info).headers_read = 1;
- zend_llist_init(&SG(sapi_headers).headers, sizeof(sapi_header_struct),
+ zend_llist_init(&SG(sapi_headers).headers, sizeof(sapi_header_struct),
(void (*)(void *)) sapi_free_header, 0);
SG(sapi_headers).send_default_content_type = 1;
- /* SG(sapi_headers).http_response_code = 200; */
+ /* SG(sapi_headers).http_response_code = 200; */
SG(sapi_headers).http_status_line = NULL;
SG(sapi_headers).mimetype = NULL;
SG(read_post_bytes) = 0;
@@ -423,7 +423,7 @@ SAPI_API void sapi_activate_headers_only(TSRMLS_D)
SG(global_request_time) = 0;
/*
- * It's possible to override this general case in the activate() callback,
+ * It's possible to override this general case in the activate() callback,
* if necessary.
*/
if (SG(request_info).request_method && !strcmp(SG(request_info).request_method, "HEAD")) {
@@ -509,7 +509,7 @@ static void sapi_send_headers_free(TSRMLS_D)
SG(sapi_headers).http_status_line = NULL;
}
}
-
+
SAPI_API void sapi_deactivate(TSRMLS_D)
{
zend_llist_destroy(&SG(sapi_headers).headers);
@@ -583,7 +583,7 @@ static int sapi_extract_response_code(const char *header_line)
break;
}
}
-
+
return code;
}
@@ -603,7 +603,7 @@ static void sapi_update_response_code(int ncode TSRMLS_DC)
SG(sapi_headers).http_response_code = ncode;
}
-/*
+/*
* since zend_llist_del_element only remove one matched item once,
* we should remove them by ourself
*/
@@ -639,7 +639,7 @@ SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bo
{
sapi_header_line ctr = {0};
int r;
-
+
ctr.line = header_line;
ctr.line_len = header_line_len;
@@ -733,7 +733,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC)
} while(header_line_len && isspace(header_line[header_line_len-1]));
header_line[header_line_len]='\0';
}
-
+
if (op == SAPI_HEADER_DELETE) {
if (strchr(header_line, ':')) {
efree(header_line);
@@ -771,7 +771,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC)
sapi_header.header_len = header_line_len;
/* Check the header for a few cases that we have special support for in SAPI */
- if (header_line_len>=5
+ if (header_line_len>=5
&& !strncasecmp(header_line, "HTTP/", 5)) {
/* filter out the response code */
sapi_update_response_code(sapi_extract_response_code(header_line) TSRMLS_CC);
@@ -830,8 +830,8 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC)
/* Return a Found Redirect if one is not already specified */
if (http_response_code) { /* user specified redirect code */
sapi_update_response_code(http_response_code TSRMLS_CC);
- } else if (SG(request_info).proto_num > 1000 &&
- SG(request_info).request_method &&
+ } else if (SG(request_info).proto_num > 1000 &&
+ SG(request_info).request_method &&
strcmp(SG(request_info).request_method, "HEAD") &&
strcmp(SG(request_info).request_method, "GET")) {
sapi_update_response_code(303 TSRMLS_CC);
@@ -1020,7 +1020,11 @@ SAPI_API struct stat *sapi_get_stat(TSRMLS_D)
SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC)
{
- if (sapi_module.getenv) {
+ if (!strncasecmp(name, "HTTP_PROXY", name_len)) {
+ /* Ugly fix for HTTP_PROXY issue, see bug #72573 */
+ return NULL;
+ }
+ if (sapi_module.getenv) {
char *value, *tmp = sapi_module.getenv(name, name_len TSRMLS_CC);
if (tmp) {
value = estrdup(tmp);
diff --git a/main/php_variables.c b/main/php_variables.c
index 58f1c7c945..018e906582 100644
--- a/main/php_variables.c
+++ b/main/php_variables.c
@@ -47,7 +47,7 @@ PHPAPI void php_register_variable_safe(char *var, char *strval, int str_len, zva
{
zval new_entry;
assert(strval != NULL);
-
+
/* Prepare value */
Z_STRLEN(new_entry) = str_len;
Z_STRVAL(new_entry) = estrndup(strval, Z_STRLEN(new_entry));
@@ -85,7 +85,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
while (*var_name && *var_name==' ') {
var_name++;
}
-
+
/*
* Prepare variable name
*/
@@ -171,7 +171,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
return;
}
*ip = 0;
- new_idx_len = strlen(index_s);
+ new_idx_len = strlen(index_s);
}
if (!index) {
@@ -214,7 +214,7 @@ plain_var:
zval_ptr_dtor(&gpc_element);
}
} else {
- /*
+ /*
* According to rfc2965, more specific paths are listed above the less specific ones.
* If we encounter a duplicate cookie name, we should skip it, since it is not possible
* to have the same (plain text) cookie name for the same path and we should not overwrite
@@ -367,7 +367,7 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
int free_buffer = 0;
char *strtok_buf = NULL;
long count = 0;
-
+
switch (arg) {
case PARSE_POST:
case PARSE_GET:
@@ -440,9 +440,9 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
separator = ";\0";
break;
}
-
+
var = php_strtok_r(res, separator, &strtok_buf);
-
+
while (var) {
val = strchr(var, '=');
@@ -537,11 +537,11 @@ static void php_build_argv(char *s, zval *track_vars_array TSRMLS_DC)
zval *arr, *argc, *tmp;
int count = 0;
char *ss, *space;
-
+
if (!(SG(request_info).argc || track_vars_array)) {
return;
}
-
+
ALLOC_INIT_ZVAL(arr);
array_init(arr);
@@ -602,7 +602,7 @@ static void php_build_argv(char *s, zval *track_vars_array TSRMLS_DC)
Z_ADDREF_P(argc);
zend_hash_update(&EG(symbol_table), "argv", sizeof("argv"), &arr, sizeof(zval *), NULL);
zend_hash_update(&EG(symbol_table), "argc", sizeof("argc"), &argc, sizeof(zval *), NULL);
- }
+ }
if (track_vars_array) {
Z_ADDREF_P(arr);
Z_ADDREF_P(argc);
@@ -732,7 +732,7 @@ static zend_bool php_auto_globals_create_get(const char *name, uint name_len TSR
zend_hash_update(&EG(symbol_table), name, name_len + 1, &vars, sizeof(zval *), NULL);
Z_ADDREF_P(vars);
-
+
return 0; /* don't rearm */
}
@@ -758,7 +758,7 @@ static zend_bool php_auto_globals_create_post(const char *name, uint name_len TS
zend_hash_update(&EG(symbol_table), name, name_len + 1, &vars, sizeof(zval *), NULL);
Z_ADDREF_P(vars);
-
+
return 0; /* don't rearm */
}
@@ -781,7 +781,7 @@ static zend_bool php_auto_globals_create_cookie(const char *name, uint name_len
zend_hash_update(&EG(symbol_table), name, name_len + 1, &vars, sizeof(zval *), NULL);
Z_ADDREF_P(vars);
-
+
return 0; /* don't rearm */
}
@@ -800,10 +800,27 @@ static zend_bool php_auto_globals_create_files(const char *name, uint name_len T
zend_hash_update(&EG(symbol_table), name, name_len + 1, &vars, sizeof(zval *), NULL);
Z_ADDREF_P(vars);
-
+
return 0; /* don't rearm */
}
+/* Upgly hack to fix HTTP_PROXY issue, see bug #72573 */
+static void check_http_proxy(HashTable *var_table)
+{
+ if (zend_hash_exists(var_table, "HTTP_PROXY", sizeof("HTTP_PROXY"))) {
+ char *local_proxy = getenv("HTTP_PROXY");
+
+ if (!local_proxy) {
+ zend_hash_del(var_table, "HTTP_PROXY", sizeof("HTTP_PROXY"));
+ } else {
+ zval *local_zval;
+ ALLOC_INIT_ZVAL(local_zval);
+ ZVAL_STRING(local_zval, local_proxy, 1);
+ zend_hash_update(var_table, "HTTP_PROXY", sizeof("HTTP_PROXY"), &local_zval, sizeof(zval **), NULL);
+ }
+ }
+}
+
static zend_bool php_auto_globals_create_server(const char *name, uint name_len TSRMLS_DC)
{
if (PG(variables_order) && (strchr(PG(variables_order),'S') || strchr(PG(variables_order),'s'))) {
@@ -812,7 +829,7 @@ static zend_bool php_auto_globals_create_server(const char *name, uint name_len
if (PG(register_argc_argv)) {
if (SG(request_info).argc) {
zval **argc, **argv;
-
+
if (zend_hash_find(&EG(symbol_table), "argc", sizeof("argc"), (void**)&argc) == SUCCESS &&
zend_hash_find(&EG(symbol_table), "argv", sizeof("argv"), (void**)&argv) == SUCCESS) {
Z_ADDREF_PP(argc);
@@ -824,7 +841,7 @@ static zend_bool php_auto_globals_create_server(const char *name, uint name_len
php_build_argv(SG(request_info).query_string, PG(http_globals)[TRACK_VARS_SERVER] TSRMLS_CC);
}
}
-
+
} else {
zval *server_vars=NULL;
ALLOC_ZVAL(server_vars);
@@ -836,9 +853,10 @@ static zend_bool php_auto_globals_create_server(const char *name, uint name_len
PG(http_globals)[TRACK_VARS_SERVER] = server_vars;
}
+ check_http_proxy(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]));
zend_hash_update(&EG(symbol_table), name, name_len + 1, &PG(http_globals)[TRACK_VARS_SERVER], sizeof(zval *), NULL);
Z_ADDREF_P(PG(http_globals)[TRACK_VARS_SERVER]);
-
+
return 0; /* don't rearm */
}
@@ -852,11 +870,12 @@ static zend_bool php_auto_globals_create_env(const char *name, uint name_len TSR
zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_ENV]);
}
PG(http_globals)[TRACK_VARS_ENV] = env_vars;
-
+
if (PG(variables_order) && (strchr(PG(variables_order),'E') || strchr(PG(variables_order),'e'))) {
php_import_environment_variables(PG(http_globals)[TRACK_VARS_ENV] TSRMLS_CC);
}
+ check_http_proxy(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_ENV]));
zend_hash_update(&EG(symbol_table), name, name_len + 1, &PG(http_globals)[TRACK_VARS_ENV], sizeof(zval *), NULL);
Z_ADDREF_P(PG(http_globals)[TRACK_VARS_ENV]);