mirror of
https://github.com/php/php-src.git
synced 2025-08-16 14:08:47 +02:00
Merge branch 'PHP-7.0' into PHP-7.1
* PHP-7.0: (48 commits) Update NEWs Unused label Fixed bug #72853 (stream_set_blocking doesn't work) fix test Bug #72663 - part 3 Bug #72663 - part 2 Bug #72663 - part 1 Update NEWS BLock test with memory leak fix tests Fix TSRM build Fix bug #72850 - integer overflow in uuencode Fixed bug #72849 - integer overflow in urlencode Fix bug #72848 - integer overflow in quoted_printable_encode caused heap corruption Fix bug #72838 - Integer overflow lead to heap corruption in sql_regcase Fix bug #72837 - integer overflow in bzdecompress caused heap corruption Fix bug #72836 - integer overflow in base64_decode caused heap corruption Fix for bug #72807 - do not produce strings with negative length Fix for bug #72790 and bug #72799 Fix bug #72730 - imagegammacorrect allows arbitrary write access ... Conflicts: ext/standard/var_unserializer.c
This commit is contained in:
commit
ce6ad9bdd9
38 changed files with 1249 additions and 589 deletions
|
@ -1503,21 +1503,21 @@ static void *zend_mm_realloc_heap(zend_mm_heap *heap, void *ptr, size_t size, si
|
||||||
|
|
||||||
ZEND_MM_CHECK(chunk->heap == heap, "zend_mm_heap corrupted");
|
ZEND_MM_CHECK(chunk->heap == heap, "zend_mm_heap corrupted");
|
||||||
if (info & ZEND_MM_IS_SRUN) {
|
if (info & ZEND_MM_IS_SRUN) {
|
||||||
int old_bin_num, bin_num;
|
int old_bin_num = ZEND_MM_SRUN_BIN_NUM(info);
|
||||||
|
|
||||||
old_bin_num = ZEND_MM_SRUN_BIN_NUM(info);
|
|
||||||
old_size = bin_data_size[old_bin_num];
|
old_size = bin_data_size[old_bin_num];
|
||||||
bin_num = ZEND_MM_SMALL_SIZE_TO_BIN(size);
|
if (size <= ZEND_MM_MAX_SMALL_SIZE) {
|
||||||
if (old_bin_num == bin_num) {
|
int bin_num = ZEND_MM_SMALL_SIZE_TO_BIN(size);
|
||||||
|
if (old_bin_num == bin_num) {
|
||||||
#if ZEND_DEBUG
|
#if ZEND_DEBUG
|
||||||
dbg = zend_mm_get_debug_info(heap, ptr);
|
dbg = zend_mm_get_debug_info(heap, ptr);
|
||||||
dbg->size = real_size;
|
dbg->size = real_size;
|
||||||
dbg->filename = __zend_filename;
|
dbg->filename = __zend_filename;
|
||||||
dbg->orig_filename = __zend_orig_filename;
|
dbg->orig_filename = __zend_orig_filename;
|
||||||
dbg->lineno = __zend_lineno;
|
dbg->lineno = __zend_lineno;
|
||||||
dbg->orig_lineno = __zend_orig_lineno;
|
dbg->orig_lineno = __zend_orig_lineno;
|
||||||
#endif
|
#endif
|
||||||
return ptr;
|
return ptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else /* if (info & ZEND_MM_IS_LARGE_RUN) */ {
|
} else /* if (info & ZEND_MM_IS_LARGE_RUN) */ {
|
||||||
ZEND_MM_CHECK(ZEND_MM_ALIGNED_OFFSET(page_offset, ZEND_MM_PAGE_SIZE) == 0, "zend_mm_heap corrupted");
|
ZEND_MM_CHECK(ZEND_MM_ALIGNED_OFFSET(page_offset, ZEND_MM_PAGE_SIZE) == 0, "zend_mm_heap corrupted");
|
||||||
|
|
|
@ -595,16 +595,26 @@ static PHP_FUNCTION(bzdecompress)
|
||||||
/* compression is better then 2:1, need to allocate more memory */
|
/* compression is better then 2:1, need to allocate more memory */
|
||||||
bzs.avail_out = source_len;
|
bzs.avail_out = source_len;
|
||||||
size = (bzs.total_out_hi32 * (unsigned int) -1) + bzs.total_out_lo32;
|
size = (bzs.total_out_hi32 * (unsigned int) -1) + bzs.total_out_lo32;
|
||||||
|
if (size > SIZE_MAX) {
|
||||||
|
/* no reason to continue if we're going to drop it anyway */
|
||||||
|
break;
|
||||||
|
}
|
||||||
dest = safe_erealloc(dest, 1, bzs.avail_out+1, (size_t) size );
|
dest = safe_erealloc(dest, 1, bzs.avail_out+1, (size_t) size );
|
||||||
bzs.next_out = dest + size;
|
bzs.next_out = dest + size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error == BZ_STREAM_END || error == BZ_OK) {
|
if (error == BZ_STREAM_END || error == BZ_OK) {
|
||||||
size = (bzs.total_out_hi32 * (unsigned int) -1) + bzs.total_out_lo32;
|
size = (bzs.total_out_hi32 * (unsigned int) -1) + bzs.total_out_lo32;
|
||||||
dest = safe_erealloc(dest, 1, (size_t) size, 1);
|
if (size > SIZE_MAX) {
|
||||||
dest[size] = '\0';
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Decompressed size too big, max is %zd", SIZE_MAX);
|
||||||
RETVAL_STRINGL(dest, (int) size);
|
efree(dest);
|
||||||
efree(dest);
|
RETVAL_LONG(BZ_MEM_ERROR);
|
||||||
|
} else {
|
||||||
|
dest = safe_erealloc(dest, 1, (size_t) size, 1);
|
||||||
|
dest[size] = '\0';
|
||||||
|
RETVAL_STRINGL(dest, (size_t) size);
|
||||||
|
efree(dest);
|
||||||
|
}
|
||||||
} else { /* real error */
|
} else { /* real error */
|
||||||
efree(dest);
|
efree(dest);
|
||||||
RETVAL_LONG(error);
|
RETVAL_LONG(error);
|
||||||
|
|
|
@ -3530,7 +3530,7 @@ PHP_FUNCTION(curl_reset)
|
||||||
PHP_FUNCTION(curl_escape)
|
PHP_FUNCTION(curl_escape)
|
||||||
{
|
{
|
||||||
char *str = NULL, *res = NULL;
|
char *str = NULL, *res = NULL;
|
||||||
size_t str_len = 0;
|
size_t str_len = 0;
|
||||||
zval *zid;
|
zval *zid;
|
||||||
php_curl *ch;
|
php_curl *ch;
|
||||||
|
|
||||||
|
@ -3542,6 +3542,10 @@ PHP_FUNCTION(curl_escape)
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ZEND_SIZE_T_INT_OVFL(str_len)) {
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if ((res = curl_easy_escape(ch->cp, str, str_len))) {
|
if ((res = curl_easy_escape(ch->cp, str, str_len))) {
|
||||||
RETVAL_STRING(res);
|
RETVAL_STRING(res);
|
||||||
curl_free(res);
|
curl_free(res);
|
||||||
|
@ -3569,7 +3573,7 @@ PHP_FUNCTION(curl_unescape)
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str_len > INT_MAX) {
|
if (ZEND_SIZE_T_INT_OVFL(str_len)) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3758,8 +3758,11 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse
|
||||||
fgot = php_stream_read(ImageInfo->infile, ImageInfo->Thumbnail.data, ImageInfo->Thumbnail.size);
|
fgot = php_stream_read(ImageInfo->infile, ImageInfo->Thumbnail.data, ImageInfo->Thumbnail.size);
|
||||||
if (fgot < ImageInfo->Thumbnail.size) {
|
if (fgot < ImageInfo->Thumbnail.size) {
|
||||||
EXIF_ERRLOG_THUMBEOF(ImageInfo)
|
EXIF_ERRLOG_THUMBEOF(ImageInfo)
|
||||||
|
efree(ImageInfo->Thumbnail.data);
|
||||||
|
ImageInfo->Thumbnail.data = NULL;
|
||||||
|
} else {
|
||||||
|
exif_thumbnail_build(ImageInfo);
|
||||||
}
|
}
|
||||||
exif_thumbnail_build(ImageInfo);
|
|
||||||
}
|
}
|
||||||
#ifdef EXIF_DEBUG
|
#ifdef EXIF_DEBUG
|
||||||
exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Read next IFD (THUMBNAIL) done");
|
exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Read next IFD (THUMBNAIL) done");
|
||||||
|
|
71
ext/exif/tests/bug72627.phpt
Normal file
71
ext/exif/tests/bug72627.phpt
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72627 (Memory Leakage In exif_process_IFD_in_TIFF)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
$exif = exif_read_data(__DIR__ . '/bug72627.tiff',0,0,true);
|
||||||
|
var_dump($exif);
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Warning: exif_read_data(%s): Thumbnail goes IFD boundary or end of file reached in %sbug72627.php on line %d
|
||||||
|
|
||||||
|
Warning: exif_read_data(%s): Error in TIFF: filesize(x04E2) less than start of IFD dir(x829A0004) in %sbug72627.php on line %d
|
||||||
|
|
||||||
|
Warning: exif_read_data(%s): Thumbnail goes IFD boundary or end of file reached in %sbug72627.php on line %d
|
||||||
|
array(11) {
|
||||||
|
["FileName"]=>
|
||||||
|
string(13) "bug72627.tiff"
|
||||||
|
["FileDateTime"]=>
|
||||||
|
int(%d)
|
||||||
|
["FileSize"]=>
|
||||||
|
int(1250)
|
||||||
|
["FileType"]=>
|
||||||
|
int(7)
|
||||||
|
["MimeType"]=>
|
||||||
|
string(10) "image/tiff"
|
||||||
|
["SectionsFound"]=>
|
||||||
|
string(30) "ANY_TAG, IFD0, THUMBNAIL, EXIF"
|
||||||
|
["COMPUTED"]=>
|
||||||
|
array(10) {
|
||||||
|
["html"]=>
|
||||||
|
string(24) "width="128" height="132""
|
||||||
|
["Height"]=>
|
||||||
|
int(132)
|
||||||
|
["Width"]=>
|
||||||
|
int(128)
|
||||||
|
["IsColor"]=>
|
||||||
|
int(0)
|
||||||
|
["ByteOrderMotorola"]=>
|
||||||
|
int(0)
|
||||||
|
["ApertureFNumber"]=>
|
||||||
|
string(5) "f/1.0"
|
||||||
|
["Thumbnail.FileType"]=>
|
||||||
|
int(2)
|
||||||
|
["Thumbnail.MimeType"]=>
|
||||||
|
string(10) "image/jpeg"
|
||||||
|
["Thumbnail.Height"]=>
|
||||||
|
int(132)
|
||||||
|
["Thumbnail.Width"]=>
|
||||||
|
int(128)
|
||||||
|
}
|
||||||
|
["XResolution"]=>
|
||||||
|
string(21) "1414812756/1414812756"
|
||||||
|
["THUMBNAIL"]=>
|
||||||
|
array(5) {
|
||||||
|
["ImageWidth"]=>
|
||||||
|
int(128)
|
||||||
|
["ImageLength"]=>
|
||||||
|
int(132)
|
||||||
|
["JPEGInterchangeFormat"]=>
|
||||||
|
int(1280)
|
||||||
|
["JPEGInterchangeFormatLength"]=>
|
||||||
|
int(100)
|
||||||
|
["THUMBNAIL"]=>
|
||||||
|
NULL
|
||||||
|
}
|
||||||
|
["ExposureTime"]=>
|
||||||
|
string(21) "1414812756/1414812756"
|
||||||
|
["FNumber"]=>
|
||||||
|
string(21) "1414812756/1414812756"
|
||||||
|
}
|
BIN
ext/exif/tests/bug72627.tiff
Normal file
BIN
ext/exif/tests/bug72627.tiff
Normal file
Binary file not shown.
11
ext/gd/gd.c
11
ext/gd/gd.c
|
@ -1537,11 +1537,11 @@ PHP_FUNCTION(imagetruecolortopalette)
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ncolors <= 0) {
|
if (ncolors <= 0 || ZEND_LONG_INT_OVFL(ncolors)) {
|
||||||
php_error_docref(NULL, E_WARNING, "Number of colors has to be greater than zero");
|
php_error_docref(NULL, E_WARNING, "Number of colors has to be greater than zero and no more than %d", INT_MAX);
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
gdImageTrueColorToPalette(im, dither, ncolors);
|
gdImageTrueColorToPalette(im, dither, (int)ncolors);
|
||||||
|
|
||||||
RETURN_TRUE;
|
RETURN_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -3039,6 +3039,11 @@ PHP_FUNCTION(imagegammacorrect)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( input <= 0.0 || output <= 0.0 ) {
|
||||||
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Gamma values should be positive");
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
|
if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
17
ext/gd/tests/bug72697.phpt
Normal file
17
ext/gd/tests/bug72697.phpt
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72697: select_colors write out-of-bounds
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (!function_exists("imagecreatetruecolor")) die("skip");
|
||||||
|
if (PHP_INT_MAX !== 9223372036854775807) die("skip for 64-bit long systems only");
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$img=imagecreatetruecolor(10, 10);
|
||||||
|
imagetruecolortopalette($img, false, PHP_INT_MAX / 8);
|
||||||
|
?>
|
||||||
|
DONE
|
||||||
|
--EXPECTF--
|
||||||
|
Warning: imagetruecolortopalette(): Number of colors has to be greater than zero and no more than 2147483647 in %sbug72697.php on line %d
|
||||||
|
DONE
|
15
ext/gd/tests/bug72730.phpt
Normal file
15
ext/gd/tests/bug72730.phpt
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72730: imagegammacorrect allows arbitrary write access
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (!function_exists("imagecreatetruecolor")) die("skip");
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
$img = imagecreatetruecolor(1, 1);
|
||||||
|
imagegammacorrect($img, -1, 1337);
|
||||||
|
?>
|
||||||
|
DONE
|
||||||
|
--EXPECTF--
|
||||||
|
Warning: imagegammacorrect(): Gamma values should be positive in %sbug72730.php on line %d
|
||||||
|
DONE
|
|
@ -25,4 +25,4 @@ Warning: imagetruecolortopalette() expects parameter 3 to be integer, resource g
|
||||||
|
|
||||||
Warning: imagetruecolortopalette() expects parameter 3 to be integer, array given in %s on line %d
|
Warning: imagetruecolortopalette() expects parameter 3 to be integer, array given in %s on line %d
|
||||||
|
|
||||||
Warning: imagetruecolortopalette(): Number of colors has to be greater than zero in %s on line %d
|
Warning: imagetruecolortopalette(): Number of colors has to be greater than zero and no more than %d in %s on line %d
|
||||||
|
|
|
@ -16,6 +16,6 @@ imagetruecolortopalette($image, true, -1);
|
||||||
|
|
||||||
?>
|
?>
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
Warning: imagetruecolortopalette(): Number of colors has to be greater than zero in %s on line %d
|
Warning: imagetruecolortopalette(): Number of colors has to be greater than zero and no more than %d in %s line %d
|
||||||
|
|
||||||
Warning: imagetruecolortopalette(): Number of colors has to be greater than zero in %s on line %d
|
Warning: imagetruecolortopalette(): Number of colors has to be greater than zero and no more than %d in %s line %d
|
||||||
|
|
|
@ -633,6 +633,10 @@ PHP_FUNCTION(mcrypt_generic)
|
||||||
RETURN_FALSE
|
RETURN_FALSE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data_len > INT_MAX) {
|
||||||
|
php_error_docref(NULL, E_WARNING, "Data size too large, %d maximum", INT_MAX);
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
/* Check blocksize */
|
/* Check blocksize */
|
||||||
if (mcrypt_enc_is_block_mode(pm->td) == 1) { /* It's a block algorithm */
|
if (mcrypt_enc_is_block_mode(pm->td) == 1) { /* It's a block algorithm */
|
||||||
block_size = mcrypt_enc_get_block_size(pm->td);
|
block_size = mcrypt_enc_get_block_size(pm->td);
|
||||||
|
@ -645,10 +649,6 @@ PHP_FUNCTION(mcrypt_generic)
|
||||||
memset(ZSTR_VAL(data_str), 0, data_size);
|
memset(ZSTR_VAL(data_str), 0, data_size);
|
||||||
memcpy(ZSTR_VAL(data_str), data, data_len);
|
memcpy(ZSTR_VAL(data_str), data, data_len);
|
||||||
} else { /* It's not a block algorithm */
|
} else { /* It's not a block algorithm */
|
||||||
if (data_len > INT_MAX) {
|
|
||||||
php_error_docref(NULL, E_WARNING, "Data size too large, %d maximum", INT_MAX);
|
|
||||||
RETURN_FALSE;
|
|
||||||
}
|
|
||||||
data_size = (int)data_len;
|
data_size = (int)data_len;
|
||||||
data_str = zend_string_alloc(data_size, 0);
|
data_str = zend_string_alloc(data_size, 0);
|
||||||
memset(ZSTR_VAL(data_str), 0, data_size);
|
memset(ZSTR_VAL(data_str), 0, data_size);
|
||||||
|
@ -688,6 +688,10 @@ PHP_FUNCTION(mdecrypt_generic)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check blocksize */
|
/* Check blocksize */
|
||||||
|
if (data_len > INT_MAX) {
|
||||||
|
php_error_docref(NULL, E_WARNING, "Data size too large, %d maximum", INT_MAX);
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
if (mcrypt_enc_is_block_mode(pm->td) == 1) { /* It's a block algorithm */
|
if (mcrypt_enc_is_block_mode(pm->td) == 1) { /* It's a block algorithm */
|
||||||
block_size = mcrypt_enc_get_block_size(pm->td);
|
block_size = mcrypt_enc_get_block_size(pm->td);
|
||||||
data_size = ((((int)data_len - 1) / block_size) + 1) * block_size;
|
data_size = ((((int)data_len - 1) / block_size) + 1) * block_size;
|
||||||
|
@ -699,10 +703,6 @@ PHP_FUNCTION(mdecrypt_generic)
|
||||||
memset(data_s, 0, data_size);
|
memset(data_s, 0, data_size);
|
||||||
memcpy(data_s, data, data_len);
|
memcpy(data_s, data, data_len);
|
||||||
} else { /* It's not a block algorithm */
|
} else { /* It's not a block algorithm */
|
||||||
if (data_len > INT_MAX) {
|
|
||||||
php_error_docref(NULL, E_WARNING, "Data size too large, %d maximum", INT_MAX);
|
|
||||||
RETURN_FALSE;
|
|
||||||
}
|
|
||||||
data_size = (int)data_len;
|
data_size = (int)data_len;
|
||||||
data_s = emalloc(data_size + 1);
|
data_s = emalloc(data_size + 1);
|
||||||
memset(data_s, 0, data_size);
|
memset(data_s, 0, data_size);
|
||||||
|
|
|
@ -765,12 +765,19 @@ PS_SERIALIZER_DECODE_FUNC(php_serialize) /* {{{ */
|
||||||
const char *endptr = val + vallen;
|
const char *endptr = val + vallen;
|
||||||
zval session_vars;
|
zval session_vars;
|
||||||
php_unserialize_data_t var_hash;
|
php_unserialize_data_t var_hash;
|
||||||
|
int result;
|
||||||
zend_string *var_name = zend_string_init("_SESSION", sizeof("_SESSION") - 1, 0);
|
zend_string *var_name = zend_string_init("_SESSION", sizeof("_SESSION") - 1, 0);
|
||||||
|
|
||||||
ZVAL_NULL(&session_vars);
|
ZVAL_NULL(&session_vars);
|
||||||
PHP_VAR_UNSERIALIZE_INIT(var_hash);
|
PHP_VAR_UNSERIALIZE_INIT(var_hash);
|
||||||
php_var_unserialize(&session_vars, (const unsigned char **)&val, (const unsigned char *)endptr, &var_hash);
|
result = php_var_unserialize(
|
||||||
|
&session_vars, (const unsigned char **)&val, (const unsigned char *)endptr, &var_hash);
|
||||||
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
|
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
|
||||||
|
if (!result) {
|
||||||
|
zval_ptr_dtor(&session_vars);
|
||||||
|
ZVAL_NULL(&session_vars);
|
||||||
|
}
|
||||||
|
|
||||||
if (!Z_ISUNDEF(PS(http_session_vars))) {
|
if (!Z_ISUNDEF(PS(http_session_vars))) {
|
||||||
zval_ptr_dtor(&PS(http_session_vars));
|
zval_ptr_dtor(&PS(http_session_vars));
|
||||||
}
|
}
|
||||||
|
@ -823,11 +830,13 @@ PS_SERIALIZER_DECODE_FUNC(php_binary) /* {{{ */
|
||||||
int namelen;
|
int namelen;
|
||||||
zend_string *name;
|
zend_string *name;
|
||||||
php_unserialize_data_t var_hash;
|
php_unserialize_data_t var_hash;
|
||||||
|
int skip = 0;
|
||||||
|
|
||||||
PHP_VAR_UNSERIALIZE_INIT(var_hash);
|
PHP_VAR_UNSERIALIZE_INIT(var_hash);
|
||||||
|
|
||||||
for (p = val; p < endptr; ) {
|
for (p = val; p < endptr; ) {
|
||||||
zval *tmp;
|
zval *tmp;
|
||||||
|
skip = 0;
|
||||||
namelen = ((unsigned char)(*p)) & (~PS_BIN_UNDEF);
|
namelen = ((unsigned char)(*p)) & (~PS_BIN_UNDEF);
|
||||||
|
|
||||||
if (namelen < 0 || namelen > PS_BIN_MAX || (p + namelen) >= endptr) {
|
if (namelen < 0 || namelen > PS_BIN_MAX || (p + namelen) >= endptr) {
|
||||||
|
@ -844,8 +853,7 @@ PS_SERIALIZER_DECODE_FUNC(php_binary) /* {{{ */
|
||||||
if ((tmp = zend_hash_find(&EG(symbol_table), name))) {
|
if ((tmp = zend_hash_find(&EG(symbol_table), name))) {
|
||||||
if ((Z_TYPE_P(tmp) == IS_ARRAY &&
|
if ((Z_TYPE_P(tmp) == IS_ARRAY &&
|
||||||
Z_ARRVAL_P(tmp) == &EG(symbol_table)) || tmp == &PS(http_session_vars)) {
|
Z_ARRVAL_P(tmp) == &EG(symbol_table)) || tmp == &PS(http_session_vars)) {
|
||||||
zend_string_release(name);
|
skip = 1;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -854,7 +862,9 @@ PS_SERIALIZER_DECODE_FUNC(php_binary) /* {{{ */
|
||||||
current = var_tmp_var(&var_hash);
|
current = var_tmp_var(&var_hash);
|
||||||
if (php_var_unserialize(current, (const unsigned char **) &p, (const unsigned char *) endptr, &var_hash)) {
|
if (php_var_unserialize(current, (const unsigned char **) &p, (const unsigned char *) endptr, &var_hash)) {
|
||||||
ZVAL_PTR(&rv, current);
|
ZVAL_PTR(&rv, current);
|
||||||
php_set_session_var(name, &rv, &var_hash );
|
if (!skip) {
|
||||||
|
php_set_session_var(name, &rv, &var_hash);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
zend_string_release(name);
|
zend_string_release(name);
|
||||||
php_session_normalize_vars();
|
php_session_normalize_vars();
|
||||||
|
@ -916,6 +926,7 @@ PS_SERIALIZER_DECODE_FUNC(php) /* {{{ */
|
||||||
zend_string *name;
|
zend_string *name;
|
||||||
int has_value, retval = SUCCESS;
|
int has_value, retval = SUCCESS;
|
||||||
php_unserialize_data_t var_hash;
|
php_unserialize_data_t var_hash;
|
||||||
|
int skip = 0;
|
||||||
|
|
||||||
PHP_VAR_UNSERIALIZE_INIT(var_hash);
|
PHP_VAR_UNSERIALIZE_INIT(var_hash);
|
||||||
|
|
||||||
|
@ -924,6 +935,7 @@ PS_SERIALIZER_DECODE_FUNC(php) /* {{{ */
|
||||||
while (p < endptr) {
|
while (p < endptr) {
|
||||||
zval *tmp;
|
zval *tmp;
|
||||||
q = p;
|
q = p;
|
||||||
|
skip = 0;
|
||||||
while (*q != PS_DELIMITER) {
|
while (*q != PS_DELIMITER) {
|
||||||
if (++q >= endptr) goto break_outer_loop;
|
if (++q >= endptr) goto break_outer_loop;
|
||||||
}
|
}
|
||||||
|
@ -941,7 +953,7 @@ PS_SERIALIZER_DECODE_FUNC(php) /* {{{ */
|
||||||
if ((tmp = zend_hash_find(&EG(symbol_table), name))) {
|
if ((tmp = zend_hash_find(&EG(symbol_table), name))) {
|
||||||
if ((Z_TYPE_P(tmp) == IS_ARRAY &&
|
if ((Z_TYPE_P(tmp) == IS_ARRAY &&
|
||||||
Z_ARRVAL_P(tmp) == &EG(symbol_table)) || tmp == &PS(http_session_vars)) {
|
Z_ARRVAL_P(tmp) == &EG(symbol_table)) || tmp == &PS(http_session_vars)) {
|
||||||
goto skip;
|
skip = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -950,16 +962,19 @@ PS_SERIALIZER_DECODE_FUNC(php) /* {{{ */
|
||||||
current = var_tmp_var(&var_hash);
|
current = var_tmp_var(&var_hash);
|
||||||
if (php_var_unserialize(current, (const unsigned char **)&q, (const unsigned char *)endptr, &var_hash)) {
|
if (php_var_unserialize(current, (const unsigned char **)&q, (const unsigned char *)endptr, &var_hash)) {
|
||||||
ZVAL_PTR(&rv, current);
|
ZVAL_PTR(&rv, current);
|
||||||
php_set_session_var(name, &rv, &var_hash);
|
if (!skip) {
|
||||||
|
php_set_session_var(name, &rv, &var_hash);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
zend_string_release(name);
|
zend_string_release(name);
|
||||||
retval = FAILURE;
|
retval = FAILURE;
|
||||||
goto break_outer_loop;
|
goto break_outer_loop;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PS_ADD_VARL(name);
|
if(!skip) {
|
||||||
|
PS_ADD_VARL(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
skip:
|
|
||||||
zend_string_release(name);
|
zend_string_release(name);
|
||||||
|
|
||||||
p = q;
|
p = q;
|
||||||
|
|
17
ext/session/tests/bug72681.phpt
Normal file
17
ext/session/tests/bug72681.phpt
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72681: PHP Session Data Injection Vulnerability
|
||||||
|
--SKIPIF--
|
||||||
|
<?php include('skipif.inc'); ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
ini_set('session.serialize_handler', 'php');
|
||||||
|
session_start();
|
||||||
|
$GLOBALS['ryat'] = $GLOBALS;
|
||||||
|
$_SESSION['ryat'] = 'ryat|O:8:"stdClass":0:{}';
|
||||||
|
session_write_close();
|
||||||
|
session_start();
|
||||||
|
var_dump($_SESSION);
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
array(0) {
|
||||||
|
}
|
|
@ -1008,7 +1008,7 @@ static int php_snmp_parse_oid(zval *object, int st, struct objid_query *objid_qu
|
||||||
php_error_docref(NULL, E_WARNING, "Got empty OID array");
|
php_error_docref(NULL, E_WARNING, "Got empty OID array");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
objid_query->vars = (snmpobjarg *)emalloc(sizeof(snmpobjarg) * zend_hash_num_elements(Z_ARRVAL_P(oid)));
|
objid_query->vars = (snmpobjarg *)safe_emalloc(sizeof(snmpobjarg), zend_hash_num_elements(Z_ARRVAL_P(oid)), 0);
|
||||||
if (objid_query->vars == NULL) {
|
if (objid_query->vars == NULL) {
|
||||||
php_error_docref(NULL, E_WARNING, "emalloc() failed while parsing oid array: %s", strerror(errno));
|
php_error_docref(NULL, E_WARNING, "emalloc() failed while parsing oid array: %s", strerror(errno));
|
||||||
efree(objid_query->vars);
|
efree(objid_query->vars);
|
||||||
|
|
|
@ -59,7 +59,7 @@ PHPAPI zend_string *php_base64_encode(const unsigned char *str, size_t length) /
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
zend_string *result;
|
zend_string *result;
|
||||||
|
|
||||||
result = zend_string_alloc(((length + 2) / 3) * 4 * sizeof(char), 0);
|
result = zend_string_safe_alloc(((length + 2) / 3), 4 * sizeof(char), 0, 0);
|
||||||
p = (unsigned char *)ZSTR_VAL(result);
|
p = (unsigned char *)ZSTR_VAL(result);
|
||||||
|
|
||||||
while (length > 2) { /* keep going until we have less than 24 bits */
|
while (length > 2) { /* keep going until we have less than 24 bits */
|
||||||
|
|
|
@ -188,7 +188,8 @@ static php_stream *php_ftp_fopen_connect(php_stream_wrapper *wrapper, const char
|
||||||
/* get the response */
|
/* get the response */
|
||||||
result = GET_FTP_RESULT(stream);
|
result = GET_FTP_RESULT(stream);
|
||||||
if (result != 334) {
|
if (result != 334) {
|
||||||
use_ssl = 0;
|
php_stream_wrapper_log_error(wrapper, options, "Server doesn't support FTPS.");
|
||||||
|
goto connect_errexit;
|
||||||
} else {
|
} else {
|
||||||
/* we must reuse the old SSL session id */
|
/* we must reuse the old SSL session id */
|
||||||
/* if we talk to an old ftpd-ssl */
|
/* if we talk to an old ftpd-ssl */
|
||||||
|
|
|
@ -52,19 +52,22 @@
|
||||||
#define SMART_STRING_DO_REALLOC(d, what) \
|
#define SMART_STRING_DO_REALLOC(d, what) \
|
||||||
(d)->c = SMART_STRING_REALLOC((d)->c, (d)->a + 1, (what))
|
(d)->c = SMART_STRING_REALLOC((d)->c, (d)->a + 1, (what))
|
||||||
|
|
||||||
#define smart_string_alloc4(d, n, what, newlen) do { \
|
#define smart_string_alloc4(d, n, what, newlen) do { \
|
||||||
if (!(d)->c) { \
|
if (!(d)->c) { \
|
||||||
(d)->len = 0; \
|
(d)->len = 0; \
|
||||||
newlen = (n); \
|
newlen = (n); \
|
||||||
(d)->a = newlen < SMART_STRING_START_SIZE \
|
(d)->a = newlen < SMART_STRING_START_SIZE \
|
||||||
? SMART_STRING_START_SIZE \
|
? SMART_STRING_START_SIZE \
|
||||||
: newlen + SMART_STRING_PREALLOC; \
|
: newlen + SMART_STRING_PREALLOC; \
|
||||||
SMART_STRING_DO_REALLOC(d, what); \
|
SMART_STRING_DO_REALLOC(d, what); \
|
||||||
} else { \
|
} else { \
|
||||||
|
if(UNEXPECTED(n > SIZE_MAX - (d)->len)) { \
|
||||||
|
zend_error(E_ERROR, "String size overflow"); \
|
||||||
|
} \
|
||||||
newlen = (d)->len + (n); \
|
newlen = (d)->len + (n); \
|
||||||
if (newlen >= (d)->a) { \
|
if (newlen >= (d)->a) { \
|
||||||
(d)->a = newlen + SMART_STRING_PREALLOC; \
|
(d)->a = newlen + SMART_STRING_PREALLOC; \
|
||||||
SMART_STRING_DO_REALLOC(d, what); \
|
SMART_STRING_DO_REALLOC(d, what); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
|
@ -275,7 +275,7 @@ PHP_FUNCTION(quoted_printable_encode)
|
||||||
RETURN_EMPTY_STRING();
|
RETURN_EMPTY_STRING();
|
||||||
}
|
}
|
||||||
|
|
||||||
new_str = php_quot_print_encode((unsigned char *)ZSTR_VAL(str), (size_t)ZSTR_LEN(str));
|
new_str = php_quot_print_encode((unsigned char *)ZSTR_VAL(str), ZSTR_LEN(str));
|
||||||
RETURN_STR(new_str);
|
RETURN_STR(new_str);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
56
ext/standard/tests/serialize/bug72663.phpt
Normal file
56
ext/standard/tests/serialize/bug72663.phpt
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72663 (1): Don't call __destruct if __wakeup not called or fails
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Test1 {
|
||||||
|
public function __wakeup() {
|
||||||
|
echo "Wakeup\n";
|
||||||
|
}
|
||||||
|
public function __destruct() {
|
||||||
|
echo "Dtor\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Test2 {
|
||||||
|
public function __wakeup() {
|
||||||
|
throw new Exception('Unserialization forbidden');
|
||||||
|
}
|
||||||
|
public function __destruct() {
|
||||||
|
echo "Dtor\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unserialize object with error in properties
|
||||||
|
$s = 'O:5:"Test1":1:{s:10:"";}';
|
||||||
|
var_dump(unserialize($s));
|
||||||
|
|
||||||
|
// Variation: Object is turned into a reference
|
||||||
|
$s = 'O:5:"Test1":2:{i:0;R:1;s:10:"";}';
|
||||||
|
var_dump(unserialize($s));
|
||||||
|
|
||||||
|
// Unserialize object with throwing __wakeup
|
||||||
|
$s = 'O:5:"Test2":0:{}';
|
||||||
|
try {
|
||||||
|
var_dump(unserialize($s));
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo "Caught\n";
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Variation: Object is turned into a reference
|
||||||
|
$s = 'O:5:"Test2":1:{i:0;R:1;}';
|
||||||
|
try {
|
||||||
|
var_dump(unserialize($s));
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo "Caught\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Notice: unserialize(): Error at offset 17 of 24 bytes in %s on line %d
|
||||||
|
bool(false)
|
||||||
|
|
||||||
|
Notice: unserialize(): Error at offset 25 of 32 bytes in %s on line %d
|
||||||
|
bool(false)
|
||||||
|
Caught
|
||||||
|
Caught
|
27
ext/standard/tests/serialize/bug72663_2.phpt
Normal file
27
ext/standard/tests/serialize/bug72663_2.phpt
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72663 (2): Don't allow references into failed unserialize
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class obj implements Serializable {
|
||||||
|
public $data;
|
||||||
|
function serialize() {
|
||||||
|
return serialize($this->data);
|
||||||
|
}
|
||||||
|
function unserialize($data) {
|
||||||
|
$this->data = unserialize($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$inner = 'a:1:{i:0;O:9:"Exception":2:{s:7:"'."\0".'*'."\0".'file";R:4;}';
|
||||||
|
$exploit = 'a:2:{i:0;C:3:"obj":'.strlen($inner).':{'.$inner.'}i:1;R:4;}';
|
||||||
|
var_dump(unserialize($exploit));
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Notice: unserialize(): Unexpected end of serialized data in %s on line %d
|
||||||
|
|
||||||
|
Notice: unserialize(): Error at offset 46 of 47 bytes in %s on line %d
|
||||||
|
|
||||||
|
Notice: unserialize(): Error at offset 79 of 80 bytes in %s on line %d
|
||||||
|
bool(false)
|
17
ext/standard/tests/serialize/bug72663_3.phpt
Normal file
17
ext/standard/tests/serialize/bug72663_3.phpt
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72663 (3): If unserialization fails, don't initialize the session with the result
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if (!extension_loaded('session')) die('skip Session extension required'); ?>
|
||||||
|
--INI--
|
||||||
|
session.serialize_handler=php_serialize
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
$sess = 'O:9:"Exception":2:{s:7:"'."\0".'*'."\0".'file";R:1;}';
|
||||||
|
session_decode($sess);
|
||||||
|
var_dump($_SESSION);
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Notice: session_decode(): Unexpected end of serialized data in %s on line %d
|
||||||
|
array(0) {
|
||||||
|
}
|
59
ext/standard/tests/streams/bug72853.phpt
Normal file
59
ext/standard/tests/streams/bug72853.phpt
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72853 (stream_set_blocking doesn't work)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if(substr(PHP_OS, 0, 3) == 'WIN' ) {
|
||||||
|
die('skip not for windows');
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$descs = array(
|
||||||
|
0 => array('pipe', 'r'), // stdin
|
||||||
|
1 => array('pipe', 'w'), // stdout
|
||||||
|
);
|
||||||
|
|
||||||
|
$p = proc_open("ls", $descs, $pipes, '.', NULL, NULL);
|
||||||
|
|
||||||
|
stream_set_blocking($pipes[1], false);
|
||||||
|
var_dump(stream_get_meta_data($pipes[1]));
|
||||||
|
stream_set_blocking($pipes[1], true);
|
||||||
|
while ($outs = fgets($pipes[1], 1024)) {
|
||||||
|
}
|
||||||
|
var_dump(stream_get_meta_data($pipes[1]));
|
||||||
|
proc_close($p);
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
array(7) {
|
||||||
|
["timed_out"]=>
|
||||||
|
bool(false)
|
||||||
|
["blocked"]=>
|
||||||
|
bool(false)
|
||||||
|
["eof"]=>
|
||||||
|
bool(false)
|
||||||
|
["stream_type"]=>
|
||||||
|
string(5) "STDIO"
|
||||||
|
["mode"]=>
|
||||||
|
string(1) "r"
|
||||||
|
["unread_bytes"]=>
|
||||||
|
int(0)
|
||||||
|
["seekable"]=>
|
||||||
|
bool(false)
|
||||||
|
}
|
||||||
|
array(7) {
|
||||||
|
["timed_out"]=>
|
||||||
|
bool(false)
|
||||||
|
["blocked"]=>
|
||||||
|
bool(true)
|
||||||
|
["eof"]=>
|
||||||
|
bool(true)
|
||||||
|
["stream_type"]=>
|
||||||
|
string(5) "STDIO"
|
||||||
|
["mode"]=>
|
||||||
|
string(1) "r"
|
||||||
|
["unread_bytes"]=>
|
||||||
|
int(0)
|
||||||
|
["seekable"]=>
|
||||||
|
bool(false)
|
||||||
|
}
|
65
ext/standard/tests/strings/bug70436.phpt
Normal file
65
ext/standard/tests/strings/bug70436.phpt
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #70436: Use After Free Vulnerability in unserialize()
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class obj implements Serializable
|
||||||
|
{
|
||||||
|
var $data;
|
||||||
|
|
||||||
|
function serialize()
|
||||||
|
{
|
||||||
|
return serialize($this->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function unserialize($data)
|
||||||
|
{
|
||||||
|
$this->data = unserialize($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$fakezval = ptr2str(1122334455);
|
||||||
|
$fakezval .= ptr2str(0);
|
||||||
|
$fakezval .= "\x00\x00\x00\x00";
|
||||||
|
$fakezval .= "\x01";
|
||||||
|
$fakezval .= "\x00";
|
||||||
|
$fakezval .= "\x00\x00";
|
||||||
|
|
||||||
|
$inner = 'C:3:"obj":3:{ryat';
|
||||||
|
$exploit = 'a:4:{i:0;i:1;i:1;C:3:"obj":'.strlen($inner).':{'.$inner.'}i:2;s:'.strlen($fakezval).':"'.$fakezval.'";i:3;R:5;}';
|
||||||
|
|
||||||
|
$data = unserialize($exploit);
|
||||||
|
|
||||||
|
var_dump($data);
|
||||||
|
|
||||||
|
function ptr2str($ptr)
|
||||||
|
{
|
||||||
|
$out = '';
|
||||||
|
|
||||||
|
for ($i = 0; $i < 8; $i++) {
|
||||||
|
$out .= chr($ptr & 0xff);
|
||||||
|
$ptr >>= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
DONE
|
||||||
|
--EXPECTF--
|
||||||
|
Notice: unserialize(): Error at offset 0 of 3 bytes in %sbug70436.php on line %d
|
||||||
|
|
||||||
|
Notice: unserialize(): Error at offset 17 of 17 bytes in %sbug70436.php on line %d
|
||||||
|
array(4) {
|
||||||
|
[0]=>
|
||||||
|
int(1)
|
||||||
|
[1]=>
|
||||||
|
object(obj)#%d (1) {
|
||||||
|
["data"]=>
|
||||||
|
bool(false)
|
||||||
|
}
|
||||||
|
[2]=>
|
||||||
|
string(24) "%s"
|
||||||
|
[3]=>
|
||||||
|
bool(false)
|
||||||
|
}
|
||||||
|
DONE
|
26
ext/standard/tests/strings/bug72663.phpt
Normal file
26
ext/standard/tests/strings/bug72663.phpt
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72663: Create an Unexpected Object and Don't Invoke __wakeup() in Deserialization
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
class obj implements Serializable {
|
||||||
|
var $data;
|
||||||
|
function serialize() {
|
||||||
|
return serialize($this->data);
|
||||||
|
}
|
||||||
|
function unserialize($data) {
|
||||||
|
$this->data = unserialize($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$inner = 'a:1:{i:0;O:9:"Exception":2:{s:7:"'."\0".'*'."\0".'file";R:4;}';
|
||||||
|
$exploit = 'a:2:{i:0;C:3:"obj":'.strlen($inner).':{'.$inner.'}i:1;R:4;}';
|
||||||
|
|
||||||
|
$data = unserialize($exploit);
|
||||||
|
echo $data[1];
|
||||||
|
?>
|
||||||
|
DONE
|
||||||
|
--EXPECTF--
|
||||||
|
Notice: unserialize(): Unexpected end of serialized data in %sbug72663.php on line %d
|
||||||
|
|
||||||
|
Notice: unserialize(): Error at offset 46 of 47 bytes in %sbug72663.php on line %d
|
||||||
|
DONE
|
17
ext/standard/tests/strings/bug72663_2.phpt
Normal file
17
ext/standard/tests/strings/bug72663_2.phpt
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72663: Create an Unexpected Object and Don't Invoke __wakeup() in Deserialization
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
ini_set('session.serialize_handler', 'php_serialize');
|
||||||
|
session_start();
|
||||||
|
$sess = 'O:9:"Exception":2:{s:7:"'."\0".'*'."\0".'file";R:1;}';
|
||||||
|
session_decode($sess);
|
||||||
|
var_dump($_SESSION);
|
||||||
|
?>
|
||||||
|
DONE
|
||||||
|
--EXPECTF--
|
||||||
|
Notice: session_decode(): Unexpected end of serialized data in %sbug72663_2.php on line %d
|
||||||
|
array(0) {
|
||||||
|
}
|
||||||
|
DONE
|
20
ext/standard/tests/strings/bug72663_3.phpt
Normal file
20
ext/standard/tests/strings/bug72663_3.phpt
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72663: Create an Unexpected Object and Don't Invoke __wakeup() in Deserialization
|
||||||
|
--XFAIL--
|
||||||
|
Memory leak, TBF later.
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
class obj {
|
||||||
|
var $ryat;
|
||||||
|
function __wakeup() {
|
||||||
|
$this->ryat = str_repeat('A', 0x112);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$poc = 'O:8:"stdClass":1:{i:0;O:3:"obj":1:{s:4:"ryat";R:1;';
|
||||||
|
unserialize($poc);
|
||||||
|
?>
|
||||||
|
DONE
|
||||||
|
--EXPECTF--
|
||||||
|
Notice: unserialize(): Error at offset 51 of 50 bytes in %sbug72663_3.php on line %d
|
||||||
|
DONE
|
|
@ -71,8 +71,10 @@ PHPAPI zend_string *php_uuencode(char *src, size_t src_len) /* {{{ */
|
||||||
char *p, *s, *e, *ee;
|
char *p, *s, *e, *ee;
|
||||||
zend_string *dest;
|
zend_string *dest;
|
||||||
|
|
||||||
/* encoded length is ~ 38% greater than the original */
|
/* encoded length is ~ 38% greater than the original
|
||||||
dest = zend_string_alloc((size_t)ceil(src_len * 1.38) + 46, 0);
|
Use 1.5 for easier calculation.
|
||||||
|
*/
|
||||||
|
dest = zend_string_safe_alloc(src_len/2, 3, 46, 0);
|
||||||
p = ZSTR_VAL(dest);
|
p = ZSTR_VAL(dest);
|
||||||
s = src;
|
s = src;
|
||||||
e = src + src_len;
|
e = src + src_len;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -340,6 +340,8 @@ static inline size_t parse_uiv(const unsigned char *p)
|
||||||
#define UNSERIALIZE_PARAMETER zval *rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash, HashTable *classes
|
#define UNSERIALIZE_PARAMETER zval *rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash, HashTable *classes
|
||||||
#define UNSERIALIZE_PASSTHRU rval, p, max, var_hash, classes
|
#define UNSERIALIZE_PASSTHRU rval, p, max, var_hash, classes
|
||||||
|
|
||||||
|
static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER);
|
||||||
|
|
||||||
static zend_always_inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, zend_long elements, int objprops)
|
static zend_always_inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, zend_long elements, int objprops)
|
||||||
{
|
{
|
||||||
while (elements-- > 0) {
|
while (elements-- > 0) {
|
||||||
|
@ -348,7 +350,7 @@ static zend_always_inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTab
|
||||||
|
|
||||||
ZVAL_UNDEF(&key);
|
ZVAL_UNDEF(&key);
|
||||||
|
|
||||||
if (!php_var_unserialize_ex(&key, p, max, NULL, classes)) {
|
if (!php_var_unserialize_internal(&key, p, max, NULL, classes)) {
|
||||||
zval_dtor(&key);
|
zval_dtor(&key);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -404,7 +406,7 @@ string_key:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!php_var_unserialize_ex(data, p, max, var_hash, classes)) {
|
if (!php_var_unserialize_internal(data, p, max, var_hash, classes)) {
|
||||||
zval_dtor(&key);
|
zval_dtor(&key);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -494,23 +496,32 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, zend_long elements)
|
||||||
zval retval;
|
zval retval;
|
||||||
zval fname;
|
zval fname;
|
||||||
HashTable *ht;
|
HashTable *ht;
|
||||||
|
zend_bool has_wakeup;
|
||||||
|
|
||||||
if (Z_TYPE_P(rval) != IS_OBJECT) {
|
if (Z_TYPE_P(rval) != IS_OBJECT) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
has_wakeup = Z_OBJCE_P(rval) != PHP_IC_ENTRY
|
||||||
|
&& zend_hash_str_exists(&Z_OBJCE_P(rval)->function_table, "__wakeup", sizeof("__wakeup")-1);
|
||||||
|
|
||||||
ht = Z_OBJPROP_P(rval);
|
ht = Z_OBJPROP_P(rval);
|
||||||
zend_hash_extend(ht, zend_hash_num_elements(ht) + elements, (ht->u.flags & HASH_FLAG_PACKED));
|
zend_hash_extend(ht, zend_hash_num_elements(ht) + elements, (ht->u.flags & HASH_FLAG_PACKED));
|
||||||
if (!process_nested_data(UNSERIALIZE_PASSTHRU, ht, elements, 1)) {
|
if (!process_nested_data(UNSERIALIZE_PASSTHRU, ht, elements, 1)) {
|
||||||
|
if (has_wakeup) {
|
||||||
|
ZVAL_DEREF(rval);
|
||||||
|
GC_FLAGS(Z_OBJ_P(rval)) |= IS_OBJ_DESTRUCTOR_CALLED;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZVAL_DEREF(rval);
|
ZVAL_DEREF(rval);
|
||||||
if (Z_OBJCE_P(rval) != PHP_IC_ENTRY &&
|
if (has_wakeup) {
|
||||||
zend_hash_str_exists(&Z_OBJCE_P(rval)->function_table, "__wakeup", sizeof("__wakeup")-1)) {
|
|
||||||
ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1);
|
ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1);
|
||||||
BG(serialize_lock)++;
|
BG(serialize_lock)++;
|
||||||
call_user_function_ex(CG(function_table), rval, &fname, &retval, 0, 0, 1, NULL);
|
if (call_user_function_ex(CG(function_table), rval, &fname, &retval, 0, 0, 1, NULL) == FAILURE || Z_ISUNDEF(retval)) {
|
||||||
|
GC_FLAGS(Z_OBJ_P(rval)) |= IS_OBJ_DESTRUCTOR_CALLED;
|
||||||
|
}
|
||||||
BG(serialize_lock)--;
|
BG(serialize_lock)--;
|
||||||
zval_dtor(&fname);
|
zval_dtor(&fname);
|
||||||
zval_dtor(&retval);
|
zval_dtor(&retval);
|
||||||
|
@ -521,7 +532,6 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, zend_long elements)
|
||||||
}
|
}
|
||||||
|
|
||||||
return finish_nested_data(UNSERIALIZE_PASSTHRU);
|
return finish_nested_data(UNSERIALIZE_PASSTHRU);
|
||||||
|
|
||||||
}
|
}
|
||||||
#ifdef PHP_WIN32
|
#ifdef PHP_WIN32
|
||||||
# pragma optimize("", on)
|
# pragma optimize("", on)
|
||||||
|
@ -533,8 +543,34 @@ PHPAPI int php_var_unserialize(zval *rval, const unsigned char **p, const unsign
|
||||||
return php_var_unserialize_ex(UNSERIALIZE_PASSTHRU);
|
return php_var_unserialize_ex(UNSERIALIZE_PASSTHRU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PHPAPI int php_var_unserialize_ex(UNSERIALIZE_PARAMETER)
|
PHPAPI int php_var_unserialize_ex(UNSERIALIZE_PARAMETER)
|
||||||
|
{
|
||||||
|
var_entries *orig_var_entries = (*var_hash)->last;
|
||||||
|
zend_long orig_used_slots = orig_var_entries ? orig_var_entries->used_slots : 0;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = php_var_unserialize_internal(UNSERIALIZE_PASSTHRU);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
/* If the unserialization failed, mark all elements that have been added to var_hash
|
||||||
|
* as NULL. This will forbid their use by other unserialize() calls in the same
|
||||||
|
* unserialization context. */
|
||||||
|
var_entries *e = orig_var_entries;
|
||||||
|
zend_long s = orig_used_slots;
|
||||||
|
while (e) {
|
||||||
|
for (; s < e->used_slots; s++) {
|
||||||
|
e->data[s] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
e = e->next;
|
||||||
|
s = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
|
||||||
{
|
{
|
||||||
const unsigned char *cursor, *limit, *marker, *start;
|
const unsigned char *cursor, *limit, *marker, *start;
|
||||||
zval *rval_ref;
|
zval *rval_ref;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
--TEST--
|
--TEST--
|
||||||
Bug #72142: WDDX Packet Injection Vulnerability in wddx_serialize_value()
|
Bug #72142: WDDX Packet Injection Vulnerability in wddx_serialize_value()
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if (!extension_loaded("wddx")) print "skip"; ?>
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
34
ext/wddx/tests/bug72749.phpt
Normal file
34
ext/wddx/tests/bug72749.phpt
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72749: wddx_deserialize allows illegal memory access
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (!extension_loaded('wddx')) {
|
||||||
|
die('skip. wddx not available');
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
$xml = <<<XML
|
||||||
|
<?xml version='1.0'?>
|
||||||
|
<!DOCTYPE wddxPacket SYSTEM 'wddx_0100.dtd'>
|
||||||
|
<wddxPacket version='1.0'>
|
||||||
|
<header/>
|
||||||
|
<data>
|
||||||
|
<struct>
|
||||||
|
<var name='aDateTime3'>
|
||||||
|
<dateTime>2\r2004-09-10T05:52:49+00</dateTime>
|
||||||
|
</var>
|
||||||
|
</struct>
|
||||||
|
</data>
|
||||||
|
</wddxPacket>
|
||||||
|
XML;
|
||||||
|
|
||||||
|
$array = wddx_deserialize($xml);
|
||||||
|
var_dump($array);
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
array(1) {
|
||||||
|
["aDateTime3"]=>
|
||||||
|
string(24) "2
|
||||||
|
2004-09-10T05:52:49+00"
|
||||||
|
}
|
34
ext/wddx/tests/bug72750.phpt
Normal file
34
ext/wddx/tests/bug72750.phpt
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72750: wddx_deserialize null dereference
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (!extension_loaded('wddx')) {
|
||||||
|
die('skip. wddx not available');
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$xml = <<< XML
|
||||||
|
<?xml version='1.0'?>
|
||||||
|
<!DOCTYPE wddxPacket SYSTEM 'wddx_0100.dtd'>
|
||||||
|
<wddxPacket version='1.0'>
|
||||||
|
<header/>
|
||||||
|
<data>
|
||||||
|
<struct>
|
||||||
|
<var name='aBinary'>
|
||||||
|
<binary length='11'>\\tYmluYXJRhdGE=</binary>
|
||||||
|
</var>
|
||||||
|
</struct>
|
||||||
|
</data>
|
||||||
|
</wddxPacket>
|
||||||
|
XML;
|
||||||
|
|
||||||
|
$array = wddx_deserialize($xml);
|
||||||
|
var_dump($array);
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
array(1) {
|
||||||
|
["aBinary"]=>
|
||||||
|
string(0) ""
|
||||||
|
}
|
36
ext/wddx/tests/bug72790.phpt
Normal file
36
ext/wddx/tests/bug72790.phpt
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
--TEST--
|
||||||
|
Bug 72790: wddx_deserialize null dereference with invalid xml
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (!extension_loaded('wddx')) {
|
||||||
|
die('skip. wddx not available');
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$xml = <<< XML
|
||||||
|
<?xml version='1.0' ?>
|
||||||
|
<!DOCTYPE wddxPacket SYSTEM 'wddx_0100.dtd'>
|
||||||
|
<wddxPacket version='1.0'>
|
||||||
|
|array>
|
||||||
|
<var name="XXXX">
|
||||||
|
<boolean value="this">
|
||||||
|
</boolean>
|
||||||
|
</var>
|
||||||
|
<var name="YYYY">
|
||||||
|
<var name="UUUU">
|
||||||
|
<var name="EZEZ">
|
||||||
|
</var>
|
||||||
|
</var>
|
||||||
|
</var>
|
||||||
|
</array>
|
||||||
|
</wddxPacket>
|
||||||
|
XML;
|
||||||
|
|
||||||
|
$array = wddx_deserialize($xml);
|
||||||
|
var_dump($array);
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Notice: Undefined variable: array in %s%ebug72790.php on line %d
|
||||||
|
NULL
|
29
ext/wddx/tests/bug72799.phpt
Normal file
29
ext/wddx/tests/bug72799.phpt
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72799: wddx_deserialize null dereference in php_wddx_pop_element
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (!extension_loaded('wddx')) {
|
||||||
|
die('skip. wddx not available');
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$xml = <<<XML
|
||||||
|
<?xml version='1.0'?>
|
||||||
|
<!DOCTYPE wddxPacket SYSTEM 'wddx_0100.dtd'>
|
||||||
|
<wddxPacket version="1.0">
|
||||||
|
<var name="XXXX">
|
||||||
|
<boolean value="1">
|
||||||
|
<dateTime>1998-06-12T04:32:12+00</dateTime>
|
||||||
|
</boolean>
|
||||||
|
</var>
|
||||||
|
</wddxPacket>
|
||||||
|
XML;
|
||||||
|
|
||||||
|
$array = wddx_deserialize($xml);
|
||||||
|
var_dump($array);
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Notice: Undefined variable: array in %s%ebug72799.php on line 16
|
||||||
|
NULL
|
|
@ -886,10 +886,10 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name)
|
||||||
if (Z_TYPE(ent1->data) == IS_UNDEF) {
|
if (Z_TYPE(ent1->data) == IS_UNDEF) {
|
||||||
if (stack->top > 1) {
|
if (stack->top > 1) {
|
||||||
stack->top--;
|
stack->top--;
|
||||||
|
efree(ent1);
|
||||||
} else {
|
} else {
|
||||||
stack->done = 1;
|
stack->done = 1;
|
||||||
}
|
}
|
||||||
efree(ent1);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -897,7 +897,11 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name)
|
||||||
zend_string *new_str = php_base64_decode(
|
zend_string *new_str = php_base64_decode(
|
||||||
(unsigned char *)Z_STRVAL(ent1->data), Z_STRLEN(ent1->data));
|
(unsigned char *)Z_STRVAL(ent1->data), Z_STRLEN(ent1->data));
|
||||||
zval_ptr_dtor(&ent1->data);
|
zval_ptr_dtor(&ent1->data);
|
||||||
ZVAL_STR(&ent1->data, new_str);
|
if (new_str) {
|
||||||
|
ZVAL_STR(&ent1->data, new_str);
|
||||||
|
} else {
|
||||||
|
ZVAL_EMPTY_STRING(&ent1->data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Call __wakeup() method on the object. */
|
/* Call __wakeup() method on the object. */
|
||||||
|
@ -917,7 +921,7 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name)
|
||||||
wddx_stack_top(stack, (void**)&ent2);
|
wddx_stack_top(stack, (void**)&ent2);
|
||||||
|
|
||||||
/* if non-existent field */
|
/* if non-existent field */
|
||||||
if (ent2->type == ST_FIELD && Z_ISUNDEF(ent2->data)) {
|
if (Z_ISUNDEF(ent2->data)) {
|
||||||
zval_ptr_dtor(&ent1->data);
|
zval_ptr_dtor(&ent1->data);
|
||||||
efree(ent1);
|
efree(ent1);
|
||||||
return;
|
return;
|
||||||
|
@ -1030,16 +1034,23 @@ static void php_wddx_process_data(void *user_data, const XML_Char *s, int len)
|
||||||
case ST_DATETIME: {
|
case ST_DATETIME: {
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
tmp = emalloc(len + 1);
|
if (Z_TYPE(ent->data) == IS_STRING) {
|
||||||
memcpy(tmp, (char *)s, len);
|
tmp = safe_emalloc(Z_STRLEN(ent->data), 1, (size_t)len + 1);
|
||||||
|
memcpy(tmp, Z_STRVAL(ent->data), Z_STRLEN(ent->data));
|
||||||
|
memcpy(tmp + Z_STRLEN(ent->data), s, len);
|
||||||
|
len += Z_STRLEN(ent->data);
|
||||||
|
zval_dtor(&ent->data);
|
||||||
|
} else {
|
||||||
|
tmp = emalloc(len + 1);
|
||||||
|
memcpy(tmp, (char *)s, len);
|
||||||
|
}
|
||||||
tmp[len] = '\0';
|
tmp[len] = '\0';
|
||||||
|
|
||||||
Z_LVAL(ent->data) = php_parse_date(tmp, NULL);
|
ZVAL_LONG(&ent->data, php_parse_date(tmp, NULL));
|
||||||
/* date out of range < 1969 or > 2038 */
|
/* date out of range < 1969 or > 2038 */
|
||||||
if (Z_LVAL(ent->data) == -1) {
|
if (Z_LVAL(ent->data) == -1) {
|
||||||
ZVAL_STRINGL(&ent->data, (char *)s, len);
|
ZVAL_STRINGL(&ent->data, (char *)tmp, len);
|
||||||
}
|
}
|
||||||
efree(tmp);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1073,8 +1084,12 @@ int php_wddx_deserialize_ex(const char *value, size_t vallen, zval *return_value
|
||||||
|
|
||||||
if (stack.top == 1) {
|
if (stack.top == 1) {
|
||||||
wddx_stack_top(&stack, (void**)&ent);
|
wddx_stack_top(&stack, (void**)&ent);
|
||||||
ZVAL_COPY(return_value, &ent->data);
|
if (Z_ISUNDEF(ent->data)) {
|
||||||
retval = SUCCESS;
|
retval = FAILURE;
|
||||||
|
} else {
|
||||||
|
ZVAL_COPY(return_value, &ent->data);
|
||||||
|
retval = SUCCESS;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
retval = FAILURE;
|
retval = FAILURE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,7 +144,7 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path
|
||||||
char *path_file;
|
char *path_file;
|
||||||
int resolved_basedir_len;
|
int resolved_basedir_len;
|
||||||
int resolved_name_len;
|
int resolved_name_len;
|
||||||
int path_len;
|
size_t path_len;
|
||||||
int nesting_level = 0;
|
int nesting_level = 0;
|
||||||
|
|
||||||
/* Special case basedir==".": Use script-directory */
|
/* Special case basedir==".": Use script-directory */
|
||||||
|
@ -153,7 +153,7 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path
|
||||||
strlcpy(local_open_basedir, basedir, sizeof(local_open_basedir));
|
strlcpy(local_open_basedir, basedir, sizeof(local_open_basedir));
|
||||||
}
|
}
|
||||||
|
|
||||||
path_len = (int)strlen(path);
|
path_len = strlen(path);
|
||||||
if (path_len > (MAXPATHLEN - 1)) {
|
if (path_len > (MAXPATHLEN - 1)) {
|
||||||
/* empty and too long paths are invalid */
|
/* empty and too long paths are invalid */
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -164,7 +164,7 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
path_len = (int)strlen(resolved_name);
|
path_len = strlen(resolved_name);
|
||||||
memcpy(path_tmp, resolved_name, path_len + 1); /* safe */
|
memcpy(path_tmp, resolved_name, path_len + 1); /* safe */
|
||||||
|
|
||||||
while (VCWD_REALPATH(path_tmp, resolved_name) == NULL) {
|
while (VCWD_REALPATH(path_tmp, resolved_name) == NULL) {
|
||||||
|
|
|
@ -857,7 +857,19 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
|
||||||
data->is_pipe_blocking = value;
|
data->is_pipe_blocking = value;
|
||||||
return PHP_STREAM_OPTION_RETURN_OK;
|
return PHP_STREAM_OPTION_RETURN_OK;
|
||||||
#endif
|
#endif
|
||||||
|
case PHP_STREAM_OPTION_META_DATA_API:
|
||||||
|
if (fd == -1)
|
||||||
|
return -1;
|
||||||
|
#ifdef O_NONBLOCK
|
||||||
|
flags = fcntl(fd, F_GETFL, 0);
|
||||||
|
|
||||||
|
add_assoc_bool((zval*)ptrparam, "timed_out", 0);
|
||||||
|
add_assoc_bool((zval*)ptrparam, "blocked", (flags & O_NONBLOCK)? 0 : 1);
|
||||||
|
add_assoc_bool((zval*)ptrparam, "eof", stream->eof);
|
||||||
|
|
||||||
|
return PHP_STREAM_OPTION_RETURN_OK;
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
default:
|
default:
|
||||||
return PHP_STREAM_OPTION_RETURN_NOTIMPL;
|
return PHP_STREAM_OPTION_RETURN_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue