mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Merge remote-tracking branch 'origin/master' into native-tls
* origin/master: (25 commits) Fix return code (merges are hard :( ) fix bad merge Fix bug #68113 (Heap corruption in exif_thumbnail()) Fix bug #68089 - do not accept options with embedded \0 Fixed bug #68044: Integer overflow in unserialize() (32-bits only) Fix bug #68027 - fix date parsing in XMLRPC lib Fix bug #68113 (Heap corruption in exif_thumbnail()) Fix bug #68089 - do not accept options with embedded \0 Fixed bug #68044: Integer overflow in unserialize() (32-bits only) Fix bug #68027 - fix date parsing in XMLRPC lib Fix bug #68113 (Heap corruption in exif_thumbnail()) Fix bug #68089 - do not accept options with embedded \0 Fixed bug #68044: Integer overflow in unserialize() (32-bits only) Fix bug #68027 - fix date parsing in XMLRPC lib Fixed bug #68128 Added API function to retrive current custom heap handlers update NEWS and UPGRADING Allow to substitute storage layer in memory manager. Upated NEWS Address issues raised by @nikic ...
This commit is contained in:
commit
382f95e612
24 changed files with 686 additions and 317 deletions
|
@ -119,6 +119,9 @@
|
|||
# define ZEND_MM_CUSTOM 1 /* support for custom memory allocator */
|
||||
/* USE_ZEND_ALLOC=0 may switch to system malloc() */
|
||||
#endif
|
||||
#ifndef ZEND_MM_STORAGE
|
||||
# define ZEND_MM_STORAGE 1 /* support for custom memory storage */
|
||||
#endif
|
||||
#ifndef ZEND_MM_ERROR
|
||||
# define ZEND_MM_ERROR 1 /* report system errors */
|
||||
#endif
|
||||
|
@ -217,6 +220,9 @@ struct _zend_mm_heap {
|
|||
#if ZEND_MM_CUSTOM
|
||||
int use_custom_heap;
|
||||
#endif
|
||||
#if ZEND_MM_STORAGE
|
||||
zend_mm_storage *storage;
|
||||
#endif
|
||||
#if ZEND_MM_STAT
|
||||
size_t size; /* current memory usage */
|
||||
size_t peak; /* peak memory usage */
|
||||
|
@ -707,7 +713,7 @@ static zend_always_inline int zend_mm_bitset_is_free_range(zend_mm_bitset *bitse
|
|||
/* Chunks */
|
||||
/**********/
|
||||
|
||||
static void *zend_mm_chunk_alloc(size_t size, size_t alignment)
|
||||
static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment)
|
||||
{
|
||||
void *ptr = zend_mm_mmap(size);
|
||||
|
||||
|
@ -751,6 +757,40 @@ static void *zend_mm_chunk_alloc(size_t size, size_t alignment)
|
|||
}
|
||||
}
|
||||
|
||||
static void *zend_mm_chunk_alloc(zend_mm_heap *heap, size_t size, size_t alignment)
|
||||
{
|
||||
#if ZEND_MM_STORAGE
|
||||
if (UNEXPECTED(heap->storage)) {
|
||||
void *ptr = heap->storage->chunk_alloc(heap->storage, size, alignment);
|
||||
ZEND_ASSERT(((zend_uintptr_t)((char*)ptr + (alignment-1)) & (alignment-1)) == (zend_uintptr_t)ptr);
|
||||
return ptr;
|
||||
}
|
||||
#endif
|
||||
return zend_mm_chunk_alloc_int(size, alignment);
|
||||
}
|
||||
|
||||
static void zend_mm_chunk_free(zend_mm_heap *heap, void *addr, size_t size)
|
||||
{
|
||||
#if ZEND_MM_STORAGE
|
||||
if (UNEXPECTED(heap->storage)) {
|
||||
heap->storage->chunk_free(heap->storage, addr, size);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
zend_mm_munmap(addr, size);
|
||||
}
|
||||
|
||||
static void zend_mm_chunk_truncate(zend_mm_heap *heap, void *addr, size_t old_size, size_t new_size)
|
||||
{
|
||||
#if ZEND_MM_STORAGE
|
||||
if (UNEXPECTED(heap->storage)) {
|
||||
heap->storage->chunk_truncate(heap->storage, addr, old_size, new_size);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
zend_mm_munmap((char*)addr + new_size, old_size - new_size);
|
||||
}
|
||||
|
||||
static zend_always_inline void zend_mm_chunk_init(zend_mm_heap *heap, zend_mm_chunk *chunk)
|
||||
{
|
||||
chunk->heap = heap;
|
||||
|
@ -928,7 +968,7 @@ not_found:
|
|||
}
|
||||
}
|
||||
#endif
|
||||
chunk = (zend_mm_chunk*)zend_mm_chunk_alloc(ZEND_MM_CHUNK_SIZE, ZEND_MM_CHUNK_SIZE);
|
||||
chunk = (zend_mm_chunk*)zend_mm_chunk_alloc(heap, ZEND_MM_CHUNK_SIZE, ZEND_MM_CHUNK_SIZE);
|
||||
if (UNEXPECTED(chunk == NULL)) {
|
||||
/* insufficient memory */
|
||||
#if !ZEND_MM_LIMIT
|
||||
|
@ -1019,11 +1059,11 @@ static void zend_mm_free_pages(zend_mm_heap *heap, zend_mm_chunk *chunk, int pag
|
|||
heap->real_size -= ZEND_MM_CHUNK_SIZE;
|
||||
#endif
|
||||
if (!heap->cached_chunks || chunk->num > heap->cached_chunks->num) {
|
||||
zend_mm_munmap(chunk, ZEND_MM_CHUNK_SIZE);
|
||||
zend_mm_chunk_free(heap, chunk, ZEND_MM_CHUNK_SIZE);
|
||||
} else {
|
||||
//TODO: select the best chunk to delete???
|
||||
chunk->next = heap->cached_chunks->next;
|
||||
zend_mm_munmap(heap->cached_chunks, ZEND_MM_CHUNK_SIZE);
|
||||
zend_mm_chunk_free(heap, heap->cached_chunks, ZEND_MM_CHUNK_SIZE);
|
||||
heap->cached_chunks = chunk;
|
||||
}
|
||||
}
|
||||
|
@ -1355,7 +1395,7 @@ static void *zend_mm_realloc_heap(zend_mm_heap *heap, void *ptr, size_t size ZEN
|
|||
#ifndef _WIN32
|
||||
} else if (new_size < old_size) {
|
||||
/* unmup tail */
|
||||
zend_mm_munmap((char*)ptr + new_size, old_size - new_size);
|
||||
zend_mm_chunk_truncate(heap, ptr, old_size, new_size);
|
||||
#if ZEND_MM_STAT || ZEND_MM_LIMIT
|
||||
heap->real_size -= old_size - new_size;
|
||||
#endif
|
||||
|
@ -1607,7 +1647,7 @@ static void *zend_mm_alloc_huge(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D
|
|||
}
|
||||
}
|
||||
#endif
|
||||
ptr = zend_mm_chunk_alloc(new_size, ZEND_MM_CHUNK_SIZE);
|
||||
ptr = zend_mm_chunk_alloc(heap, new_size, ZEND_MM_CHUNK_SIZE);
|
||||
if (UNEXPECTED(ptr == NULL)) {
|
||||
/* insufficient memory */
|
||||
#if !ZEND_MM_LIMIT
|
||||
|
@ -1649,7 +1689,7 @@ static void zend_mm_free_huge(zend_mm_heap *heap, void *ptr ZEND_FILE_LINE_DC ZE
|
|||
|
||||
ZEND_MM_CHECK(ZEND_MM_ALIGNED_OFFSET(ptr, ZEND_MM_CHUNK_SIZE) == 0, "zend_mm_heap corrupted");
|
||||
size = zend_mm_del_huge_block(heap, ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
zend_mm_munmap(ptr, size);
|
||||
zend_mm_chunk_free(heap, ptr, size);
|
||||
#if ZEND_MM_STAT || ZEND_MM_LIMIT
|
||||
heap->real_size -= size;
|
||||
#endif
|
||||
|
@ -1662,9 +1702,9 @@ static void zend_mm_free_huge(zend_mm_heap *heap, void *ptr ZEND_FILE_LINE_DC ZE
|
|||
/* Initialization */
|
||||
/******************/
|
||||
|
||||
zend_mm_heap *zend_mm_init(void)
|
||||
static zend_mm_heap *zend_mm_init(void)
|
||||
{
|
||||
zend_mm_chunk *chunk = (zend_mm_chunk*)zend_mm_chunk_alloc(ZEND_MM_CHUNK_SIZE, ZEND_MM_CHUNK_SIZE);
|
||||
zend_mm_chunk *chunk = (zend_mm_chunk*)zend_mm_chunk_alloc_int(ZEND_MM_CHUNK_SIZE, ZEND_MM_CHUNK_SIZE);
|
||||
zend_mm_heap *heap;
|
||||
|
||||
if (UNEXPECTED(chunk == NULL)) {
|
||||
|
@ -1706,6 +1746,9 @@ zend_mm_heap *zend_mm_init(void)
|
|||
#endif
|
||||
#if ZEND_MM_CUSTOM
|
||||
heap->use_custom_heap = 0;
|
||||
#endif
|
||||
#if ZEND_MM_STORAGE
|
||||
heap->storage = NULL;
|
||||
#endif
|
||||
heap->huge_list = NULL;
|
||||
return heap;
|
||||
|
@ -1805,7 +1848,7 @@ static void zend_mm_check_leaks(zend_mm_heap *heap TSRMLS_DC)
|
|||
}
|
||||
|
||||
list = list->next;
|
||||
zend_mm_munmap(q->ptr, q->size);
|
||||
zend_mm_chunk_free(heap, q->ptr, q->size);
|
||||
zend_mm_free_heap(heap, q, NULL, 0, NULL, 0);
|
||||
}
|
||||
|
||||
|
@ -1904,7 +1947,7 @@ void zend_mm_shutdown(zend_mm_heap *heap, int full, int silent TSRMLS_DC)
|
|||
while (list) {
|
||||
zend_mm_huge_list *q = list;
|
||||
list = list->next;
|
||||
zend_mm_munmap(q->ptr, q->size);
|
||||
zend_mm_chunk_free(heap, q->ptr, q->size);
|
||||
}
|
||||
|
||||
/* move all chunks except of the first one into the cache */
|
||||
|
@ -1923,10 +1966,20 @@ void zend_mm_shutdown(zend_mm_heap *heap, int full, int silent TSRMLS_DC)
|
|||
while (heap->cached_chunks) {
|
||||
p = heap->cached_chunks;
|
||||
heap->cached_chunks = p->next;
|
||||
zend_mm_munmap(p, ZEND_MM_CHUNK_SIZE);
|
||||
zend_mm_chunk_free(heap, p, ZEND_MM_CHUNK_SIZE);
|
||||
}
|
||||
/* free the first chunk */
|
||||
zend_mm_munmap(heap->main_chunk, ZEND_MM_CHUNK_SIZE);
|
||||
#if ZEND_MM_STORAGE
|
||||
if (UNEXPECTED(heap->storage)) {
|
||||
zend_mm_storage *storage = heap->storage;
|
||||
zend_mm_chunk_free(heap, heap->main_chunk, ZEND_MM_CHUNK_SIZE);
|
||||
storage->dtor(storage);
|
||||
} else {
|
||||
zend_mm_chunk_free(heap, heap->main_chunk, ZEND_MM_CHUNK_SIZE);
|
||||
}
|
||||
#else
|
||||
zend_mm_chunk_free(heap, heap->main_chunk, ZEND_MM_CHUNK_SIZE);
|
||||
#endif
|
||||
} else {
|
||||
zend_mm_heap old_heap;
|
||||
|
||||
|
@ -1936,7 +1989,7 @@ void zend_mm_shutdown(zend_mm_heap *heap, int full, int silent TSRMLS_DC)
|
|||
heap->cached_chunks) {
|
||||
p = heap->cached_chunks;
|
||||
heap->cached_chunks = p->next;
|
||||
zend_mm_munmap(p, ZEND_MM_CHUNK_SIZE);
|
||||
zend_mm_chunk_free(heap, p, ZEND_MM_CHUNK_SIZE);
|
||||
heap->cached_chunks_count--;
|
||||
}
|
||||
/* clear cached chunks */
|
||||
|
@ -2343,6 +2396,98 @@ ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
|
|||
#endif
|
||||
}
|
||||
|
||||
ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
|
||||
void* (**_malloc)(size_t),
|
||||
void (**_free)(void*),
|
||||
void* (**_realloc)(void*, size_t))
|
||||
{
|
||||
#if ZEND_MM_CUSTOM
|
||||
zend_mm_heap *_heap = (zend_mm_heap*)heap;
|
||||
|
||||
if (heap->use_custom_heap) {
|
||||
*_malloc = _heap->_malloc;
|
||||
*_free = _heap->_free;
|
||||
*_realloc = _heap->_realloc;
|
||||
} else {
|
||||
*_malloc = NULL;
|
||||
*_free = NULL;
|
||||
*_realloc = NULL;
|
||||
}
|
||||
#else
|
||||
*_malloc = NULL;
|
||||
*_free = NULL;
|
||||
*_realloc = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
ZEND_API zend_mm_storage *zend_mm_get_storage(zend_mm_heap *heap)
|
||||
{
|
||||
#if ZEND_MM_CUSTOM
|
||||
return heap->storage;
|
||||
#else
|
||||
return NULL
|
||||
#endif
|
||||
}
|
||||
|
||||
ZEND_API zend_mm_heap *zend_mm_startup(void)
|
||||
{
|
||||
return zend_mm_init();
|
||||
}
|
||||
|
||||
ZEND_API zend_mm_heap *zend_mm_startup_ex(zend_mm_storage *storage)
|
||||
{
|
||||
#if ZEND_MM_STORAGE
|
||||
zend_mm_chunk *chunk = (zend_mm_chunk*)storage->chunk_alloc(storage, ZEND_MM_CHUNK_SIZE, ZEND_MM_CHUNK_SIZE);
|
||||
zend_mm_heap *heap;
|
||||
|
||||
if (UNEXPECTED(chunk == NULL)) {
|
||||
#if ZEND_MM_ERROR
|
||||
#ifdef _WIN32
|
||||
stderr_last_error("Can't initialize heap");
|
||||
#else
|
||||
fprintf(stderr, "\nCan't initialize heap: [%d] %s\n", errno, strerror(errno));
|
||||
#endif
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
heap = &chunk->heap_slot;
|
||||
chunk->heap = heap;
|
||||
chunk->next = chunk;
|
||||
chunk->prev = chunk;
|
||||
chunk->free_pages = ZEND_MM_PAGES - ZEND_MM_FIRST_PAGE;
|
||||
chunk->free_tail = ZEND_MM_FIRST_PAGE;
|
||||
chunk->num = 0;
|
||||
chunk->free_map[0] = (Z_L(1) << ZEND_MM_FIRST_PAGE) - 1;
|
||||
chunk->map[0] = ZEND_MM_LRUN(ZEND_MM_FIRST_PAGE);
|
||||
heap->main_chunk = chunk;
|
||||
heap->cached_chunks = NULL;
|
||||
heap->chunks_count = 1;
|
||||
heap->peak_chunks_count = 1;
|
||||
heap->cached_chunks_count = 0;
|
||||
heap->avg_chunks_count = 1.0;
|
||||
#if ZEND_MM_STAT || ZEND_MM_LIMIT
|
||||
heap->real_size = ZEND_MM_CHUNK_SIZE;
|
||||
#endif
|
||||
#if ZEND_MM_STAT
|
||||
heap->real_peak = ZEND_MM_CHUNK_SIZE;
|
||||
heap->size = 0;
|
||||
heap->peak = 0;
|
||||
#endif
|
||||
#if ZEND_MM_LIMIT
|
||||
heap->limit = (Z_L(-1) >> Z_L(1));
|
||||
heap->overflow = 0;
|
||||
#endif
|
||||
#if ZEND_MM_CUSTOM
|
||||
heap->use_custom_heap = 0;
|
||||
#endif
|
||||
heap->storage = storage;
|
||||
heap->huge_list = NULL;
|
||||
return heap;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
|
|
@ -259,6 +259,27 @@ ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
|
|||
void* (*_malloc)(size_t),
|
||||
void (*_free)(void*),
|
||||
void* (*_realloc)(void*, size_t));
|
||||
ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
|
||||
void* (**_malloc)(size_t),
|
||||
void (**_free)(void*),
|
||||
void* (**_realloc)(void*, size_t));
|
||||
|
||||
typedef struct _zend_mm_storage zend_mm_storage;
|
||||
|
||||
typedef void* (*zend_mm_chunk_alloc_t)(zend_mm_storage *storage, size_t size, size_t alignment);
|
||||
typedef void (*zend_mm_chunk_free_t)(zend_mm_storage *storage, void *chunk, size_t size);
|
||||
typedef void (*zend_mm_chunk_truncate_t)(zend_mm_storage *storage, void *chunk, size_t old_size, size_t new_size);
|
||||
typedef void (*zend_mm_storage_dtor_t)(zend_mm_storage *storage);
|
||||
|
||||
struct _zend_mm_storage {
|
||||
zend_mm_chunk_alloc_t chunk_alloc;
|
||||
zend_mm_chunk_free_t chunk_free;
|
||||
zend_mm_chunk_truncate_t chunk_truncate;
|
||||
zend_mm_storage_dtor_t dtor;
|
||||
};
|
||||
|
||||
ZEND_API zend_mm_storage *zend_mm_get_storage(zend_mm_heap *heap);
|
||||
ZEND_API zend_mm_heap *zend_mm_startup_ex(zend_mm_storage *storage);
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
|
|
|
@ -170,6 +170,11 @@ static int php_curl_option_str(php_curl *ch, zend_long option, const char *str,
|
|||
{
|
||||
CURLcode error = CURLE_OK;
|
||||
|
||||
if (strlen(str) != len) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Curl option contains invalid characters (\\0)");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x071100
|
||||
if (make_copy) {
|
||||
#endif
|
||||
|
|
18
ext/curl/tests/bug68089.phpt
Normal file
18
ext/curl/tests/bug68089.phpt
Normal file
|
@ -0,0 +1,18 @@
|
|||
--TEST--
|
||||
Bug #68089 (NULL byte injection - cURL lib)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include 'skipif.inc';
|
||||
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$url = "file:///etc/passwd\0http://google.com";
|
||||
$ch = curl_init();
|
||||
var_dump(curl_setopt($ch, CURLOPT_URL, $url));
|
||||
?>
|
||||
Done
|
||||
--EXPECTF--
|
||||
Warning: curl_setopt(): Curl option contains invalid characters (\0) in %s/bug68089.php on line 4
|
||||
bool(false)
|
||||
Done
|
|
@ -2413,11 +2413,11 @@ static void* exif_ifd_make_value(image_info_data *info_data, int motorola_intel
|
|||
data_ptr += 8;
|
||||
break;
|
||||
case TAG_FMT_SINGLE:
|
||||
memmove(data_ptr, &info_data->value.f, byte_count);
|
||||
memmove(data_ptr, &info_value->f, 4);
|
||||
data_ptr += 4;
|
||||
break;
|
||||
case TAG_FMT_DOUBLE:
|
||||
memmove(data_ptr, &info_data->value.d, byte_count);
|
||||
memmove(data_ptr, &info_value->d, 8);
|
||||
data_ptr += 8;
|
||||
break;
|
||||
}
|
||||
|
|
BIN
ext/exif/tests/bug68113.jpg
Executable file
BIN
ext/exif/tests/bug68113.jpg
Executable file
Binary file not shown.
After Width: | Height: | Size: 368 B |
17
ext/exif/tests/bug68113.phpt
Normal file
17
ext/exif/tests/bug68113.phpt
Normal file
|
@ -0,0 +1,17 @@
|
|||
--TEST--
|
||||
Bug #68113 (Heap corruption in exif_thumbnail())
|
||||
--SKIPIF--
|
||||
<?php
|
||||
extension_loaded("exif") or die("skip need exif");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump(exif_thumbnail(__DIR__."/bug68113.jpg"));
|
||||
?>
|
||||
Done
|
||||
--EXPECTF--
|
||||
Warning: exif_thumbnail(bug68113.jpg): File structure corrupted in %s/bug68113.php on line 2
|
||||
|
||||
Warning: exif_thumbnail(bug68113.jpg): Invalid JPEG file in %s/bug68113.php on line 2
|
||||
bool(false)
|
||||
Done
|
118
ext/gmp/gmp.c
118
ext/gmp/gmp.c
|
@ -104,6 +104,15 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_random, 0, 0, 0)
|
|||
ZEND_ARG_INFO(0, limiter)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_random_bits, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, bits)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_random_range, 0, 0, 2)
|
||||
ZEND_ARG_INFO(0, min)
|
||||
ZEND_ARG_INFO(0, max)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_gmp_setbit, 0, 0, 2)
|
||||
ZEND_ARG_INFO(0, a)
|
||||
ZEND_ARG_INFO(0, index)
|
||||
|
@ -161,6 +170,8 @@ const zend_function_entry gmp_functions[] = {
|
|||
ZEND_FE(gmp_cmp, arginfo_gmp_binary)
|
||||
ZEND_FE(gmp_sign, arginfo_gmp_unary)
|
||||
ZEND_FE(gmp_random, arginfo_gmp_random)
|
||||
ZEND_FE(gmp_random_bits, arginfo_gmp_random_bits)
|
||||
ZEND_FE(gmp_random_range, arginfo_gmp_random_range)
|
||||
ZEND_FE(gmp_and, arginfo_gmp_binary)
|
||||
ZEND_FE(gmp_or, arginfo_gmp_binary)
|
||||
ZEND_FE(gmp_com, arginfo_gmp_unary)
|
||||
|
@ -1743,6 +1754,18 @@ ZEND_FUNCTION(gmp_sign)
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
static void gmp_init_random(TSRMLS_D)
|
||||
{
|
||||
if (!GMPG(rand_initialized)) {
|
||||
/* Initialize */
|
||||
gmp_randinit_mt(GMPG(rand_state));
|
||||
/* Seed */
|
||||
gmp_randseed_ui(GMPG(rand_state), GENERATE_SEED());
|
||||
|
||||
GMPG(rand_initialized) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ proto GMP gmp_random([int limiter])
|
||||
Gets random number */
|
||||
ZEND_FUNCTION(gmp_random)
|
||||
|
@ -1755,16 +1778,8 @@ ZEND_FUNCTION(gmp_random)
|
|||
}
|
||||
|
||||
INIT_GMP_RETVAL(gmpnum_result);
|
||||
gmp_init_random(TSRMLS_C);
|
||||
|
||||
if (!GMPG(rand_initialized)) {
|
||||
/* Initialize */
|
||||
gmp_randinit_mt(GMPG(rand_state));
|
||||
|
||||
/* Seed */
|
||||
gmp_randseed_ui(GMPG(rand_state), GENERATE_SEED());
|
||||
|
||||
GMPG(rand_initialized) = 1;
|
||||
}
|
||||
#ifdef GMP_LIMB_BITS
|
||||
mpz_urandomb(gmpnum_result, GMPG(rand_state), GMP_ABS (limiter) * GMP_LIMB_BITS);
|
||||
#else
|
||||
|
@ -1773,6 +1788,91 @@ ZEND_FUNCTION(gmp_random)
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto GMP gmp_random_bits(int bits)
|
||||
Gets a random number in the range 0 to (2 ** n) - 1 */
|
||||
ZEND_FUNCTION(gmp_random_bits)
|
||||
{
|
||||
long bits;
|
||||
mpz_ptr gmpnum_result;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &bits) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bits <= 0) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The number of bits must be positive");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
INIT_GMP_RETVAL(gmpnum_result);
|
||||
gmp_init_random(TSRMLS_C);
|
||||
|
||||
mpz_urandomb(gmpnum_result, GMPG(rand_state), bits);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto GMP gmp_random_range(mixed min, mixed max)
|
||||
Gets a random number in the range min to max */
|
||||
ZEND_FUNCTION(gmp_random_range)
|
||||
{
|
||||
zval *min_arg, *max_arg;
|
||||
mpz_ptr gmpnum_min, gmpnum_max, gmpnum_result;
|
||||
gmp_temp_t temp_a, temp_b;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &min_arg, &max_arg) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
gmp_init_random(TSRMLS_C);
|
||||
|
||||
FETCH_GMP_ZVAL(gmpnum_max, max_arg, temp_a);
|
||||
|
||||
if (Z_TYPE_P(min_arg) == IS_LONG && Z_LVAL_P(min_arg) >= 0) {
|
||||
if (mpz_cmp_ui(gmpnum_max, Z_LVAL_P(min_arg)) <= 0) {
|
||||
FREE_GMP_TEMP(temp_a);
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The minimum value must be less than the maximum value");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
INIT_GMP_RETVAL(gmpnum_result);
|
||||
|
||||
if (Z_LVAL_P(min_arg)) {
|
||||
mpz_sub_ui(gmpnum_max, gmpnum_max, Z_LVAL_P(min_arg));
|
||||
}
|
||||
|
||||
mpz_add_ui(gmpnum_max, gmpnum_max, 1);
|
||||
mpz_urandomm(gmpnum_result, GMPG(rand_state), gmpnum_max);
|
||||
|
||||
if (Z_LVAL_P(min_arg)) {
|
||||
mpz_add_ui(gmpnum_result, gmpnum_result, Z_LVAL_P(min_arg));
|
||||
}
|
||||
|
||||
FREE_GMP_TEMP(temp_a);
|
||||
|
||||
}
|
||||
else {
|
||||
FETCH_GMP_ZVAL_DEP(gmpnum_min, min_arg, temp_b, temp_a);
|
||||
|
||||
if (mpz_cmp(gmpnum_max, gmpnum_min) <= 0) {
|
||||
FREE_GMP_TEMP(temp_b);
|
||||
FREE_GMP_TEMP(temp_a);
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The minimum value must be less than the maximum value");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
INIT_GMP_RETVAL(gmpnum_result);
|
||||
|
||||
mpz_sub(gmpnum_max, gmpnum_max, gmpnum_min);
|
||||
mpz_add_ui(gmpnum_max, gmpnum_max, 1);
|
||||
mpz_urandomm(gmpnum_result, GMPG(rand_state), gmpnum_max);
|
||||
mpz_add(gmpnum_result, gmpnum_result, gmpnum_min);
|
||||
|
||||
FREE_GMP_TEMP(temp_b);
|
||||
FREE_GMP_TEMP(temp_a);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto GMP gmp_and(mixed a, mixed b)
|
||||
Calculates logical AND of a and b */
|
||||
ZEND_FUNCTION(gmp_and)
|
||||
|
|
|
@ -66,6 +66,8 @@ ZEND_FUNCTION(gmp_or);
|
|||
ZEND_FUNCTION(gmp_com);
|
||||
ZEND_FUNCTION(gmp_xor);
|
||||
ZEND_FUNCTION(gmp_random);
|
||||
ZEND_FUNCTION(gmp_random_bits);
|
||||
ZEND_FUNCTION(gmp_random_range);
|
||||
ZEND_FUNCTION(gmp_setbit);
|
||||
ZEND_FUNCTION(gmp_clrbit);
|
||||
ZEND_FUNCTION(gmp_scan0);
|
||||
|
|
45
ext/gmp/tests/gmp_random_bits.phpt
Normal file
45
ext/gmp/tests/gmp_random_bits.phpt
Normal file
|
@ -0,0 +1,45 @@
|
|||
--TEST--
|
||||
gmp_random_bits() basic tests
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("gmp")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
var_dump(gmp_random_bits());
|
||||
var_dump(gmp_random_bits(0));
|
||||
var_dump(gmp_random_bits(-1));
|
||||
|
||||
// If these error the test fails.
|
||||
gmp_random_bits(1);
|
||||
gmp_random_bits(1024);
|
||||
|
||||
// 2 seconds to make sure the numbers stay in range
|
||||
$start = microtime(true);
|
||||
$limit = (2 ** 30) - 1;
|
||||
while (1) {
|
||||
for ($i = 0; $i < 5000; $i++) {
|
||||
$result = gmp_random_bits(30);
|
||||
if ($result < 0 || $result > $limit) {
|
||||
print "RANGE VIOLATION\n";
|
||||
var_dump($result);
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (microtime(true) - $start > 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: gmp_random_bits() expects exactly 1 parameter, 0 given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: gmp_random_bits(): The number of bits must be positive in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: gmp_random_bits(): The number of bits must be positive in %s on line %d
|
||||
bool(false)
|
||||
Done
|
81
ext/gmp/tests/gmp_random_range.phpt
Normal file
81
ext/gmp/tests/gmp_random_range.phpt
Normal file
|
@ -0,0 +1,81 @@
|
|||
--TEST--
|
||||
gmp_random_range() basic tests
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("gmp")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$minusTen = gmp_init(-1);
|
||||
$plusTen = gmp_init(1);
|
||||
$zero = gmp_init(0);
|
||||
|
||||
var_dump(gmp_random_range());
|
||||
var_dump(gmp_random_range(10));
|
||||
var_dump(gmp_random_range(10, -10));
|
||||
|
||||
var_dump(gmp_random_range($plusTen, $minusTen));
|
||||
var_dump(gmp_random_range($plusTen, $zero));
|
||||
|
||||
// If these error the test fails.
|
||||
gmp_random_range(0, 10);
|
||||
gmp_random_range(1, 10);
|
||||
gmp_random_range(-1, 10);
|
||||
gmp_random_range(-10, 0);
|
||||
gmp_random_range(-10, -1);
|
||||
|
||||
gmp_random_range(0, $plusTen);
|
||||
gmp_random_range(1, $plusTen);
|
||||
gmp_random_range(-1, $plusTen);
|
||||
|
||||
gmp_random_range($zero, $plusTen);
|
||||
gmp_random_range($minusTen, $plusTen);
|
||||
|
||||
// 2 seconds to make sure the numbers stay in range
|
||||
$start = microtime(true);
|
||||
while (1) {
|
||||
for ($i = 0; $i < 5000; $i++) {
|
||||
$result = gmp_random_range(0, 1000);
|
||||
if ($result < 0 || $result > 1000) {
|
||||
print "RANGE VIOLATION 1\n";
|
||||
var_dump($result);
|
||||
break 2;
|
||||
}
|
||||
|
||||
$result = gmp_random_range(-1000, 0);
|
||||
if ($result < -1000 || $result > 0) {
|
||||
print "RANGE VIOLATION 2\n";
|
||||
var_dump($result);
|
||||
break 2;
|
||||
}
|
||||
|
||||
$result = gmp_random_range(-500, 500);
|
||||
if ($result < -500 || $result > 500) {
|
||||
print "RANGE VIOLATION 3\n";
|
||||
var_dump($result);
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (microtime(true) - $start > 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: gmp_random_range() expects exactly 2 parameters, 0 given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: gmp_random_range() expects exactly 2 parameters, 1 given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: gmp_random_range(): The minimum value must be less than the maximum value in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: gmp_random_range(): The minimum value must be less than the maximum value in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: gmp_random_range(): The minimum value must be less than the maximum value in %s on line %d
|
||||
bool(false)
|
||||
Done
|
|
@ -51,6 +51,36 @@ static inline int spl_instantiate_arg_ex2(zend_class_entry *pce, zval *retval, z
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ spl_instantiate_arg_n */
|
||||
static inline void spl_instantiate_arg_n(zend_class_entry *pce, zval *retval, int argc, zval *argv TSRMLS_DC)
|
||||
{
|
||||
zend_function *func = pce->constructor;
|
||||
zend_fcall_info fci;
|
||||
zend_fcall_info_cache fcc;
|
||||
zval dummy;
|
||||
|
||||
spl_instantiate(pce, retval TSRMLS_CC);
|
||||
|
||||
fci.size = sizeof(zend_fcall_info);
|
||||
fci.function_table = &pce->function_table;
|
||||
ZVAL_STR(&fci.function_name, func->common.function_name);
|
||||
fci.object = Z_OBJ_P(retval);
|
||||
fci.symbol_table = NULL;
|
||||
fci.retval = &dummy;
|
||||
fci.param_count = argc;
|
||||
fci.params = argv;
|
||||
fci.no_separation = 1;
|
||||
|
||||
fcc.initialized = 1;
|
||||
fcc.function_handler = func;
|
||||
fcc.calling_scope = EG(scope);
|
||||
fcc.called_scope = pce;
|
||||
fcc.object = Z_OBJ_P(retval);
|
||||
|
||||
zend_call_function(&fci, &fcc TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#endif /* SPL_ENGINE_H */
|
||||
|
||||
/*
|
||||
|
|
|
@ -2037,8 +2037,10 @@ SPL_METHOD(RegexIterator, accept)
|
|||
|
||||
if (Z_TYPE(intern->current.data) == IS_UNDEF) {
|
||||
RETURN_FALSE;
|
||||
} else if (Z_TYPE(intern->current.data) == IS_ARRAY) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
|
||||
if (intern->u.regex.flags & REGIT_USE_KEY) {
|
||||
subject_ptr = &intern->current.key;
|
||||
} else {
|
||||
|
@ -2074,8 +2076,7 @@ SPL_METHOD(RegexIterator, accept)
|
|||
ZVAL_UNDEF(&intern->current.data);
|
||||
php_pcre_match_impl(intern->u.regex.pce, subject, subject_len, &zcount,
|
||||
&intern->current.data, intern->u.regex.mode == REGIT_MODE_ALL_MATCHES, intern->u.regex.use_flags, intern->u.regex.preg_flags, 0 TSRMLS_CC);
|
||||
count = zend_hash_num_elements(Z_ARRVAL(intern->current.data));
|
||||
RETVAL_BOOL(count > 0);
|
||||
RETVAL_BOOL(Z_LVAL(zcount) > 0);
|
||||
break;
|
||||
|
||||
case REGIT_MODE_SPLIT:
|
||||
|
@ -2254,7 +2255,7 @@ SPL_METHOD(RecursiveRegexIterator, __construct)
|
|||
SPL_METHOD(RecursiveRegexIterator, getChildren)
|
||||
{
|
||||
spl_dual_it_object *intern;
|
||||
zval retval, regex;
|
||||
zval retval;
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
return;
|
||||
|
@ -2264,13 +2265,40 @@ SPL_METHOD(RecursiveRegexIterator, getChildren)
|
|||
|
||||
zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval);
|
||||
if (!EG(exception)) {
|
||||
ZVAL_STR_COPY(®ex, intern->u.regex.regex);
|
||||
spl_instantiate_arg_ex2(Z_OBJCE_P(getThis()), return_value, &retval, ®ex TSRMLS_CC);
|
||||
zval_ptr_dtor(®ex);
|
||||
zval args[5];
|
||||
|
||||
ZVAL_COPY(&args[0], &retval);
|
||||
ZVAL_STR_COPY(&args[1], intern->u.regex.regex);
|
||||
ZVAL_LONG(&args[2], intern->u.regex.mode);
|
||||
ZVAL_LONG(&args[3], intern->u.regex.flags);
|
||||
ZVAL_LONG(&args[4], intern->u.regex.preg_flags);
|
||||
|
||||
spl_instantiate_arg_n(Z_OBJCE_P(getThis()), return_value, 5, args TSRMLS_CC);
|
||||
|
||||
zval_ptr_dtor(&args[1]);
|
||||
}
|
||||
zval_ptr_dtor(&retval);
|
||||
} /* }}} */
|
||||
|
||||
SPL_METHOD(RecursiveRegexIterator, accept)
|
||||
{
|
||||
spl_dual_it_object *intern;
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis());
|
||||
|
||||
if (Z_TYPE(intern->current.data) == IS_UNDEF) {
|
||||
RETURN_FALSE;
|
||||
} else if (Z_TYPE(intern->current.data) == IS_ARRAY) {
|
||||
RETURN_BOOL(zend_hash_num_elements(Z_ARRVAL(intern->current.data)) > 0);
|
||||
}
|
||||
|
||||
zend_call_method_with_0_params(getThis(), spl_ce_RegexIterator, NULL, "accept", return_value);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* {{{ spl_dual_it_dtor */
|
||||
|
@ -2456,6 +2484,7 @@ ZEND_END_ARG_INFO();
|
|||
|
||||
static const zend_function_entry spl_funcs_RecursiveRegexIterator[] = {
|
||||
SPL_ME(RecursiveRegexIterator, __construct, arginfo_rec_regex_it___construct, ZEND_ACC_PUBLIC)
|
||||
SPL_ME(RecursiveRegexIterator, accept, arginfo_recursive_it_void, ZEND_ACC_PUBLIC)
|
||||
SPL_ME(RecursiveFilterIterator, hasChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC)
|
||||
SPL_ME(RecursiveRegexIterator, getChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC)
|
||||
PHP_FE_END
|
||||
|
|
91
ext/spl/tests/bug68128.phpt
Normal file
91
ext/spl/tests/bug68128.phpt
Normal file
|
@ -0,0 +1,91 @@
|
|||
--TEST--
|
||||
Bug #68128 - RecursiveRegexIterator raises "Array to string conversion" notice
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$array = new ArrayIterator(array('a', array('b', 'c')));
|
||||
$regex = new RegexIterator($array, '/Array/');
|
||||
|
||||
foreach ($regex as $match) {
|
||||
var_dump($match);
|
||||
}
|
||||
|
||||
$rArrayIterator = new RecursiveArrayIterator(array('test1', array('tet3', 'test4', 'test5')));
|
||||
$rRegexIterator = new RecursiveRegexIterator($rArrayIterator, '/^(t)est(\d*)/',
|
||||
RecursiveRegexIterator::ALL_MATCHES, 0, PREG_PATTERN_ORDER);
|
||||
|
||||
foreach ($rRegexIterator as $key1 => $value1) {
|
||||
|
||||
if ($rRegexIterator->hasChildren()) {
|
||||
|
||||
// print all children
|
||||
echo "Children: ";
|
||||
foreach ($rRegexIterator->getChildren() as $key => $value) {
|
||||
print_r($value);
|
||||
}
|
||||
echo "\n";
|
||||
} else {
|
||||
echo "No children ";
|
||||
print_r($value1);
|
||||
echo "\n";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
No children Array
|
||||
(
|
||||
[0] => Array
|
||||
(
|
||||
[0] => test1
|
||||
)
|
||||
|
||||
[1] => Array
|
||||
(
|
||||
[0] => t
|
||||
)
|
||||
|
||||
[2] => Array
|
||||
(
|
||||
[0] => 1
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
Children: Array
|
||||
(
|
||||
[0] => Array
|
||||
(
|
||||
[0] => test4
|
||||
)
|
||||
|
||||
[1] => Array
|
||||
(
|
||||
[0] => t
|
||||
)
|
||||
|
||||
[2] => Array
|
||||
(
|
||||
[0] => 4
|
||||
)
|
||||
|
||||
)
|
||||
Array
|
||||
(
|
||||
[0] => Array
|
||||
(
|
||||
[0] => test5
|
||||
)
|
||||
|
||||
[1] => Array
|
||||
(
|
||||
[0] => t
|
||||
)
|
||||
|
||||
[2] => Array
|
||||
(
|
||||
[0] => 5
|
||||
)
|
||||
|
||||
)
|
||||
|
|
@ -13,11 +13,6 @@ class MyRecursiveRegexIterator extends RecursiveRegexIterator
|
|||
var_dump($v);
|
||||
}
|
||||
}
|
||||
|
||||
function accept()
|
||||
{
|
||||
return $this->hasChildren() || parent::accept();
|
||||
}
|
||||
}
|
||||
|
||||
$ar = new RecursiveArrayIterator(array('Foo', array('Bar'), 'FooBar', array('Baz'), 'Biz'));
|
||||
|
|
|
@ -46,8 +46,6 @@ array(3) {
|
|||
[2]=>
|
||||
%s(1) "2"
|
||||
}
|
||||
|
||||
Notice: Array to string conversion in %siterator_050.php on line %d
|
||||
int(0)
|
||||
array(2) {
|
||||
[0]=>
|
||||
|
@ -69,8 +67,6 @@ array(2) {
|
|||
[1]=>
|
||||
%s(1) "1"
|
||||
}
|
||||
|
||||
Notice: Array to string conversion in %siterator_050.php on line %d
|
||||
object(ArrayIterator)#%d (1) {
|
||||
%s"storage"%s"ArrayIterator":private]=>
|
||||
array(9) {
|
||||
|
|
|
@ -46,18 +46,6 @@ var_dump($ar);
|
|||
<?php exit(0); ?>
|
||||
--EXPECTF--
|
||||
bool(true)
|
||||
int(0)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
[2]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(1)
|
||||
array(3) {
|
||||
|
@ -97,85 +85,11 @@ array(3) {
|
|||
}
|
||||
}
|
||||
bool(true)
|
||||
int(3)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
[2]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(4)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
[2]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
|
||||
Notice: Array to string conversion in %siterator_052.php on line %d
|
||||
bool(false)
|
||||
bool(true)
|
||||
int(5)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
[2]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(6)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
[2]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(7)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
[2]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(8)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
[2]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(0)
|
||||
array(2) {
|
||||
|
@ -231,67 +145,11 @@ array(2) {
|
|||
}
|
||||
}
|
||||
bool(true)
|
||||
int(3)
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(4)
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
|
||||
Notice: Array to string conversion in %siterator_052.php on line %d
|
||||
bool(false)
|
||||
bool(true)
|
||||
int(5)
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(6)
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(7)
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(8)
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
object(ArrayIterator)#%d (1) {
|
||||
["storage":"ArrayIterator":private]=>
|
||||
array(9) {
|
||||
|
|
|
@ -46,122 +46,14 @@ var_dump($ar);
|
|||
<?php exit(0); ?>
|
||||
--EXPECTF--
|
||||
bool(true)
|
||||
int(0)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
[2]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(1)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
[2]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(2)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
[2]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(3)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
[2]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(4)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
[2]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(false)
|
||||
bool(true)
|
||||
int(5)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
[2]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(6)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
[2]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(7)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
[2]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(8)
|
||||
array(3) {
|
||||
[0]=>
|
||||
array(0) {
|
||||
}
|
||||
[1]=>
|
||||
array(0) {
|
||||
}
|
||||
[2]=>
|
||||
array(0) {
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(0)
|
||||
array(2) {
|
||||
|
@ -232,20 +124,7 @@ array(2) {
|
|||
string(1) "4"
|
||||
}
|
||||
}
|
||||
bool(true)
|
||||
int(5)
|
||||
array(2) {
|
||||
[0]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(1) "5"
|
||||
}
|
||||
[1]=>
|
||||
array(1) {
|
||||
[0]=>
|
||||
string(1) "5"
|
||||
}
|
||||
}
|
||||
bool(false)
|
||||
bool(true)
|
||||
int(6)
|
||||
array(2) {
|
||||
|
|
|
@ -42,8 +42,6 @@ array(3) {
|
|||
[2]=>
|
||||
string(1) "3"
|
||||
}
|
||||
|
||||
Notice: Array to string conversion in %siterator_054.php on line %d
|
||||
int(7)
|
||||
array(2) {
|
||||
[0]=>
|
||||
|
|
12
ext/standard/tests/serialize/bug68044.phpt
Normal file
12
ext/standard/tests/serialize/bug68044.phpt
Normal file
|
@ -0,0 +1,12 @@
|
|||
--TEST--
|
||||
Bug #68044 Integer overflow in unserialize() (32-bits only)
|
||||
--FILE--
|
||||
<?php
|
||||
echo unserialize('C:3:"XYZ":18446744075857035259:{}');
|
||||
?>
|
||||
===DONE==
|
||||
--EXPECTF--
|
||||
Warning: Insufficient data for unserializing - %d required, 1 present in %s/bug68044.php on line 2
|
||||
|
||||
Notice: unserialize(): Error at offset 32 of 33 bytes in %s/bug68044.php on line 2
|
||||
===DONE==
|
|
@ -386,7 +386,7 @@ static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
|
|||
|
||||
(*p) += 2;
|
||||
|
||||
if (datalen < 0 || (*p) + datalen >= max) {
|
||||
if (datalen < 0 || (max - (*p)) <= datalen) {
|
||||
zend_error(E_WARNING, "Insufficient data for unserializing - %pd required, %pd present", datalen, (zend_long)(max - (*p)));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -390,7 +390,7 @@ static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
|
|||
|
||||
(*p) += 2;
|
||||
|
||||
if (datalen < 0 || (*p) + datalen >= max) {
|
||||
if (datalen < 0 || (max - (*p)) <= datalen) {
|
||||
zend_error(E_WARNING, "Insufficient data for unserializing - %pd required, %pd present", datalen, (zend_long)(max - (*p)));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -219,16 +219,19 @@ static int date_from_ISO8601 (const char *text, time_t * value) {
|
|||
n = 10;
|
||||
tm.tm_mon = 0;
|
||||
for(i = 0; i < 2; i++) {
|
||||
XMLRPC_IS_NUMBER(text[i])
|
||||
XMLRPC_IS_NUMBER(text[i+4])
|
||||
tm.tm_mon += (text[i+4]-'0')*n;
|
||||
n /= 10;
|
||||
}
|
||||
tm.tm_mon --;
|
||||
if(tm.tm_mon < 0 || tm.tm_mon > 11) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
n = 10;
|
||||
tm.tm_mday = 0;
|
||||
for(i = 0; i < 2; i++) {
|
||||
XMLRPC_IS_NUMBER(text[i])
|
||||
XMLRPC_IS_NUMBER(text[i+6])
|
||||
tm.tm_mday += (text[i+6]-'0')*n;
|
||||
n /= 10;
|
||||
}
|
||||
|
@ -236,7 +239,7 @@ static int date_from_ISO8601 (const char *text, time_t * value) {
|
|||
n = 10;
|
||||
tm.tm_hour = 0;
|
||||
for(i = 0; i < 2; i++) {
|
||||
XMLRPC_IS_NUMBER(text[i])
|
||||
XMLRPC_IS_NUMBER(text[i+9])
|
||||
tm.tm_hour += (text[i+9]-'0')*n;
|
||||
n /= 10;
|
||||
}
|
||||
|
@ -244,7 +247,7 @@ static int date_from_ISO8601 (const char *text, time_t * value) {
|
|||
n = 10;
|
||||
tm.tm_min = 0;
|
||||
for(i = 0; i < 2; i++) {
|
||||
XMLRPC_IS_NUMBER(text[i])
|
||||
XMLRPC_IS_NUMBER(text[i+12])
|
||||
tm.tm_min += (text[i+12]-'0')*n;
|
||||
n /= 10;
|
||||
}
|
||||
|
@ -252,7 +255,7 @@ static int date_from_ISO8601 (const char *text, time_t * value) {
|
|||
n = 10;
|
||||
tm.tm_sec = 0;
|
||||
for(i = 0; i < 2; i++) {
|
||||
XMLRPC_IS_NUMBER(text[i])
|
||||
XMLRPC_IS_NUMBER(text[i+15])
|
||||
tm.tm_sec += (text[i+15]-'0')*n;
|
||||
n /= 10;
|
||||
}
|
||||
|
|
44
ext/xmlrpc/tests/bug68027.phpt
Normal file
44
ext/xmlrpc/tests/bug68027.phpt
Normal file
|
@ -0,0 +1,44 @@
|
|||
--TEST--
|
||||
Bug #68027 (buffer overflow in mkgmtime() function)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("xmlrpc")) print "skip";
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$d = '6-01-01 20:00:00';
|
||||
xmlrpc_set_type($d, 'datetime');
|
||||
var_dump($d);
|
||||
$datetime = "2001-0-08T21:46:40-0400";
|
||||
$obj = xmlrpc_decode("<?xml version=\"1.0\"?><methodResponse><params><param><value><dateTime.iso8601>$datetime</dateTime.iso8601></value></param></params></methodResponse>");
|
||||
print_r($obj);
|
||||
|
||||
$datetime = "34770-0-08T21:46:40-0400";
|
||||
$obj = xmlrpc_decode("<?xml version=\"1.0\"?><methodResponse><params><param><value><dateTime.iso8601>$datetime</dateTime.iso8601></value></param></params></methodResponse>");
|
||||
print_r($obj);
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
object(stdClass)#1 (3) {
|
||||
["scalar"]=>
|
||||
string(16) "6-01-01 20:00:00"
|
||||
["xmlrpc_type"]=>
|
||||
string(8) "datetime"
|
||||
["timestamp"]=>
|
||||
int(%d)
|
||||
}
|
||||
stdClass Object
|
||||
(
|
||||
[scalar] => 2001-0-08T21:46:40-0400
|
||||
[xmlrpc_type] => datetime
|
||||
[timestamp] => %s
|
||||
)
|
||||
stdClass Object
|
||||
(
|
||||
[scalar] => 34770-0-08T21:46:40-0400
|
||||
[xmlrpc_type] => datetime
|
||||
[timestamp] => %d
|
||||
)
|
||||
Done
|
Loading…
Add table
Add a link
Reference in a new issue