diff options
author | Anatol Belski <ab@php.net> | 2014-10-15 08:32:54 +0200 |
---|---|---|
committer | Anatol Belski <ab@php.net> | 2014-10-15 08:32:54 +0200 |
commit | 382f95e6127d52b079d172ccd017cf306402e015 (patch) | |
tree | dcc5d8f6f2b1390a3d93a5be5994d625d260bfd9 | |
parent | 766eb0103fe8f59c00ddadc5c5767093ee35b2e8 (diff) | |
parent | 01d17228dc62ea30b7ad25835f049ccd1998b5f2 (diff) | |
download | php-git-382f95e6127d52b079d172ccd017cf306402e015.tar.gz |
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
...
-rw-r--r-- | Zend/zend_alloc.c | 173 | ||||
-rw-r--r-- | Zend/zend_alloc.h | 21 | ||||
-rw-r--r-- | ext/curl/interface.c | 5 | ||||
-rw-r--r-- | ext/curl/tests/bug68089.phpt | 18 | ||||
-rw-r--r-- | ext/exif/exif.c | 4 | ||||
-rwxr-xr-x | ext/exif/tests/bug68113.jpg | bin | 0 -> 368 bytes | |||
-rw-r--r-- | ext/exif/tests/bug68113.phpt | 17 | ||||
-rw-r--r-- | ext/gmp/gmp.c | 118 | ||||
-rw-r--r-- | ext/gmp/php_gmp.h | 2 | ||||
-rw-r--r-- | ext/gmp/tests/gmp_random_bits.phpt | 45 | ||||
-rw-r--r-- | ext/gmp/tests/gmp_random_range.phpt | 81 | ||||
-rw-r--r-- | ext/spl/spl_engine.h | 30 | ||||
-rw-r--r-- | ext/spl/spl_iterators.c | 43 | ||||
-rw-r--r-- | ext/spl/tests/bug68128.phpt | 91 | ||||
-rw-r--r-- | ext/spl/tests/iterator_048.phpt | 5 | ||||
-rw-r--r-- | ext/spl/tests/iterator_050.phpt | 4 | ||||
-rw-r--r-- | ext/spl/tests/iterator_052.phpt | 146 | ||||
-rw-r--r-- | ext/spl/tests/iterator_053.phpt | 125 | ||||
-rw-r--r-- | ext/spl/tests/iterator_054.phpt | 2 | ||||
-rw-r--r-- | ext/standard/tests/serialize/bug68044.phpt | 12 | ||||
-rw-r--r-- | ext/standard/var_unserializer.c | 2 | ||||
-rw-r--r-- | ext/standard/var_unserializer.re | 2 | ||||
-rw-r--r-- | ext/xmlrpc/libxmlrpc/xmlrpc.c | 13 | ||||
-rw-r--r-- | ext/xmlrpc/tests/bug68027.phpt | 44 |
24 files changed, 686 insertions, 317 deletions
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index aea04d82f0..fb4d3b35e1 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -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)) { @@ -1707,6 +1747,9 @@ zend_mm_heap *zend_mm_init(void) #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 diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h index 6d310cbca3..c9918955ab 100644 --- a/Zend/zend_alloc.h +++ b/Zend/zend_alloc.h @@ -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() diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 5c4a8800a3..079c8d7070 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.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 diff --git a/ext/curl/tests/bug68089.phpt b/ext/curl/tests/bug68089.phpt new file mode 100644 index 0000000000..3bd5889709 --- /dev/null +++ b/ext/curl/tests/bug68089.phpt @@ -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 diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 42f8a24102..06e1dae41a 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -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; } diff --git a/ext/exif/tests/bug68113.jpg b/ext/exif/tests/bug68113.jpg Binary files differnew file mode 100755 index 0000000000..3ce7a620fb --- /dev/null +++ b/ext/exif/tests/bug68113.jpg diff --git a/ext/exif/tests/bug68113.phpt b/ext/exif/tests/bug68113.phpt new file mode 100644 index 0000000000..0fa4c4aca8 --- /dev/null +++ b/ext/exif/tests/bug68113.phpt @@ -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
\ No newline at end of file diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index b5c18ecb37..de294049c4 100644 --- a/ext/gmp/gmp.c +++ b/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) diff --git a/ext/gmp/php_gmp.h b/ext/gmp/php_gmp.h index 59485dd5b7..f9bc0f3269 100644 --- a/ext/gmp/php_gmp.h +++ b/ext/gmp/php_gmp.h @@ -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); diff --git a/ext/gmp/tests/gmp_random_bits.phpt b/ext/gmp/tests/gmp_random_bits.phpt new file mode 100644 index 0000000000..21d493cdb6 --- /dev/null +++ b/ext/gmp/tests/gmp_random_bits.phpt @@ -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 diff --git a/ext/gmp/tests/gmp_random_range.phpt b/ext/gmp/tests/gmp_random_range.phpt new file mode 100644 index 0000000000..a8e7c4a9c1 --- /dev/null +++ b/ext/gmp/tests/gmp_random_range.phpt @@ -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 diff --git a/ext/spl/spl_engine.h b/ext/spl/spl_engine.h index a621355ba4..8fa5539ba5 100644 --- a/ext/spl/spl_engine.h +++ b/ext/spl/spl_engine.h @@ -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 */ /* diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index f47093bf4c..8b09e3ef37 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -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 diff --git a/ext/spl/tests/bug68128.phpt b/ext/spl/tests/bug68128.phpt new file mode 100644 index 0000000000..ff41dd4931 --- /dev/null +++ b/ext/spl/tests/bug68128.phpt @@ -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 + ) + +) + diff --git a/ext/spl/tests/iterator_048.phpt b/ext/spl/tests/iterator_048.phpt index bad4e7888a..64ca97f4d6 100644 --- a/ext/spl/tests/iterator_048.phpt +++ b/ext/spl/tests/iterator_048.phpt @@ -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')); diff --git a/ext/spl/tests/iterator_050.phpt b/ext/spl/tests/iterator_050.phpt index fed4a3b2ee..63d8fbfa9a 100644 --- a/ext/spl/tests/iterator_050.phpt +++ b/ext/spl/tests/iterator_050.phpt @@ -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) { diff --git a/ext/spl/tests/iterator_052.phpt b/ext/spl/tests/iterator_052.phpt index c68bd5234d..84b3eb993c 100644 --- a/ext/spl/tests/iterator_052.phpt +++ b/ext/spl/tests/iterator_052.phpt @@ -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(true) -int(5) -array(2) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } -} +bool(false) 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) { diff --git a/ext/spl/tests/iterator_053.phpt b/ext/spl/tests/iterator_053.phpt index 5d9c740c31..b472523ab6 100644 --- a/ext/spl/tests/iterator_053.phpt +++ b/ext/spl/tests/iterator_053.phpt @@ -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(true) -int(5) -array(3) { - [0]=> - array(0) { - } - [1]=> - array(0) { - } - [2]=> - array(0) { - } -} +bool(false) 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) { diff --git a/ext/spl/tests/iterator_054.phpt b/ext/spl/tests/iterator_054.phpt index 1f1cd580c1..91266c9571 100644 --- a/ext/spl/tests/iterator_054.phpt +++ b/ext/spl/tests/iterator_054.phpt @@ -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]=> diff --git a/ext/standard/tests/serialize/bug68044.phpt b/ext/standard/tests/serialize/bug68044.phpt new file mode 100644 index 0000000000..031e44e149 --- /dev/null +++ b/ext/standard/tests/serialize/bug68044.phpt @@ -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== diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c index c94f3eec58..9be2b0658a 100644 --- a/ext/standard/var_unserializer.c +++ b/ext/standard/var_unserializer.c @@ -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; } diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index a11f556f7e..1898c7734c 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -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; } diff --git a/ext/xmlrpc/libxmlrpc/xmlrpc.c b/ext/xmlrpc/libxmlrpc/xmlrpc.c index 0f77ae2451..fed73bbfa8 100644 --- a/ext/xmlrpc/libxmlrpc/xmlrpc.c +++ b/ext/xmlrpc/libxmlrpc/xmlrpc.c @@ -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; } diff --git a/ext/xmlrpc/tests/bug68027.phpt b/ext/xmlrpc/tests/bug68027.phpt new file mode 100644 index 0000000000..a5c96f1cf2 --- /dev/null +++ b/ext/xmlrpc/tests/bug68027.phpt @@ -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 |