summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.appveyor.yml6
-rw-r--r--NEWS7
-rw-r--r--appveyor/build_task.bat15
-rw-r--r--ext/mbstring/libmbfl/mbfl/mbfl_memory_device.c9
-rw-r--r--ext/pdo/tests/bug_60665.phpt8
-rw-r--r--ext/pdo_firebird/firebird_statement.c4
-rw-r--r--ext/pdo_firebird/tests/bug_aaa.phpt19
-rw-r--r--ext/reflection/php_reflection.c10
-rw-r--r--ext/reflection/tests/bug46103.phpt18
-rw-r--r--ext/standard/dns.c4
-rw-r--r--ext/standard/dns_win32.c6
-rw-r--r--ext/standard/tests/misc/get_browser_variation2.phpt94
-rw-r--r--ext/standard/tests/network/bug73594.phpt26
-rw-r--r--ext/standard/tests/network/bug73594a.phpt25
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
diff --git a/NEWS b/NEWS
index 9649a255b7..b79be92f36 100644
--- a/NEWS
+++ b/NEWS
@@ -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)