diff options
-rw-r--r-- | .appveyor.yml | 6 | ||||
-rw-r--r-- | NEWS | 7 | ||||
-rw-r--r-- | appveyor/build_task.bat | 15 | ||||
-rw-r--r-- | ext/mbstring/libmbfl/mbfl/mbfl_memory_device.c | 9 | ||||
-rw-r--r-- | ext/pdo/tests/bug_60665.phpt | 8 | ||||
-rw-r--r-- | ext/pdo_firebird/firebird_statement.c | 4 | ||||
-rw-r--r-- | ext/pdo_firebird/tests/bug_aaa.phpt | 19 | ||||
-rw-r--r-- | ext/reflection/php_reflection.c | 10 | ||||
-rw-r--r-- | ext/reflection/tests/bug46103.phpt | 18 | ||||
-rw-r--r-- | ext/standard/dns.c | 4 | ||||
-rw-r--r-- | ext/standard/dns_win32.c | 6 | ||||
-rw-r--r-- | ext/standard/tests/misc/get_browser_variation2.phpt | 94 | ||||
-rw-r--r-- | ext/standard/tests/network/bug73594.phpt | 26 | ||||
-rw-r--r-- | ext/standard/tests/network/bug73594a.phpt | 25 |
14 files changed, 232 insertions, 19 deletions
diff --git a/.appveyor.yml b/.appveyor.yml index 210130e9b8..9a05c6a65c 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,3 +1,6 @@ + +version: "{branch}.build.{build}" + image: Visual Studio 2015 clone_depth: 64 @@ -26,6 +29,9 @@ environment: - THREAD_SAFE: 1 OPCACHE: 1 +matrix: + fast_finish: true + services: # the setup scripts have to be touched, once some other db version is used - mysql @@ -35,6 +35,13 @@ PHP NEWS - Apache2handler: . Fixed bug #61471 (POST request timeout did not handle correctly). (Zheng SHAO) +- Reflection: + . Fixed bug #46103 (ReflectionObject memory leak). (Nikita) + +- Standard: + . Fixed bug #73594 (dns_get_record does not populate $additional out parameter). + (Bruce Weirdan) + 08 Dec 2016 PHP 7.0.14 - Core: diff --git a/appveyor/build_task.bat b/appveyor/build_task.bat index 52f049f744..cf5187738c 100644 --- a/appveyor/build_task.bat +++ b/appveyor/build_task.bat @@ -1,14 +1,14 @@ @echo off if "%APPVEYOR%" equ "True" rmdir /s /q C:\cygwin >NUL 2>NUL -if errorlevel 1 exit /b 1 +if %errorlevel% neq 0 exit /b 3 if "%APPVEYOR%" equ "True" rmdir /s /q C:\mingw >NUL 2>NUL -if errorlevel 1 exit /b 1 +if %errorlevel% neq 0 exit /b 3 if "%APPVEYOR%" equ "True" rmdir /s /q C:\mingw-w64 >NUL 2>NUL -if errorlevel 1 exit /b 1 +if %errorlevel% neq 0 exit /b 3 cd /D %APPVEYOR_BUILD_FOLDER% -if errorlevel 1 exit /b 1 +if %errorlevel% neq 0 exit /b 3 if /i "%APPVEYOR_REPO_BRANCH:~0,4%" equ "php-" ( set BRANCH=%APPVEYOR_REPO_BRANCH:~4% @@ -21,9 +21,10 @@ set DEPS_DIR=%PHP_BUILD_CACHE_BASE_DIR%\deps-%PHP_SDK_VC%-%PHP_SDK_ARCH%-%APPVEY rem SDK is cached, deps info is cached as well echo Updating dependencies call phpsdk_deps --update --branch %BRANCH% --stability %STABILITY% --deps %DEPS_DIR% +if %errorlevel% neq 0 exit /b 3 call buildconf.bat --force -if errorlevel 1 exit /b 1 +if %errorlevel% neq 0 exit /b 3 if "%THREAD_SAFE%" equ "0" set ADD_CONF=--disable-zts @@ -40,10 +41,10 @@ call configure.bat ^ --with-php-build=%DEPS_DIR% ^ %ADD_CONF% ^ --with-test-ini-ext-exclude=%EXT_EXCLUDE_FROM_TEST% -if errorlevel 1 exit /b 1 +if %errorlevel% neq 0 exit /b 3 nmake /NOLOGO -if errorlevel 1 exit /b 1 +if %errorlevel% neq 0 exit /b 3 exit /b 0 diff --git a/ext/mbstring/libmbfl/mbfl/mbfl_memory_device.c b/ext/mbstring/libmbfl/mbfl/mbfl_memory_device.c index c4d4e7fe37..eae05953b2 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfl_memory_device.c +++ b/ext/mbstring/libmbfl/mbfl/mbfl_memory_device.c @@ -239,11 +239,12 @@ mbfl_memory_device_strcat(mbfl_memory_device *device, const char *psrc) if ((device->pos + len) >= device->length) { /* reallocate buffer */ int newlen = device->length + (len + MBFL_MEMORY_DEVICE_ALLOC_SIZE)*sizeof(unsigned char); + unsigned char *tmp; if (newlen <= 0) { /* overflow */ return -1; } - unsigned char *tmp = (unsigned char *)mbfl_realloc((void *)device->buffer, newlen*sizeof(unsigned char)); + tmp = (unsigned char *)mbfl_realloc((void *)device->buffer, newlen*sizeof(unsigned char)); if (tmp == NULL) { return -1; } @@ -270,11 +271,12 @@ mbfl_memory_device_strncat(mbfl_memory_device *device, const char *psrc, int len if ((device->pos + len) >= device->length) { /* reallocate buffer */ int newlen = device->length + len + MBFL_MEMORY_DEVICE_ALLOC_SIZE; + unsigned char *tmp; if (newlen <= 0) { /* overflow */ return -1; } - unsigned char *tmp = (unsigned char *)mbfl_realloc((void *)device->buffer, newlen*sizeof(unsigned char)); + tmp = (unsigned char *)mbfl_realloc((void *)device->buffer, newlen*sizeof(unsigned char)); if (tmp == NULL) { return -1; } @@ -301,11 +303,12 @@ mbfl_memory_device_devcat(mbfl_memory_device *dest, mbfl_memory_device *src) if ((dest->pos + src->pos) >= dest->length) { /* reallocate buffer */ int newlen = dest->length + src->pos + MBFL_MEMORY_DEVICE_ALLOC_SIZE; + unsigned char *tmp; if (newlen <= 0) { /* overflow */ return -1; } - unsigned char *tmp = (unsigned char *)mbfl_realloc((void *)dest->buffer, newlen*sizeof(unsigned char)); + tmp = (unsigned char *)mbfl_realloc((void *)dest->buffer, newlen*sizeof(unsigned char)); if (tmp == NULL) { return -1; } diff --git a/ext/pdo/tests/bug_60665.phpt b/ext/pdo/tests/bug_60665.phpt index 28c1482154..bae3d603d7 100644 --- a/ext/pdo/tests/bug_60665.phpt +++ b/ext/pdo/tests/bug_60665.phpt @@ -13,8 +13,12 @@ PDOTest::skip(); if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.dirname(__FILE__) . '/../../pdo/tests/'); require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc'; $db = PDOTest::factory(); - -$statement = $db->prepare("SELECT NULL AS null_value, 0 AS zero, 1 AS one"); +switch ($db->getAttribute(PDO::ATTR_DRIVER_NAME)) { + case 'oci': $from = 'from dual'; break; + case 'firebird': $from = 'from rdb$database'; break; + default: $from = ''; break; +} +$statement = $db->prepare("SELECT NULL AS null_value, 0 AS zero, 1 AS one $from"); $statement->execute(); $row = $statement->fetch(PDO::FETCH_LAZY); var_dump( diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c index f719ecc36d..64968428bd 100644 --- a/ext/pdo_firebird/firebird_statement.c +++ b/ext/pdo_firebird/firebird_statement.c @@ -152,8 +152,8 @@ static int firebird_stmt_execute(pdo_stmt_t *stmt) /* {{{ */ } *S->name = 0; - S->cursor_open = (S->out_sqlda.sqln > 0); /* A cursor is opened, when more than zero columns returned */ - S->exhausted = !S->cursor_open; + S->cursor_open = S->out_sqlda.sqln && (S->statement_type != isc_info_sql_stmt_exec_procedure); + S->exhausted = !S->out_sqlda.sqln; /* There are data to fetch */ return 1; } while (0); diff --git a/ext/pdo_firebird/tests/bug_aaa.phpt b/ext/pdo_firebird/tests/bug_aaa.phpt new file mode 100644 index 0000000000..821d59afd2 --- /dev/null +++ b/ext/pdo_firebird/tests/bug_aaa.phpt @@ -0,0 +1,19 @@ +--TEST-- +PDO_Firebird: cursor should not be marked as opened on singleton statements +--SKIPIF-- +<?php if (!extension_loaded('interbase') || !extension_loaded('pdo_firebird')) die('skip'); ?> +--FILE-- +<?php +require 'testdb.inc'; +$C = new PDO('firebird:dbname='.$test_base, $user, $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING]) or die; +@$C->exec('drop table ta_table'); +$C->exec('create table ta_table (id integer)'); +$S = $C->prepare('insert into ta_table (id) values (:id) returning id'); +$S->execute(['id' => 1]); +$S->execute(['id' => 2]); +unset($S); +unset($C); +echo 'OK'; +?> +--EXPECT-- +OK
\ No newline at end of file diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index b24f9c691d..1c13aa5090 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -344,6 +344,15 @@ static void reflection_free_objects_storage(zend_object *object) /* {{{ */ } /* }}} */ +static HashTable *reflection_get_gc(zval *obj, zval **gc_data, int *gc_data_count) /* {{{ */ +{ + reflection_object *intern = Z_REFLECTION_P(obj); + *gc_data = &intern->obj; + *gc_data_count = 1; + return zend_std_get_properties(obj); +} +/* }}} */ + static zend_object *reflection_objects_new(zend_class_entry *class_type) /* {{{ */ { reflection_object *intern; @@ -6524,6 +6533,7 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ reflection_object_handlers.free_obj = reflection_free_objects_storage; reflection_object_handlers.clone_obj = NULL; reflection_object_handlers.write_property = _reflection_write_property; + reflection_object_handlers.get_gc = reflection_get_gc; INIT_CLASS_ENTRY(_reflection_entry, "ReflectionException", reflection_exception_functions); reflection_exception_ptr = zend_register_internal_class_ex(&_reflection_entry, zend_ce_exception); diff --git a/ext/reflection/tests/bug46103.phpt b/ext/reflection/tests/bug46103.phpt new file mode 100644 index 0000000000..978a9c2c46 --- /dev/null +++ b/ext/reflection/tests/bug46103.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #46103: ReflectionObject memory leak +--FILE-- +<?php + +$obj = new stdClass; +$obj->r = new ReflectionObject($obj); +var_dump($obj); + +?> +--EXPECT-- +object(stdClass)#1 (1) { + ["r"]=> + object(ReflectionObject)#2 (1) { + ["name"]=> + string(8) "stdClass" + } +} diff --git a/ext/standard/dns.c b/ext/standard/dns.c index de40649e69..de277a3035 100644 --- a/ext/standard/dns.c +++ b/ext/standard/dns.c @@ -761,7 +761,7 @@ static u_char *php_parserr(u_char *cp, u_char *end, querybuf *answer, int type_t } /* }}} */ -/* {{{ proto array|false dns_get_record(string hostname [, int type[, array authns, array addtl]]) +/* {{{ proto array|false dns_get_record(string hostname [, int type[, array &authns[, array &addtl[, bool raw]]]]) Get any Resource Record corresponding to a given Internet host name */ PHP_FUNCTION(dns_get_record) { @@ -785,7 +785,7 @@ PHP_FUNCTION(dns_get_record) int type, first_query = 1, store_results = 1; zend_bool raw = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|lz!z!b", + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|lz/!z/!b", &hostname, &hostname_len, &type_param, &authns, &addtl, &raw) == FAILURE) { return; } diff --git a/ext/standard/dns_win32.c b/ext/standard/dns_win32.c index f28977ab6a..d63bfd6a66 100644 --- a/ext/standard/dns_win32.c +++ b/ext/standard/dns_win32.c @@ -341,18 +341,18 @@ static void php_parserr(PDNS_RECORD pRec, int type_to_fetch, int store, int raw, } /* }}} */ -/* {{{ proto array|false dns_get_record(string hostname [, int type[, array authns, array addtl]]) +/* {{{ proto array|false dns_get_record(string hostname [, int type[, array &authns[, array &addtl[, bool raw]]]]) Get any Resource Record corresponding to a given Internet host name */ PHP_FUNCTION(dns_get_record) { char *hostname; size_t hostname_len; - long type_param = PHP_DNS_ANY; + zend_long type_param = PHP_DNS_ANY; zval *authns = NULL, *addtl = NULL; int type, type_to_fetch, first_query = 1, store_results = 1; zend_bool raw = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|lz!z!b", + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|lz/!z/!b", &hostname, &hostname_len, &type_param, &authns, &addtl, &raw) == FAILURE) { return; } diff --git a/ext/standard/tests/misc/get_browser_variation2.phpt b/ext/standard/tests/misc/get_browser_variation2.phpt new file mode 100644 index 0000000000..5c4d2ecd6e --- /dev/null +++ b/ext/standard/tests/misc/get_browser_variation2.phpt @@ -0,0 +1,94 @@ +--TEST-- +Test get_browser() function variation : Return data as object +--INI-- +browscap={PWD}/browscap.ini +--SKIPIF-- +<?php + /** + * Basic test, it would be pretty much coincidence if there's + * a browscap.ini on another place that isn't valid. + */ + if(! is_readable( ini_get( 'browscap' ) ) ) { + die( 'skip: browscap.ini file ' . ini_get('browscap') . " not readable" ); + } +?> +--FILE-- +<?php + +$agent = "Opera/7.11 (Windows NT 5.1; U) [en]"; +var_dump(get_browser($agent)); + +?> +--EXPECT-- +object(stdClass)#1 (35) { + ["browser_name_regex"]=> + string(41) "~^opera/7\.1.* \(windows nt 5\.1; .\).*$~" + ["browser_name_pattern"]=> + string(31) "Opera/7.1* (Windows NT 5.1; ?)*" + ["parent"]=> + string(9) "Opera 7.1" + ["platform"]=> + string(5) "WinXP" + ["win32"]=> + string(1) "1" + ["browser"]=> + string(5) "Opera" + ["version"]=> + string(3) "7.1" + ["majorver"]=> + string(1) "7" + ["minorver"]=> + string(1) "1" + ["frames"]=> + string(1) "1" + ["iframes"]=> + string(1) "1" + ["tables"]=> + string(1) "1" + ["cookies"]=> + string(1) "1" + ["backgroundsounds"]=> + string(1) "1" + ["javaapplets"]=> + string(1) "1" + ["javascript"]=> + string(1) "1" + ["css"]=> + string(1) "2" + ["cssversion"]=> + string(1) "2" + ["supportscss"]=> + string(1) "1" + ["alpha"]=> + string(0) "" + ["beta"]=> + string(0) "" + ["win16"]=> + string(0) "" + ["win64"]=> + string(0) "" + ["authenticodeupdate"]=> + string(0) "" + ["cdf"]=> + string(0) "" + ["vbscript"]=> + string(0) "" + ["activexcontrols"]=> + string(0) "" + ["stripper"]=> + string(0) "" + ["isbanned"]=> + string(0) "" + ["wap"]=> + string(0) "" + ["ismobiledevice"]=> + string(0) "" + ["issyndicationreader"]=> + string(0) "" + ["crawler"]=> + string(0) "" + ["aol"]=> + string(0) "" + ["aolversion"]=> + string(1) "0" +} diff --git a/ext/standard/tests/network/bug73594.phpt b/ext/standard/tests/network/bug73594.phpt new file mode 100644 index 0000000000..a3068360ce --- /dev/null +++ b/ext/standard/tests/network/bug73594.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #73594 (dns_get_record() does not populate $additional out parameter) +--SKIPIF-- +<?php +if (getenv("SKIP_ONLINE_TESTS")) die("skip test requiring internet connection"); + +$out = array(); +$ret = 0; +exec("dig -tmx php.net +noall +additional 2>/dev/null", $out, $ret); + +if ($ret != 0) die("skip dig command is not present or failed to run"); + +// skip empty and header lines +$out = preg_grep("/^(?!($|;))/", $out); + +if (empty($out)) die("skip local resolver does not return additional records"); +?> +--FILE-- +<?php +$auth = array(); +$additional = array(); +dns_get_record('php.net', DNS_MX, $auth, $additional); +var_dump(empty($additional)); +?> +--EXPECT-- +bool(false) diff --git a/ext/standard/tests/network/bug73594a.phpt b/ext/standard/tests/network/bug73594a.phpt new file mode 100644 index 0000000000..a0a08e4a9e --- /dev/null +++ b/ext/standard/tests/network/bug73594a.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #73594 (dns_get_record() does not populate $additional out parameter - $authns parameter) +--SKIPIF-- +<?php +if (getenv("SKIP_ONLINE_TESTS")) die("skip test requiring internet connection"); + +$out = array(); +$ret = 0; +exec("dig -tmx php.net +noall +authority 2>/dev/null", $out, $ret); + +if ($ret != 0) die("skip dig command is not present or failed to run"); + +// skip empty and header lines +$out = preg_grep("/^(?!($|;))/", $out); + +if (empty($out)) die("skip local resolver does not return authority records"); +?> +--FILE-- +<?php +$auth = array(); +dns_get_record('php.net', DNS_MX, $auth); +var_dump(empty($auth)); +?> +--EXPECT-- +bool(false) |