summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRasmus Lerdorf <rasmus@php.net>2014-11-06 10:19:45 -0800
committerRasmus Lerdorf <rasmus@php.net>2014-11-06 10:19:45 -0800
commit2375d659d7ba006429d4b3a28cf8a158f24b30db (patch)
tree608223966abbd29a02080b3cd99ca4847149c10a
parent50756b515c76bb9c43a01bfce03207906f596005 (diff)
parent8fccf0bac9eab67412612b2df14da58b9129c6b2 (diff)
downloadphp-git-2375d659d7ba006429d4b3a28cf8a158f24b30db.tar.gz
Merge branch 'PHP-5.6' of git.php.net:php-src into PHP-5.6
* 'PHP-5.6' of git.php.net:php-src: (142 commits) Fixed bug #68351 (PDO::PARAM_BOOL and ATTR_EMULATE_PREPARES misbehaving) Update NEWS Fixed bug #68331 - This was partial patch for https://wiki.php.net/rfc/session-lock-ini fix dir separator in test arg1-3 are not variable names to use; removed useless buffer variable update NEWS Fix bug #63595 GMP memory management conflicts with other libraries using GMP Initialize the offset table - PCRE may sometimes miss offsets set default response code to 200 set default response code to 200 set default response code to 200 Fixed bug #66584 Segmentation fault on statement deallocation Add credit fix ZTS build Added PGSQL_TEST_CONNSTR env var support for ext/pgsql tests Fixed bug #67462 PDO_PGSQL::beginTransaction() wrongly throws exception when not in transaction Fixed Bug #68104 (Segfault while pre-evaluating a disabled function) Temporarily disable wait/xml protocol... don't try to send in the test results until we restored qa.php.net Fix uninitialized value... ...
-rw-r--r--.travis.yml2
-rw-r--r--NEWS26
-rw-r--r--Zend/zend_API.c15
-rw-r--r--configure.in2
-rw-r--r--ext/curl/tests/bug68089.phpt2
-rw-r--r--ext/gmp/gmp.c26
-rw-r--r--ext/opcache/tests/bug68104.phpt19
-rw-r--r--ext/pcre/php_pcre.c2
-rw-r--r--ext/pdo_pgsql/pgsql_driver.c28
-rw-r--r--ext/pdo_pgsql/pgsql_statement.c3
-rw-r--r--ext/pdo_pgsql/tests/bug62593.phpt15
-rw-r--r--ext/pdo_pgsql/tests/bug66584.phpt66
-rw-r--r--ext/pdo_pgsql/tests/bug67462.phpt34
-rw-r--r--ext/pgsql/tests/config.inc10
-rw-r--r--ext/session/session.c17
-rw-r--r--ext/session/tests/session_set_save_handler_write_short_circuit.phpt1
-rw-r--r--ext/standard/basic_functions.c4
-rw-r--r--ext/standard/basic_functions.h4
-rw-r--r--ext/standard/file.c114
-rw-r--r--ext/standard/tests/file/bug52820.phpt134
-rw-r--r--ext/xmlrpc/libxmlrpc/xmlrpc.c6
-rw-r--r--main/getopt.c8
-rw-r--r--main/output.c2
-rw-r--r--main/php_main.h3
-rw-r--r--main/php_output.h2
-rw-r--r--main/php_version.h6
-rwxr-xr-xrun-tests.php5
-rw-r--r--sapi/litespeed/lsapi_main.c4
-rw-r--r--sapi/phpdbg/config.m410
-rw-r--r--sapi/phpdbg/config.w325
-rw-r--r--sapi/phpdbg/phpdbg.c88
-rw-r--r--sapi/phpdbg/phpdbg.h13
-rw-r--r--sapi/phpdbg/phpdbg_bp.c210
-rw-r--r--sapi/phpdbg/phpdbg_bp.h4
-rw-r--r--sapi/phpdbg/phpdbg_frame.c1
-rw-r--r--sapi/phpdbg/phpdbg_help.c2
-rw-r--r--sapi/phpdbg/phpdbg_io.c4
-rw-r--r--sapi/phpdbg/phpdbg_out.c16
-rw-r--r--sapi/phpdbg/phpdbg_prompt.c200
-rw-r--r--sapi/phpdbg/phpdbg_prompt.h1
-rw-r--r--sapi/phpdbg/phpdbg_rinit_hook.c6
-rw-r--r--sapi/phpdbg/phpdbg_sigio_win32.c25
-rw-r--r--sapi/phpdbg/phpdbg_sigio_win32.h2
-rw-r--r--sapi/phpdbg/phpdbg_wait.c22
-rw-r--r--sapi/phpdbg/phpdbg_webdata_transfer.c22
45 files changed, 710 insertions, 481 deletions
diff --git a/.travis.yml b/.travis.yml
index 2125e8d3d6..f0a6f257d5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -42,5 +42,5 @@ before_script:
# Run PHPs run-tests.php
script:
- - ./sapi/cli/php run-tests.php -p `pwd`/sapi/cli/php -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --show-diff --set-timeout 120
+ - ./sapi/cli/php run-tests.php -p `pwd`/sapi/cli/php -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --show-diff --set-timeout 120 -s
- ./sapi/cli/php sapi/phpdbg/tests/run-tests.php -diff2stdout --phpdbg sapi/phpdbg/phpdbg
diff --git a/NEWS b/NEWS
index 2b68ac1493..b02976cb0f 100644
--- a/NEWS
+++ b/NEWS
@@ -1,19 +1,27 @@
PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+?? ??? 2014, PHP 5.6.4
+
+
+
?? ??? 2014, PHP 5.6.3
- Core:
- . Fixed bug #67739 (Windows 8.1/Server 2012 R2 OS build number reported
- as 6.2 (instead of 6.3)). (Christian Wenz)
+ . Fixed bug #68104 (Segfault while pre-evaluating a disabled function).
+ (Laruence)
+ . Implemented 64-bit format codes for pack() and unpack(). (Leigh)
+ . Fixed bug #51800 (proc_open on Windows hangs forever). (Anatol)
. Fixed bug #67633 (A foreach on an array returned from a function not doing
copy-on-write). (Nikita)
- . Fixed bug #51800 (proc_open on Windows hangs forever). (Anatol)
+ . Fixed bug #67739 (Windows 8.1/Server 2012 R2 OS build number reported
+ as 6.2 (instead of 6.3)). (Christian Wenz)
+ . Fixed bug #67949 (DOMNodeList elements should be accessible through
+ array notation) (Florian)
+ . Fixed bug #68095 (AddressSanitizer reports a heap buffer overflow in
+ php_getopt()). (Stas)
. Fixed bug #68118 ($a->foo .= 'test'; can leave $a->foo undefined). (Nikita)
. Fixed bug #68129 (parse_url() - incomplete support for empty usernames
and passwords) (Tjerk)
- . Fixed bug #67949 (DOMNodeList elements should be accessible through
- array notation) (Florian)
- . Implemented 64-bit format codes for pack() and unpack(). (Leigh)
- phpdbg:
. Added XML protocol (-x command line flag). (Bob)
@@ -37,6 +45,8 @@ PHP NEWS
- GMP:
. Implemented gmp_random_range() and gmp_random_bits(). (Leigh)
+ . Fixed bug #63595 (GMP memory management conflicts with other libraries
+ using GMP). (Remi)
- Reflection:
. Fixed bug #68103 (Duplicate entry in Reflection for class alias). (Remi)
@@ -53,6 +63,10 @@ PHP NEWS
. Fixed bug #68087 (ODBC not correctly reading DATE column when preceded by
a VARCHAR column) (Keyur Govande)
+- Session:
+ . Fixed bug #68331 (Session custom storage callable functions not being called)
+ (Yasuo Ohgaki)
+
- SPL:
. Fixed bug #68128 (Regression in RecursiveRegexIterator) (Tjerk)
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 8472cd7ab1..a465721f1f 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -2635,18 +2635,15 @@ ZEND_API ZEND_FUNCTION(display_disabled_function)
}
/* }}} */
-static zend_function_entry disabled_function[] = {
- ZEND_FE(display_disabled_function, NULL)
- ZEND_FE_END
-};
-
ZEND_API int zend_disable_function(char *function_name, uint function_name_length TSRMLS_DC) /* {{{ */
{
- if (zend_hash_del(CG(function_table), function_name, function_name_length+1)==FAILURE) {
- return FAILURE;
+ zend_internal_function *func;
+ if (zend_hash_find(CG(function_table), function_name, function_name_length+1, (void **)&func)==SUCCESS) {
+ func->arg_info = NULL;
+ func->handler = ZEND_FN(display_disabled_function);
+ return SUCCESS;
}
- disabled_function[0].fname = function_name;
- return zend_register_functions(NULL, disabled_function, CG(function_table), MODULE_PERSISTENT TSRMLS_CC);
+ return FAILURE;
}
/* }}} */
diff --git a/configure.in b/configure.in
index 8eb08baa3e..096f20c3f2 100644
--- a/configure.in
+++ b/configure.in
@@ -119,7 +119,7 @@ int zend_sprintf(char *buffer, const char *format, ...);
PHP_MAJOR_VERSION=5
PHP_MINOR_VERSION=6
-PHP_RELEASE_VERSION=3
+PHP_RELEASE_VERSION=4
PHP_EXTRA_VERSION="-dev"
PHP_VERSION="$PHP_MAJOR_VERSION.$PHP_MINOR_VERSION.$PHP_RELEASE_VERSION$PHP_EXTRA_VERSION"
PHP_VERSION_ID=`expr [$]PHP_MAJOR_VERSION \* 10000 + [$]PHP_MINOR_VERSION \* 100 + [$]PHP_RELEASE_VERSION`
diff --git a/ext/curl/tests/bug68089.phpt b/ext/curl/tests/bug68089.phpt
index 3bd5889709..d65441b2cc 100644
--- a/ext/curl/tests/bug68089.phpt
+++ b/ext/curl/tests/bug68089.phpt
@@ -13,6 +13,6 @@ 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
+Warning: curl_setopt(): Curl option contains invalid characters (\0) in %s%ebug68089.php on line 4
bool(false)
Done
diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c
index 8aff2d6b23..e9c1ad3416 100644
--- a/ext/gmp/gmp.c
+++ b/ext/gmp/gmp.c
@@ -363,30 +363,6 @@ static inline void gmp_zval_unary_ui_op(zval *return_value, zval *a_arg, gmp_una
#define gmp_unary_opl(op) _gmp_unary_opl(INTERNAL_FUNCTION_PARAM_PASSTHRU, op)
#define gmp_unary_ui_op(op) _gmp_unary_ui_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op)
-/* {{{ gmp_emalloc
- */
-static void *gmp_emalloc(size_t size)
-{
- return emalloc(size);
-}
-/* }}} */
-
-/* {{{ gmp_erealloc
- */
-static void *gmp_erealloc(void *ptr, size_t old_size, size_t new_size)
-{
- return erealloc(ptr, new_size);
-}
-/* }}} */
-
-/* {{{ gmp_efree
- */
-static void gmp_efree(void *ptr, size_t size)
-{
- efree(ptr);
-}
-/* }}} */
-
static inline long gmp_get_long(zval *zv) /* {{{ */
{
if (Z_TYPE_P(zv) == IS_LONG) {
@@ -734,8 +710,6 @@ ZEND_MINIT_FUNCTION(gmp)
REGISTER_LONG_CONSTANT("GMP_BIG_ENDIAN", GMP_BIG_ENDIAN, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("GMP_NATIVE_ENDIAN", GMP_NATIVE_ENDIAN, CONST_CS | CONST_PERSISTENT);
- mp_set_memory_functions(gmp_emalloc, gmp_erealloc, gmp_efree);
-
return SUCCESS;
}
/* }}} */
diff --git a/ext/opcache/tests/bug68104.phpt b/ext/opcache/tests/bug68104.phpt
new file mode 100644
index 0000000000..8d3bf70a4d
--- /dev/null
+++ b/ext/opcache/tests/bug68104.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Bug #68104 (Segfault while pre-evaluating a disabled function)
+--CREDITS--
+manuel <manuel@mausz.at>
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+disable_functions=dl
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+var_dump(is_callable("dl"));
+dl("a.so");
+?>
+--EXPECTF--
+bool(true)
+
+Warning: dl() has been disabled for security reasons in %sbug68104.php on line %d
diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c
index 52d43ced30..55aa3de2e5 100644
--- a/ext/pcre/php_pcre.c
+++ b/ext/pcre/php_pcre.c
@@ -646,7 +646,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec
}
offsets = (int *)safe_emalloc(size_offsets, sizeof(int), 0);
-
+ memset(offsets, 0, size_offsets*sizeof(int));
/* Allocate match sets array and initialize the values. */
if (global && subpats && subpats_order == PREG_PATTERN_ORDER) {
match_sets = (zval **)safe_emalloc(num_subpats, sizeof(zval *), 0);
diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c
index 657218d00e..f347aaa0e4 100644
--- a/ext/pdo_pgsql/pgsql_driver.c
+++ b/ext/pdo_pgsql/pgsql_driver.c
@@ -465,6 +465,15 @@ static int pdo_pgsql_check_liveness(pdo_dbh_t *dbh TSRMLS_DC)
}
/* }}} */
+static int pgsql_handle_in_transaction(pdo_dbh_t *dbh TSRMLS_DC)
+{
+ pdo_pgsql_db_handle *H;
+
+ H = (pdo_pgsql_db_handle *)dbh->driver_data;
+
+ return PQtransactionStatus(H->server) > PQTRANS_IDLE;
+}
+
static int pdo_pgsql_transaction_cmd(const char *cmd, pdo_dbh_t *dbh TSRMLS_DC)
{
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
@@ -489,7 +498,15 @@ static int pgsql_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
static int pgsql_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
{
- return pdo_pgsql_transaction_cmd("COMMIT", dbh TSRMLS_CC);
+ int ret = pdo_pgsql_transaction_cmd("COMMIT", dbh TSRMLS_CC);
+
+ /* When deferred constraints are used the commit could
+ fail, and a ROLLBACK implicitly ran. See bug #67462 */
+ if (!ret) {
+ dbh->in_txn = pgsql_handle_in_transaction(dbh TSRMLS_CC);
+ }
+
+ return ret;
}
static int pgsql_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
@@ -497,15 +514,6 @@ static int pgsql_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
return pdo_pgsql_transaction_cmd("ROLLBACK", dbh TSRMLS_CC);
}
-static int pgsql_handle_in_transaction(pdo_dbh_t *dbh TSRMLS_DC)
-{
- pdo_pgsql_db_handle *H;
-
- H = (pdo_pgsql_db_handle *)dbh->driver_data;
-
- return PQtransactionStatus(H->server);
-}
-
/* {{{ proto string PDO::pgsqlCopyFromArray(string $table_name , array $rows [, string $delimiter [, string $null_as ] [, string $fields])
Returns true if the copy worked fine or false if error */
static PHP_METHOD(PDO, pgsqlCopyFromArray)
diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c
index 35e69a3c02..2656586856 100644
--- a/ext/pdo_pgsql/pgsql_statement.c
+++ b/ext/pdo_pgsql/pgsql_statement.c
@@ -297,7 +297,7 @@ static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *
sizeof(Oid));
}
if (param->paramno >= 0) {
- if (param->paramno > zend_hash_num_elements(stmt->bound_param_map)) {
+ if (param->paramno >= zend_hash_num_elements(stmt->bound_param_map)) {
pdo_pgsql_error_stmt(stmt, PGRES_FATAL_ERROR, "HY105");
return 0;
}
@@ -371,6 +371,7 @@ static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *
((param->param_type & PDO_PARAM_INPUT_OUTPUT) != PDO_PARAM_INPUT_OUTPUT)) {
SEPARATE_ZVAL(&param->parameter);
param->param_type = PDO_PARAM_STR;
+ convert_to_boolean(param->parameter);
ZVAL_STRINGL(param->parameter, Z_BVAL_P(param->parameter) ? "t" : "f", 1, 1);
}
}
diff --git a/ext/pdo_pgsql/tests/bug62593.phpt b/ext/pdo_pgsql/tests/bug62593.phpt
index e3ebf46ed5..4ab4566f00 100644
--- a/ext/pdo_pgsql/tests/bug62593.phpt
+++ b/ext/pdo_pgsql/tests/bug62593.phpt
@@ -34,6 +34,19 @@ $query->execute();
$errors[] = $query->errorInfo();
var_dump($value);
+// Try with strings - Bug #68351
+$value = '0';
+$query->bindParam(':foo', $value, PDO::PARAM_BOOL);
+$query->execute();
+$errors[] = $query->errorInfo();
+var_dump($query->fetchColumn());
+
+$value = "abc";
+$query->bindParam(':foo', $value, PDO::PARAM_BOOL);
+$query->execute();
+$errors[] = $query->errorInfo();
+var_dump($query->fetchColumn());
+
$expect = 'No errors found';
foreach ($errors as $error)
@@ -48,4 +61,6 @@ echo $expect;
--EXPECTF--
bool(true)
bool(false)
+bool(true)
+bool(false)
No errors found
diff --git a/ext/pdo_pgsql/tests/bug66584.phpt b/ext/pdo_pgsql/tests/bug66584.phpt
new file mode 100644
index 0000000000..07742bca79
--- /dev/null
+++ b/ext/pdo_pgsql/tests/bug66584.phpt
@@ -0,0 +1,66 @@
+--TEST--
+PDO PgSQL Bug #66584 (Segmentation fault on statement deallocation)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+$pdo = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
+
+$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+
+$pdo->beginTransaction();
+
+$pdo->query("CREATE TABLE b66584 (a int)");
+$pdo->query("INSERT INTO b66584 VALUES (165)");
+
+for ($i = 1; $i >= 0; $i--) {
+ $pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, (bool)$i);
+
+ try {
+ run($pdo, [0 => 1, 2 => 165, 5 => 3]);
+ } catch (\Exception $e) {
+ var_dump($e->getMessage());
+ }
+
+ try {
+ run($pdo, json_decode('{"0":234,"1":165,"2":221,"3":207,"4":188,"5":216,"6":1150,"7":916,"8":967,"9":987,"10":951,"11":990,"12":959,"13":896,"14":947,"15":877,"16":1000,"17":1023,"18":904,"19":856,"20":860,"21":866,"22":930,"23":974,"24":1032,"25":1016,"26":1050,"27":1059,"28":1040,"29":1064,"30":1004,"31":214,"32":189,"33":166,"34":1002,"35":167,"36":191,"37":859,"38":204,"39":181,"40":1001,"42":208,"43":198,"44":177,"45":1003,"46":858,"47":190,"48":162,"49":210,"50":171,"51":197,"52":168,"53":194,"54":209,"55":200,"56":192,"57":180,"58":232,"59":222,"60":163,"61":196,"62":217,"64":176,"65":193,"66":172,"67":195,"68":170,"69":173,"70":233,"71":223,"72":218,"73":186,"74":175,"75":224,"76":205,"77":211,"78":235,"79":1101,"80":225,"81":236,"82":1102,"83":1164,"84":1083,"85":1005,"86":861,"87":1179,"88":960,"89":991,"90":1187,"91":880,"92":1149,"93":1033,"94":931,"95":1006,"96":862,"97":1151,"98":917,"99":881,"100":1148,"101":1065,"102":867,"103":952,"104":1152,"105":918,"106":961,"107":1180,"108":992,"109":1188,"110":932,"111":933,"112":968,"113":868,"114":882,"115":1147,"116":1017,"117":1131,"118":1174,"119":1178,"120":1186,"121":869,"122":1051,"123":934,"124":969,"125":975,"126":1066,"127":237,"128":953,"129":1024,"130":1146,"131":883,"132":1145,"133":884,"134":885,"135":1144,"136":886,"137":1143,"138":1025,"139":897,"140":898,"141":899,"142":1026,"143":1142,"144":887,"145":1141,"146":888,"147":889,"148":1140,"149":1189,"150":993,"151":1139,"152":890,"153":1138,"154":891,"155":900,"156":892,"157":1137,"158":1027,"159":901,"160":1136,"161":893,"162":870,"163":1052,"164":954,"165":1041,"166":1018,"167":1165,"168":1084,"169":962,"170":1181,"171":994,"172":1190,"173":1042,"174":935,"175":226,"176":871,"177":1191,"178":995,"179":977,"180":948,"181":1175,"182":1053,"183":955,"184":1182,"185":963,"186":1067,"187":919,"188":1153,"189":920,"190":1154,"191":1055,"192":1054,"193":1056,"194":863,"195":872,"196":1028,"197":921,"198":1155,"199":936,"200":970,"201":1019,"202":1166,"203":1085,"204":1135,"205":894,"206":1034,"207":905,"208":873,"209":937,"210":902,"211":1029,"212":1007,"213":864,"214":1043,"215":1057,"216":956,"217":957,"218":939,"219":1086,"220":1167,"221":1087,"222":1168,"223":1173,"224":1108,"225":978,"226":1044,"227":1183,"228":964,"229":965,"230":1184,"231":1045,"232":874,"233":940,"234":1046,"235":979,"236":903,"237":980,"238":1156,"239":922,"240":1035,"241":906,"242":971,"243":972,"244":878,"245":1134,"246":879,"247":1133,"248":907,"249":1036,"250":908,"251":1132,"252":895,"253":909,"254":1060,"255":981,"256":1068,"257":996,"258":1192,"259":941,"260":865,"261":1008,"262":910,"263":997,"264":1193,"265":982,"266":942,"267":1020,"268":983,"269":1061,"270":949,"271":1176,"272":875,"273":911,"274":1069,"275":1157,"276":923,"277":1158,"278":924,"279":988,"280":984,"281":925,"282":1159,"283":1062,"284":1047,"285":1194,"286":998,"287":1021,"288":1030,"289":1031,"290":1070,"291":1088,"292":1169,"293":958,"294":1195,"295":999,"296":966,"297":1185,"298":944,"299":945,"300":1022,"301":1103,"302":220,"303":1099,"304":1048,"305":927,"306":1161,"307":989,"308":973,"309":1071,"310":1074,"311":1072,"312":1073,"313":912,"314":1037,"315":913,"316":914,"317":1177,"318":950,"319":1049,"320":876,"321":985,"322":915,"323":1038,"324":946,"325":1089,"326":1170,"327":1090,"328":1171,"329":1091,"330":1172,"331":1063,"332":986,"333":928,"334":1162,"335":929,"336":1163,"337":976,"338":231,"339":201,"340":1098,"341":215}', true));
+ } catch (\Exception $e) {
+ var_dump($e->getMessage());
+ }
+}
+
+try {
+ $pdo->query("DROP TABLE b66584");
+ $pdo->rollback();
+} catch (\Exception $e) {
+}
+
+function run($pdo, $data)
+{
+ $bind = join(', ', array_fill(0, count($data), '?'));
+
+ $stmt = $pdo->prepare("SELECT COUNT(*) FROM b66584 WHERE a IN ({$bind})");
+
+ var_dump(count($data));
+
+ $stmt->execute($data);
+
+ var_dump($stmt->fetchColumn());
+}
+
+?>
+--EXPECTF--
+int(3)
+string(%d) "SQLSTATE%s"
+int(340)
+string(%d) "SQLSTATE%s"
+int(3)
+string(%d) "SQLSTATE%s"
+int(340)
+string(%d) "SQLSTATE%s"
diff --git a/ext/pdo_pgsql/tests/bug67462.phpt b/ext/pdo_pgsql/tests/bug67462.phpt
new file mode 100644
index 0000000000..888b19c248
--- /dev/null
+++ b/ext/pdo_pgsql/tests/bug67462.phpt
@@ -0,0 +1,34 @@
+--TEST--
+PDO PgSQL Bug #67462 (PDO_PGSQL::beginTransaction() wrongly throws exception when not in transaction)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+
+require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
+$pdo = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
+$pdo->setAttribute (\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+
+$pdo->beginTransaction();
+
+try {
+ $pdo->query("CREATE TABLE b67462 (a int NOT NULL PRIMARY KEY DEFERRABLE INITIALLY DEFERRED)");
+ $pdo->query("INSERT INTO b67462 VALUES (1), (1)");
+
+ var_dump($pdo->inTransaction());
+ $pdo->commit(); // This should fail!
+} catch (\Exception $e) {
+ var_dump($pdo->inTransaction());
+ var_dump($pdo->beginTransaction());
+}
+
+?>
+--EXPECT--
+bool(true)
+bool(false)
+bool(true)
diff --git a/ext/pgsql/tests/config.inc b/ext/pgsql/tests/config.inc
index 367f1ef9ba..e9944de793 100644
--- a/ext/pgsql/tests/config.inc
+++ b/ext/pgsql/tests/config.inc
@@ -1,10 +1,12 @@
<?php
+
// These vars are used to connect db and create test table.
-// values can be set to meet your environment
+// values can be set to meet your environment with the
+// environment var PGSQL_TEST_CONNSTR
+
+// "test" database must exist. i.e. "createdb test" before testing
+$conn_str = getenv('PGSQL_TEST_CONNSTR') ?: "host=localhost dbname=test port=5432"; // connection string
-// "test" database must be existed. i.e. "createdb test" before testing
-// PostgreSQL uses login name as username, user must have access to "test" database.
-$conn_str = "host=localhost dbname=test port=5432"; // connection string
$table_name = "php_pgsql_test"; // test table that will be created
$table_name_92 = "php_pgsql_test_92"; // test table that will be created
$num_test_record = 1000; // Number of records to create
diff --git a/ext/session/session.c b/ext/session/session.c
index d440e6fdd9..edc8f15d5b 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -514,17 +514,8 @@ static void php_session_initialize(TSRMLS_D) /* {{{ */
PS(session_status) = php_session_active;
}
if (val) {
- PHP_MD5_CTX context;
-
- /* Store read data's MD5 hash */
- PHP_MD5Init(&context);
- PHP_MD5Update(&context, val, vallen);
- PHP_MD5Final(PS(session_data_hash), &context);
-
php_session_decode(val, vallen TSRMLS_CC);
str_efree(val);
- } else {
- memset(PS(session_data_hash),'\0', 16);
}
if (!PS(use_cookies) && PS(send_cookie)) {
@@ -554,12 +545,7 @@ static void php_session_save_current_state(TSRMLS_D) /* {{{ */
PHP_MD5Init(&context);
PHP_MD5Update(&context, val, vallen);
PHP_MD5Final(digest, &context);
- /* Write only when save is required */
- if (memcmp(digest, PS(session_data_hash), 16)) {
- ret = PS(mod)->s_write(&PS(mod_data), PS(id), val, vallen TSRMLS_CC);
- } else {
- ret = SUCCESS;
- }
+ ret = PS(mod)->s_write(&PS(mod_data), PS(id), val, vallen TSRMLS_CC);
efree(val);
} else {
ret = PS(mod)->s_write(&PS(mod_data), PS(id), "", 0 TSRMLS_CC);
@@ -1994,7 +1980,6 @@ static PHP_FUNCTION(session_regenerate_id)
RETURN_FALSE;
}
efree(PS(id));
- memset(PS(session_data_hash),'\0', 16);
}
PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
diff --git a/ext/session/tests/session_set_save_handler_write_short_circuit.phpt b/ext/session/tests/session_set_save_handler_write_short_circuit.phpt
index 02ca182ec6..08da29a8fd 100644
--- a/ext/session/tests/session_set_save_handler_write_short_circuit.phpt
+++ b/ext/session/tests/session_set_save_handler_write_short_circuit.phpt
@@ -5,6 +5,7 @@ session.save_path=
session.name=PHPSESSID
--SKIPIF--
<?php include('skipif.inc'); ?>
+skip - Waiting RFC patch merge
--FILE--
<?php
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index ca14b28ccd..c5392760e8 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -5051,7 +5051,7 @@ static int user_tick_function_compare(user_tick_function_entry * tick_fe1, user_
}
/* }}} */
-void php_call_shutdown_functions(TSRMLS_D) /* {{{ */
+PHPAPI void php_call_shutdown_functions(TSRMLS_D) /* {{{ */
{
if (BG(user_shutdown_function_names)) {
zend_try {
@@ -5063,7 +5063,7 @@ void php_call_shutdown_functions(TSRMLS_D) /* {{{ */
}
/* }}} */
-void php_free_shutdown_functions(TSRMLS_D) /* {{{ */
+PHPAPI void php_free_shutdown_functions(TSRMLS_D) /* {{{ */
{
if (BG(user_shutdown_function_names))
zend_try {
diff --git a/ext/standard/basic_functions.h b/ext/standard/basic_functions.h
index 3af85b3d40..eaeb9bca83 100644
--- a/ext/standard/basic_functions.h
+++ b/ext/standard/basic_functions.h
@@ -261,4 +261,8 @@ PHPAPI extern zend_bool register_user_shutdown_function(char *function_name, siz
PHPAPI extern zend_bool remove_user_shutdown_function(char *function_name, size_t function_len TSRMLS_DC);
PHPAPI extern zend_bool append_user_shutdown_function(php_shutdown_function_entry shutdown_function_entry TSRMLS_DC);
+PHPAPI void php_call_shutdown_functions(TSRMLS_D);
+PHPAPI void php_free_shutdown_functions(TSRMLS_D);
+
+
#endif /* BASIC_FUNCTIONS_H */
diff --git a/ext/standard/file.c b/ext/standard/file.c
index 10ed693f01..a2b4db154a 100644
--- a/ext/standard/file.c
+++ b/ext/standard/file.c
@@ -339,16 +339,16 @@ static int flock_values[] = { LOCK_SH, LOCK_EX, LOCK_UN };
Portable file locking */
PHP_FUNCTION(flock)
{
- zval *arg1, *arg3 = NULL;
+ zval *res, *wouldblock = NULL;
int act;
php_stream *stream;
long operation = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &arg1, &operation, &arg3) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &res, &operation, &wouldblock) == FAILURE) {
return;
}
- PHP_STREAM_TO_ZVAL(stream, &arg1);
+ PHP_STREAM_TO_ZVAL(stream, &res);
act = operation & 3;
if (act < 1 || act > 3) {
@@ -356,16 +356,16 @@ PHP_FUNCTION(flock)
RETURN_FALSE;
}
- if (arg3 && PZVAL_IS_REF(arg3)) {
- convert_to_long_ex(&arg3);
- Z_LVAL_P(arg3) = 0;
+ if (wouldblock && PZVAL_IS_REF(wouldblock)) {
+ convert_to_long_ex(&wouldblock);
+ Z_LVAL_P(wouldblock) = 0;
}
/* flock_values contains all possible actions if (operation & 4) we won't block on the lock */
act = flock_values[act - 1] | (operation & PHP_LOCK_NB ? LOCK_NB : 0);
if (php_stream_lock(stream, act)) {
- if (operation && errno == EWOULDBLOCK && arg3 && PZVAL_IS_REF(arg3)) {
- Z_LVAL_P(arg3) = 1;
+ if (operation && errno == EWOULDBLOCK && wouldblock && PZVAL_IS_REF(wouldblock)) {
+ Z_LVAL_P(wouldblock) = 1;
}
RETURN_FALSE;
}
@@ -896,14 +896,14 @@ PHP_NAMED_FUNCTION(php_if_fopen)
Close an open file pointer */
PHPAPI PHP_FUNCTION(fclose)
{
- zval *arg1;
+ zval *res;
php_stream *stream;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) {
RETURN_FALSE;
}
- PHP_STREAM_TO_ZVAL(stream, &arg1);
+ PHP_STREAM_TO_ZVAL(stream, &res);
if ((stream->flags & PHP_STREAM_FLAG_NO_FCLOSE) != 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a valid stream resource", stream->rsrc_id);
@@ -968,14 +968,14 @@ PHP_FUNCTION(popen)
Close a file pointer opened by popen() */
PHP_FUNCTION(pclose)
{
- zval *arg1;
+ zval *res;
php_stream *stream;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) {
RETURN_FALSE;
}
- PHP_STREAM_TO_ZVAL(stream, &arg1);
+ PHP_STREAM_TO_ZVAL(stream, &res);
FG(pclose_wait) = 1;
zend_list_delete(stream->rsrc_id);
@@ -988,14 +988,14 @@ PHP_FUNCTION(pclose)
Test for end-of-file on a file pointer */
PHPAPI PHP_FUNCTION(feof)
{
- zval *arg1;
+ zval *res;
php_stream *stream;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) {
RETURN_FALSE;
}
- PHP_STREAM_TO_ZVAL(stream, &arg1);
+ PHP_STREAM_TO_ZVAL(stream, &res);
if (php_stream_eof(stream)) {
RETURN_TRUE;
@@ -1009,18 +1009,18 @@ PHPAPI PHP_FUNCTION(feof)
Get a line from file pointer */
PHPAPI PHP_FUNCTION(fgets)
{
- zval *arg1;
+ zval *res;
long len = 1024;
char *buf = NULL;
int argc = ZEND_NUM_ARGS();
size_t line_len = 0;
php_stream *stream;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &arg1, &len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &res, &len) == FAILURE) {
RETURN_FALSE;
}
- PHP_STREAM_TO_ZVAL(stream, &arg1);
+ PHP_STREAM_TO_ZVAL(stream, &res);
if (argc == 1) {
/* ask streams to give us a buffer of an appropriate size */
@@ -1060,16 +1060,16 @@ exit_failed:
Get a character from file pointer */
PHPAPI PHP_FUNCTION(fgetc)
{
- zval *arg1;
+ zval *res;
char buf[2];
int result;
php_stream *stream;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) {
RETURN_FALSE;
}
- PHP_STREAM_TO_ZVAL(stream, &arg1);
+ PHP_STREAM_TO_ZVAL(stream, &res);
result = php_stream_getc(stream);
@@ -1180,35 +1180,31 @@ PHP_FUNCTION(fscanf)
Binary-safe file write */
PHPAPI PHP_FUNCTION(fwrite)
{
- zval *arg1;
- char *arg2;
- int arg2len;
+ zval *res;
+ char *input;
+ int inputlen;
int ret;
int num_bytes;
- long arg3 = 0;
- char *buffer = NULL;
+ long maxlen = 0;
php_stream *stream;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &arg1, &arg2, &arg2len, &arg3) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|l", &res, &input, &inputlen, &maxlen) == FAILURE) {
RETURN_FALSE;
}
if (ZEND_NUM_ARGS() == 2) {
- num_bytes = arg2len;
+ num_bytes = inputlen;
} else {
- num_bytes = MAX(0, MIN((int)arg3, arg2len));
+ num_bytes = MAX(0, MIN((int) maxlen, inputlen));
}
if (!num_bytes) {
RETURN_LONG(0);
}
- PHP_STREAM_TO_ZVAL(stream, &arg1);
+ PHP_STREAM_TO_ZVAL(stream, &res);
- ret = php_stream_write(stream, buffer ? buffer : arg2, num_bytes);
- if (buffer) {
- efree(buffer);
- }
+ ret = php_stream_write(stream, input, num_bytes);
RETURN_LONG(ret);
}
@@ -1218,15 +1214,15 @@ PHPAPI PHP_FUNCTION(fwrite)
Flushes output */
PHPAPI PHP_FUNCTION(fflush)
{
- zval *arg1;
+ zval *res;
int ret;
php_stream *stream;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) {
RETURN_FALSE;
}
- PHP_STREAM_TO_ZVAL(stream, &arg1);
+ PHP_STREAM_TO_ZVAL(stream, &res);
ret = php_stream_flush(stream);
if (ret) {
@@ -1240,14 +1236,14 @@ PHPAPI PHP_FUNCTION(fflush)
Rewind the position of a file pointer */
PHPAPI PHP_FUNCTION(rewind)
{
- zval *arg1;
+ zval *res;
php_stream *stream;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) {
RETURN_FALSE;
}
- PHP_STREAM_TO_ZVAL(stream, &arg1);
+ PHP_STREAM_TO_ZVAL(stream, &res);
if (-1 == php_stream_rewind(stream)) {
RETURN_FALSE;
@@ -1260,15 +1256,15 @@ PHPAPI PHP_FUNCTION(rewind)
Get file pointer's read/write position */
PHPAPI PHP_FUNCTION(ftell)
{
- zval *arg1;
+ zval *res;
long ret;
php_stream *stream;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) {
RETURN_FALSE;
}
- PHP_STREAM_TO_ZVAL(stream, &arg1);
+ PHP_STREAM_TO_ZVAL(stream, &res);
ret = php_stream_tell(stream);
if (ret == -1) {
@@ -1282,17 +1278,17 @@ PHPAPI PHP_FUNCTION(ftell)
Seek on a file pointer */
PHPAPI PHP_FUNCTION(fseek)
{
- zval *arg1;
- long arg2, whence = SEEK_SET;
+ zval *res;
+ long offset, whence = SEEK_SET;
php_stream *stream;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|l", &arg1, &arg2, &whence) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|l", &res, &offset, &whence) == FAILURE) {
RETURN_FALSE;
}
- PHP_STREAM_TO_ZVAL(stream, &arg1);
+ PHP_STREAM_TO_ZVAL(stream, &res);
- RETURN_LONG(php_stream_seek(stream, arg2, whence));
+ RETURN_LONG(php_stream_seek(stream, offset, whence));
}
/* }}} */
@@ -1394,7 +1390,7 @@ PHP_FUNCTION(readfile)
Return or change the umask */
PHP_FUNCTION(umask)
{
- long arg1 = 0;
+ long mask = 0;
int oldumask;
oldumask = umask(077);
@@ -1403,14 +1399,14 @@ PHP_FUNCTION(umask)
BG(umask) = oldumask;
}
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &arg1) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &mask) == FAILURE) {
RETURN_FALSE;
}
if (ZEND_NUM_ARGS() == 0) {
umask(oldumask);
} else {
- umask(arg1);
+ umask(mask);
}
RETURN_LONG(oldumask);
@@ -1421,15 +1417,15 @@ PHP_FUNCTION(umask)
Output all remaining data from a file pointer */
PHPAPI PHP_FUNCTION(fpassthru)
{
- zval *arg1;
+ zval *res;
int size;
php_stream *stream;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg1) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &res) == FAILURE) {
RETURN_FALSE;
}
- PHP_STREAM_TO_ZVAL(stream, &arg1);
+ PHP_STREAM_TO_ZVAL(stream, &res);
size = php_stream_passthru(stream);
RETURN_LONG(size);
@@ -1751,15 +1747,15 @@ safe_to_copy:
Binary-safe file read */
PHPAPI PHP_FUNCTION(fread)
{
- zval *arg1;
+ zval *res;
long len;
php_stream *stream;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &arg1, &len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &res, &len) == FAILURE) {
RETURN_FALSE;
}
- PHP_STREAM_TO_ZVAL(stream, &arg1);
+ PHP_STREAM_TO_ZVAL(stream, &res);
if (len <= 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
diff --git a/ext/standard/tests/file/bug52820.phpt b/ext/standard/tests/file/bug52820.phpt
index 3a9f9c31a4..a00ebf50b6 100644
--- a/ext/standard/tests/file/bug52820.phpt
+++ b/ext/standard/tests/file/bug52820.phpt
@@ -1,71 +1,63 @@
---TEST--
-Bug #52820 (writes to fopencookie FILE* not committed when seeking the stream)
---SKIPIF--
-<?php
-if (!function_exists('leak_variable'))
- die("skip only for debug builds");
-/* unfortunately no standard function does a cast to FILE*, so we need
- * curl to test this */
-if (!extension_loaded("curl")) exit("skip curl extension not loaded");
-$handle=curl_init('http://127.0.0.1:37349/');
-curl_setopt($handle, CURLOPT_VERBOSE, true);
-curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
-if (!curl_setopt($handle, CURLOPT_STDERR, fopen("php://memory", "w+")))
- die("skip fopencookie not supported on this platform");
---FILE--
-<?php
-function do_stuff($url) {
- $handle=curl_init('http://127.0.0.1:37349/');
- curl_setopt($handle, CURLOPT_VERBOSE, true);
- curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($handle, CURLOPT_STDERR, $o = fopen($url, "w+"));
- curl_exec($handle);
- echo "About to rewind!\n";
- rewind($o);
- echo stream_get_contents($o);
- return $o;
-}
-
-echo "temp stream (close after):\n";
-fclose(do_stuff("php://temp"));
-
-echo "\nmemory stream (close after):\n";
-fclose(do_stuff("php://memory"));
-
-echo "\ntemp stream (leak):\n";
-leak_variable(do_stuff("php://temp"), true);
-
-echo "\nmemory stream (leak):\n";
-leak_variable(do_stuff("php://memory"), true);
-
-echo "\nDone.\n";
---EXPECTF--
-temp stream (close after):
-About to rewind!
-* About to connect() to 127.0.0.1 port 37349%r.*%r
-* Trying 127.0.0.1...%A* Connection refused
-* couldn't connect to host%S
-* Closing connection #0
-
-memory stream (close after):
-About to rewind!
-* About to connect() to 127.0.0.1 port 37349%r.*%r
-* Trying 127.0.0.1...%A* Connection refused
-* couldn't connect to host%S
-* Closing connection #0
-
-temp stream (leak):
-About to rewind!
-* About to connect() to 127.0.0.1 port 37349%r.*%r
-* Trying 127.0.0.1...%A* Connection refused
-* couldn't connect to host%S
-* Closing connection #0
-
-memory stream (leak):
-About to rewind!
-* About to connect() to 127.0.0.1 port 37349%r.*%r
-* Trying 127.0.0.1...%A* Connection refused
-* couldn't connect to host%S
-* Closing connection #0
-
-Done.
+--TEST--
+Bug #52820 (writes to fopencookie FILE* not committed when seeking the stream)
+--SKIPIF--
+<?php
+if (!function_exists('leak_variable'))
+ die("skip only for debug builds");
+/* unfortunately no standard function does a cast to FILE*, so we need
+ * curl to test this */
+if (!extension_loaded("curl")) exit("skip curl extension not loaded");
+$handle=curl_init('http://127.0.0.1:37349/');
+curl_setopt($handle, CURLOPT_VERBOSE, true);
+curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
+if (!curl_setopt($handle, CURLOPT_STDERR, fopen("php://memory", "w+")))
+ die("skip fopencookie not supported on this platform");
+--FILE--
+<?php
+function do_stuff($url) {
+ $handle=curl_init('http://127.0.0.1:37349/');
+ curl_setopt($handle, CURLOPT_VERBOSE, true);
+ curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($handle, CURLOPT_STDERR, $o = fopen($url, "w+"));
+ curl_exec($handle);
+ echo "About to rewind!\n";
+ rewind($o);
+ echo stream_get_contents($o);
+ return $o;
+}
+
+echo "temp stream (close after):\n";
+fclose(do_stuff("php://temp"));
+
+echo "\nmemory stream (close after):\n";
+fclose(do_stuff("php://memory"));
+
+echo "\ntemp stream (leak):\n";
+leak_variable(do_stuff("php://temp"), true);
+
+echo "\nmemory stream (leak):\n";
+leak_variable(do_stuff("php://memory"), true);
+
+echo "\nDone.\n";
+--EXPECTF--
+temp stream (close after):
+About to rewind!
+* %ATrying 127.0.0.1...%AConnection refused%A
+* Closing connection%A%d
+
+memory stream (close after):
+About to rewind!
+* %ATrying 127.0.0.1...%AConnection refused%A
+* Closing connection%A%d
+
+temp stream (leak):
+About to rewind!
+* %ATrying 127.0.0.1...%AConnection refused%A
+* Closing connection%A%d
+
+memory stream (leak):
+About to rewind!
+* %ATrying 127.0.0.1...%AConnection refused%A
+* Closing connection%A%d
+
+Done.
diff --git a/ext/xmlrpc/libxmlrpc/xmlrpc.c b/ext/xmlrpc/libxmlrpc/xmlrpc.c
index b766a5495a..f184cf49ee 100644
--- a/ext/xmlrpc/libxmlrpc/xmlrpc.c
+++ b/ext/xmlrpc/libxmlrpc/xmlrpc.c
@@ -201,9 +201,13 @@ static int date_from_ISO8601 (const char *text, time_t * value) {
}
p++;
}
- text = buf;
+ *p2 = 0;
+ text = buf;
}
+ if (strlen(text)<17) {
+ return -1;
+ }
tm.tm_isdst = -1;
diff --git a/main/getopt.c b/main/getopt.c
index a31a6c75d5..258173fc22 100644
--- a/main/getopt.c
+++ b/main/getopt.c
@@ -59,9 +59,17 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char
{
static int optchr = 0;
static int dash = 0; /* have already seen the - */
+ static char **prev_optarg = NULL;
php_optidx = -1;
+ if(prev_optarg && prev_optarg != optarg) {
+ /* reset the state */
+ optchr = 0;
+ dash = 0;
+ }
+ prev_optarg = optarg;
+
if (*optind >= argc) {
return(EOF);
}
diff --git a/main/output.c b/main/output.c
index 1dac7179b8..0c7212ac91 100644
--- a/main/output.c
+++ b/main/output.c
@@ -35,7 +35,7 @@
#include "zend_stack.h"
#include "php_output.h"
-ZEND_DECLARE_MODULE_GLOBALS(output);
+PHPAPI ZEND_DECLARE_MODULE_GLOBALS(output);
const char php_output_default_handler_name[sizeof("default output handler")] = "default output handler";
const char php_output_devnull_handler_name[sizeof("null output handler")] = "null output handler";
diff --git a/main/php_main.h b/main/php_main.h
index 1325486bd9..03c89c5d6f 100644
--- a/main/php_main.h
+++ b/main/php_main.h
@@ -50,9 +50,6 @@ PHPAPI int php_handle_auth_data(const char *auth TSRMLS_DC);
PHPAPI void php_html_puts(const char *str, uint siz TSRMLS_DC);
PHPAPI int php_stream_open_for_zend_ex(const char *filename, zend_file_handle *handle, int mode TSRMLS_DC);
-extern void php_call_shutdown_functions(TSRMLS_D);
-extern void php_free_shutdown_functions(TSRMLS_D);
-
/* environment module */
extern int php_init_environ(void);
extern int php_shutdown_environ(void);
diff --git a/main/php_output.h b/main/php_output.h
index 0312e256f8..3831478b9f 100644
--- a/main/php_output.h
+++ b/main/php_output.h
@@ -152,6 +152,8 @@ ZEND_BEGIN_MODULE_GLOBALS(output)
int output_start_lineno;
ZEND_END_MODULE_GLOBALS(output)
+PHPAPI ZEND_EXTERN_MODULE_GLOBALS(output);
+
/* there should not be a need to use OG() from outside of output.c */
#ifdef ZTS
# define OG(v) TSRMG(output_globals_id, zend_output_globals *, v)
diff --git a/main/php_version.h b/main/php_version.h
index be8584d14a..daa633ca33 100644
--- a/main/php_version.h
+++ b/main/php_version.h
@@ -2,7 +2,7 @@
/* edit configure.in to change version number */
#define PHP_MAJOR_VERSION 5
#define PHP_MINOR_VERSION 6
-#define PHP_RELEASE_VERSION 3
+#define PHP_RELEASE_VERSION 4
#define PHP_EXTRA_VERSION "-dev"
-#define PHP_VERSION "5.6.3-dev"
-#define PHP_VERSION_ID 50603
+#define PHP_VERSION "5.6.4-dev"
+#define PHP_VERSION_ID 50604
diff --git a/run-tests.php b/run-tests.php
index 1b5bcec253..315ae09200 100755
--- a/run-tests.php
+++ b/run-tests.php
@@ -2718,7 +2718,7 @@ function junit_mark_test_as($type, $file_name, $test_name, $time = null, $messag
if (is_array($type)) {
$output_type = $type[0] . 'ED';
- $temp = array_intersect(array('XFAIL', 'FAIL'), $type);
+ $temp = array_intersect(array('XFAIL', 'FAIL', 'WARN'), $type);
$type = reset($temp);
} else {
$output_type = $type . 'ED';
@@ -2732,6 +2732,9 @@ function junit_mark_test_as($type, $file_name, $test_name, $time = null, $messag
} elseif ('SKIP' == $type) {
junit_suite_record($suite, 'test_skip');
$JUNIT['files'][$file_name]['xml'] .= "<skipped>$escaped_message</skipped>\n";
+ } elseif ('WARN' == $type) {
+ junit_suite_record($suite, 'test_warn');
+ $JUNIT['files'][$file_name]['xml'] .= "<warning>$escaped_message</warning>\n";
} elseif('FAIL' == $type) {
junit_suite_record($suite, 'test_fail');
$JUNIT['files'][$file_name]['xml'] .= "<failure type='$output_type' message='$escaped_message'>$escaped_details</failure>\n";
diff --git a/sapi/litespeed/lsapi_main.c b/sapi/litespeed/lsapi_main.c
index 425d638f9e..6bdf9b7d0c 100644
--- a/sapi/litespeed/lsapi_main.c
+++ b/sapi/litespeed/lsapi_main.c
@@ -478,8 +478,8 @@ static int init_request_info( TSRMLS_D )
SG(request_info).content_length = LSAPI_GetReqBodyLen();
SG(request_info).path_translated = estrdup( LSAPI_GetScriptFileName());
- /* It is not reset by zend engine, set it to 0. */
- SG(sapi_headers).http_response_code = 0;
+ /* It is not reset by zend engine, set it to 200. */
+ SG(sapi_headers).http_response_code = 200;
pAuth = LSAPI_GetHeader( H_AUTHORIZATION );
php_handle_auth_data(pAuth TSRMLS_CC);
diff --git a/sapi/phpdbg/config.m4 b/sapi/phpdbg/config.m4
index 528abb5822..87d38ea8c5 100644
--- a/sapi/phpdbg/config.m4
+++ b/sapi/phpdbg/config.m4
@@ -22,14 +22,10 @@ if test "$BUILD_PHPDBG" == "" && test "$PHP_PHPDBG" != "no"; then
fi
if test "$PHP_PHPDBG_WEBHELPER" != "no"; then
- if ! test -d ext/phpdbg_webhelper; then
- ln -s ../sapi/phpdbg ext/phpdbg_webhelper
- fi
- if test "$PHP_JSON" != "no"; then
- PHP_NEW_EXTENSION(phpdbg_webhelper, phpdbg_rinit_hook.c phpdbg_webdata_transfer.c, $ext_shared)
- else
- AC_MSG_ERROR(Webhelper extension of phpdbg needs json enabled)
+ if ! test -d $abs_srcdir/ext/phpdbg_webhelper; then
+ ln -s ../sapi/phpdbg $abs_srcdir/ext/phpdbg_webhelper
fi
+ PHP_NEW_EXTENSION(phpdbg_webhelper, phpdbg_rinit_hook.c phpdbg_webdata_transfer.c, $ext_shared)
fi
PHP_PHPDBG_CFLAGS="-D_GNU_SOURCE"
diff --git a/sapi/phpdbg/config.w32 b/sapi/phpdbg/config.w32
index 6f0bd8f811..8a685d3347 100644
--- a/sapi/phpdbg/config.w32
+++ b/sapi/phpdbg/config.w32
@@ -1,5 +1,6 @@
ARG_ENABLE('phpdbg', 'Build phpdbg', 'no');
ARG_ENABLE('phpdbgs', 'Build phpdbg shared', 'no');
+ARG_ENABLE('phpdbg-webhelper', 'Build phpdbg webhelper', 'yes');
PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help.c phpdbg_break.c ' +
'phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c ' +
@@ -14,6 +15,10 @@ if (PHP_PHPDBG == "yes") {
ADD_FLAG("LIBS_PHPDBG", "ws2_32.lib user32.lib");
ADD_FLAG("CFLAGS_PHPDBG", "/D YY_NO_UNISTD_H");
ADD_FLAG("LDFLAGS_PHPDBG", "/stack:8388608");
+
+ if (PHP_PHPDBG_WEBHELPER == "yes") {
+ EXTENSION('phpdbg_webhelper', 'phpdbg_rinit_hook.c phpdbg_webdata_transfer.c');
+ }
}
if (PHP_PHPDBGS == "yes") {
diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c
index b7fb5e5afc..6ee41b7586 100644
--- a/sapi/phpdbg/phpdbg.c
+++ b/sapi/phpdbg/phpdbg.c
@@ -549,7 +549,7 @@ static int php_sapi_phpdbg_deactivate(TSRMLS_D) /* {{{ */
php_phpdbg_globals_ctor(pg);
- pg->exec = strndup(PHPDBG_G(exec), PHPDBG_G(exec_len));
+ pg->exec = zend_strndup(PHPDBG_G(exec), PHPDBG_G(exec_len));
pg->exec_len = PHPDBG_G(exec_len);
pg->oplog = PHPDBG_G(oplog);
pg->prompt[0] = PHPDBG_G(prompt)[0];
@@ -779,7 +779,9 @@ const opt_struct OPTIONS[] = { /* {{{ */
{'S', 1, "sapi-name"},
{'l', 1, "listen"},
{'a', 1, "address-or-any"},
+#if PHPDBG_IN_DEV
{'x', 0, "xml output"},
+#endif
{'V', 0, "version"},
{'-', 0, NULL}
}; /* }}} */
@@ -1039,13 +1041,7 @@ int main(int argc, char **argv) /* {{{ */
zend_bool remote = 0;
int step = 0;
zend_phpdbg_globals *settings = NULL;
-
-#ifdef _WIN32
- char *bp_tmp_file = NULL;
-#else
- char bp_tmp_file[] = "/tmp/phpdbg.XXXXXX";
-#endif
-
+ char *bp_tmp = NULL;
char *address;
int listen = -1;
int server = -1;
@@ -1081,29 +1077,6 @@ int main(int argc, char **argv) /* {{{ */
#endif
phpdbg_main:
- if (!cleaning) {
-
-#ifdef _WIN32
- bp_tmp_file = malloc(L_tmpnam);
-
- if (bp_tmp_file) {
- if (!tmpnam(bp_tmp_file)) {
- free(bp_tmp_file);
- bp_tmp_file = NULL;
- }
- }
-
- if (!bp_tmp_file) {
- phpdbg_error("tmpfile", "", "Unable to create temporary file");
- return 1;
- }
-#else
- if (!mkstemp(bp_tmp_file)) {
- memset(bp_tmp_file, 0, sizeof(bp_tmp_file));
- }
-#endif
-
- }
ini_entries = NULL;
ini_entries_len = 0;
ini_ignore = 0;
@@ -1242,8 +1215,10 @@ phpdbg_main:
} else address = strdup(php_optarg);
} break;
+#if PHPDBG_IN_DEV
case 'x':
flags |= PHPDBG_WRITE_XML;
+#endif
break;
case 'V': {
@@ -1343,7 +1318,7 @@ phpdbg_main:
}
/* setup remote server if necessary */
- if (!cleaning && listen > 0) {
+ if (cleaning <= 0 && listen > 0) {
server = phpdbg_open_socket(address, listen TSRMLS_CC);
if (-1 > server || phpdbg_remote_init(address, listen, server, &socket, &stream TSRMLS_CC) == FAILURE) {
exit(0);
@@ -1466,7 +1441,7 @@ phpdbg_main:
if (exec) { /* set execution context */
PHPDBG_G(exec) = phpdbg_resolve_path(exec TSRMLS_CC);
- PHPDBG_G(exec_len) = strlen(PHPDBG_G(exec));
+ PHPDBG_G(exec_len) = PHPDBG_G(exec) ? strlen(PHPDBG_G(exec)) : 0;
free(exec);
exec = NULL;
@@ -1502,9 +1477,13 @@ phpdbg_main:
PHPDBG_G(flags) |= PHPDBG_IS_INITIALIZING;
zend_try {
phpdbg_init(init_file, init_file_len, init_file_default TSRMLS_CC);
- PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT;
- phpdbg_try_file_init(bp_tmp_file, strlen(bp_tmp_file), 0 TSRMLS_CC);
- PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT;
+ if (bp_tmp) {
+ PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT;
+ phpdbg_string_init(bp_tmp TSRMLS_CC);
+ free(bp_tmp);
+ bp_tmp = NULL;
+ PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT;
+ }
} zend_end_try();
PHPDBG_G(flags) &= ~PHPDBG_IS_INITIALIZING;
@@ -1527,29 +1506,32 @@ phpdbg_main:
PHPDBG_G(flags) |= PHPDBG_IS_STEPPING;
}
- if (phpdbg_startup_run) {
- zend_try {
- PHPDBG_COMMAND_HANDLER(run)(NULL TSRMLS_CC);
- } zend_end_try();
- if (phpdbg_startup_run > 1) {
- /* if -r is on the command line more than once just quit */
- goto phpdbg_out;
- }
- phpdbg_startup_run = 0;
- }
-
phpdbg_interact:
/* phpdbg main() */
do {
zend_try {
+ if (phpdbg_startup_run) {
+ zend_bool quit_immediately = phpdbg_startup_run > 1;
+ phpdbg_startup_run = 0;
+ PHPDBG_COMMAND_HANDLER(run)(NULL TSRMLS_CC);
+ if (quit_immediately) {
+ /* if -r is on the command line more than once just quit */
+ EG(bailout) = __orig_bailout; /* reset zend_try */
+ break;
+ }
+ }
+
phpdbg_interactive(1 TSRMLS_CC);
} zend_catch {
if ((PHPDBG_G(flags) & PHPDBG_IS_CLEANING)) {
- FILE *bp_tmp_fp = fopen(bp_tmp_file, "w");
+ char *bp_tmp_str;
PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT;
- phpdbg_export_breakpoints(bp_tmp_fp TSRMLS_CC);
+ phpdbg_export_breakpoints_to_string(&bp_tmp_str TSRMLS_CC);
PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT;
- fclose(bp_tmp_fp);
+ if (bp_tmp_str) {
+ bp_tmp = strdup(bp_tmp_str);
+ efree(bp_tmp_str);
+ }
cleaning = 1;
} else {
cleaning = 0;
@@ -1689,11 +1671,5 @@ phpdbg_out:
free(PHPDBG_G(sapi_name_ptr));
}
-#ifdef _WIN32
- free(bp_tmp_file);
-#else
- unlink(bp_tmp_file);
-#endif
-
return 0;
} /* }}} */
diff --git a/sapi/phpdbg/phpdbg.h b/sapi/phpdbg/phpdbg.h
index 65bdcd0d6f..a0ba75e4d4 100644
--- a/sapi/phpdbg/phpdbg.h
+++ b/sapi/phpdbg/phpdbg.h
@@ -21,6 +21,8 @@
#ifndef PHPDBG_H
#define PHPDBG_H
+#define PHPDBG_IN_DEV 0
+
#ifdef PHP_WIN32
# define PHPDBG_API __declspec(dllexport)
#elif defined(__GNUC__) && __GNUC__ >= 4
@@ -29,8 +31,12 @@
# define PHPDBG_API
#endif
-#include <stdint.h>
-#include <stddef.h>
+#ifndef PHP_WIN32
+# include <stdint.h>
+# include <stddef.h>
+#else
+# include "win32/php_stdint.h"
+#endif
#include "php.h"
#include "php_globals.h"
#include "php_variables.h"
@@ -50,7 +56,6 @@
#if defined(_WIN32) && !defined(__MINGW32__)
# include <windows.h>
# include "config.w32.h"
-# include "win32/php_stdint.h"
# undef strcasecmp
# undef strncasecmp
# define strcasecmp _stricmp
@@ -184,7 +189,7 @@ int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC);
#define PHPDBG_BP_MASK (PHPDBG_HAS_FILE_BP | PHPDBG_HAS_SYM_BP | PHPDBG_HAS_METHOD_BP | PHPDBG_HAS_OPLINE_BP | PHPDBG_HAS_COND_BP | PHPDBG_HAS_OPCODE_BP | PHPDBG_HAS_FUNCTION_OPLINE_BP | PHPDBG_HAS_METHOD_OPLINE_BP | PHPDBG_HAS_FILE_OPLINE_BP)
#define PHPDBG_IS_STOPPING (PHPDBG_IS_QUITTING | PHPDBG_IS_CLEANING)
-#define PHPDBG_PRESERVE_FLAGS_MASK (PHPDBG_SHOW_REFCOUNTS | PHPDBG_IS_STEPONEVAL | PHPDBG_IS_BP_ENABLED | PHPDBG_STEP_OPCODE | PHPDBG_IS_QUIET | PHPDBG_IS_COLOURED)
+#define PHPDBG_PRESERVE_FLAGS_MASK (PHPDBG_SHOW_REFCOUNTS | PHPDBG_IS_STEPONEVAL | PHPDBG_IS_BP_ENABLED | PHPDBG_STEP_OPCODE | PHPDBG_IS_QUIET | PHPDBG_IS_COLOURED | PHPDBG_IS_REMOTE | PHPDBG_WRITE_XML | PHPDBG_IS_DISCONNECTED)
#ifndef _WIN32
# define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET | PHPDBG_IS_COLOURED | PHPDBG_IS_BP_ENABLED)
diff --git a/sapi/phpdbg/phpdbg_bp.c b/sapi/phpdbg/phpdbg_bp.c
index 9333b353ce..85dc12a3e5 100644
--- a/sapi/phpdbg/phpdbg_bp.c
+++ b/sapi/phpdbg/phpdbg_bp.c
@@ -111,10 +111,19 @@ PHPDBG_API void phpdbg_reset_breakpoints(TSRMLS_D) /* {{{ */
PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
{
+ char *string;
+ phpdbg_export_breakpoints_to_string(&string TSRMLS_CC);
+ fputs(string, handle);
+}
+
+PHPDBG_API void phpdbg_export_breakpoints_to_string(char **str TSRMLS_DC) /* {{{ */
+{
HashPosition position[2];
HashTable **table = NULL;
zend_ulong id = 0L;
+ *str = "";
+
if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])) {
phpdbg_notice("exportbreakpoint", "count=\"%d\"", "Exporting %d breakpoints", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]));
/* this only looks like magic, it isn't */
@@ -126,55 +135,57 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], NULL, NULL, &id, 0, &position[0]);
for (zend_hash_internal_pointer_reset_ex((*table), &position[1]);
- zend_hash_get_current_data_ex((*table), (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex((*table), &position[1])) {
+ zend_hash_get_current_data_ex((*table), (void**)&brake, &position[1]) == SUCCESS;
+ zend_hash_move_forward_ex((*table), &position[1])) {
if (brake->id == id) {
+ char *new_str = NULL;
+
switch (brake->type) {
case PHPDBG_BREAK_FILE: {
- fprintf(handle,
- "break %s:%lu\n",
+ phpdbg_asprintf(&new_str,
+ "%sbreak %s:%lu\n", *str,
((phpdbg_breakfile_t*)brake)->filename,
((phpdbg_breakfile_t*)brake)->line);
} break;
case PHPDBG_BREAK_SYM: {
- fprintf(handle,
- "break %s\n",
+ phpdbg_asprintf(&new_str,
+ "%sbreak %s\n", *str,
((phpdbg_breaksymbol_t*)brake)->symbol);
} break;
case PHPDBG_BREAK_METHOD: {
- fprintf(handle,
- "break %s::%s\n",
+ phpdbg_asprintf(&new_str,
+ "%sbreak %s::%s\n", *str,
((phpdbg_breakmethod_t*)brake)->class_name,
((phpdbg_breakmethod_t*)brake)->func_name);
} break;
case PHPDBG_BREAK_METHOD_OPLINE: {
- fprintf(handle,
- "break %s::%s#%ld\n",
+ phpdbg_asprintf(&new_str,
+ "%sbreak %s::%s#%ld\n", *str,
((phpdbg_breakopline_t*)brake)->class_name,
((phpdbg_breakopline_t*)brake)->func_name,
((phpdbg_breakopline_t*)brake)->opline_num);
} break;
case PHPDBG_BREAK_FUNCTION_OPLINE: {
- fprintf(handle,
- "break %s#%ld\n",
+ phpdbg_asprintf(&new_str,
+ "%sbreak %s#%ld\n", *str,
((phpdbg_breakopline_t*)brake)->func_name,
((phpdbg_breakopline_t*)brake)->opline_num);
} break;
case PHPDBG_BREAK_FILE_OPLINE: {
- fprintf(handle,
- "break %s:#%ld\n",
+ phpdbg_asprintf(&new_str,
+ "%sbreak %s:#%ld\n", *str,
((phpdbg_breakopline_t*)brake)->class_name,
((phpdbg_breakopline_t*)brake)->opline_num);
} break;
case PHPDBG_BREAK_OPCODE: {
- fprintf(handle,
- "break %s\n",
+ phpdbg_asprintf(&new_str,
+ "%sbreak %s\n", *str,
((phpdbg_breakop_t*)brake)->name);
} break;
@@ -184,20 +195,20 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
if (conditional->paramed) {
switch (conditional->param.type) {
case STR_PARAM:
- fprintf(handle,
- "break at %s if %s\n", conditional->param.str, conditional->code);
+ phpdbg_asprintf(&new_str,
+ "%sbreak at %s if %s\n", *str, conditional->param.str, conditional->code);
break;
case METHOD_PARAM:
- fprintf(handle,
- "break at %s::%s if %s\n",
+ phpdbg_asprintf(&new_str,
+ "%sbreak at %s::%s if %s\n", *str,
conditional->param.method.class, conditional->param.method.name,
conditional->code);
break;
case FILE_PARAM:
- fprintf(handle,
- "break at %s:%lu if %s\n",
+ phpdbg_asprintf(&new_str,
+ "%sbreak at %s:%lu if %s\n", *str,
conditional->param.file.name, conditional->param.file.line,
conditional->code);
break;
@@ -205,15 +216,23 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
default: { /* do nothing */ } break;
}
} else {
- fprintf(
- handle, "break if %s\n", conditional->code);
+ phpdbg_asprintf(&new_str, "%sbreak if %s\n", str, conditional->code);
}
} break;
}
+
+ if ((*str)[0]) {
+ efree(*str);
+ }
+ *str = new_str;
}
}
}
}
+
+ if (!(*str)[0]) {
+ *str = NULL;
+ }
} /* }}} */
PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRMLS_DC) /* {{{ */
@@ -221,7 +240,7 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML
php_stream_statbuf ssb;
char realpath[MAXPATHLEN];
const char *original_path = path;
- zend_bool pending;
+ zend_bool pending = 0;
HashTable *broken, *file_breaks = &PHPDBG_G(bp)[PHPDBG_BREAK_FILE];
phpdbg_breakfile_t new_break;
@@ -232,6 +251,8 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML
}
path_len = strlen(path);
+ phpdbg_debug("file path: %s, resolved path: %s, was compiled: %d\n", original_path, path, zend_hash_exists(&PHPDBG_G(file_sources), path, path_len));
+
if (!zend_hash_exists(&PHPDBG_G(file_sources), path, path_len)) {
if (php_stream_stat_path(path, &ssb) == FAILURE) {
if (original_path[0] == '/') {
@@ -246,6 +267,8 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML
} else if (!(ssb.sb.st_mode & (S_IFREG|S_IFLNK))) {
phpdbg_error("breakpoint", "type=\"notregular\" add=\"fail\" file=\"%s\"", "Cannot set breakpoint in %s, it is not a regular file", path);
return;
+ } else {
+ phpdbg_debug("File exists, but not compiled\n");
}
}
@@ -257,12 +280,35 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML
}
if (!zend_hash_index_exists(broken, line_num)) {
+ HashPosition position;
+ char *file;
+ uint filelen;
+
PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_FILE);
new_break.filename = estrndup(path, path_len);
new_break.line = line_num;
zend_hash_index_update(broken, line_num, (void **) &new_break, sizeof(phpdbg_breakfile_t), NULL);
+ PHPDBG_BREAK_MAPPING(new_break.id, broken);
+
+ if (pending) {
+ for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(file_sources), &position);
+ zend_hash_get_current_key_ex(&PHPDBG_G(file_sources), &file, &filelen, NULL, 0, &position) == HASH_KEY_IS_STRING;
+ zend_hash_move_forward_ex(&PHPDBG_G(file_sources), &position)) {
+ HashTable *fileht;
+
+ phpdbg_debug("Compare against loaded %s\n", file);
+
+ if (!(pending = ((fileht = phpdbg_resolve_pending_file_break_ex(file, filelen, path, path_len, broken TSRMLS_CC)) == NULL))) {
+ phpdbg_breakfile_t *brake;
+ zend_hash_index_find(fileht, line_num, (void **) &brake);
+ new_break = *brake;
+ break;
+ }
+ }
+ }
+
if (pending) {
PHPDBG_G(flags) |= PHPDBG_HAS_PENDING_FILE_BP;
@@ -272,70 +318,77 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML
phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" file=\"%s\" line=\"%ld\"", "Breakpoint #%d added at %s:%ld", new_break.id, new_break.filename, new_break.line);
}
-
- PHPDBG_BREAK_MAPPING(new_break.id, broken);
} else {
phpdbg_error("breakpoint", "type=\"exists\" add=\"fail\" file=\"%s\" line=\"%ld\"", "Breakpoint at %s:%ld exists", path, line_num);
}
} /* }}} */
-PHPDBG_API void phpdbg_resolve_pending_file_break(const char *file TSRMLS_DC) /* {{{ */
+PHPDBG_API HashTable *phpdbg_resolve_pending_file_break_ex(const char *file, uint filelen, const char *cur, uint curlen, HashTable *fileht TSRMLS_DC) /* {{{ */
{
- HashPosition position[2];
- HashTable *fileht;
- uint filelen = strlen(file);
+ phpdbg_debug("file: %s, filelen: %u, cur: %s, curlen %u, pos: %c, memcmp: %d\n", file, filelen, cur, curlen, filelen > curlen ? file[filelen - curlen - 1] : '?', filelen > curlen ? memcmp(file + filelen - curlen, cur, curlen) : 0);
- zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], &position[0]);
- while (zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], (void**) &fileht, &position[0]) == SUCCESS) {
- const char *cur;
- uint curlen;
+ if (((curlen < filelen && file[filelen - curlen - 1] == '/') || filelen == curlen) && !memcmp(file + filelen - curlen, cur, curlen)) {
+ phpdbg_breakfile_t *brake, new_brake;
+ HashTable *master = NULL;
+ HashPosition position;
- zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], (char **) &cur, &curlen, NULL, 0, &position[0]);
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], &position[0]);
+ PHPDBG_G(flags) |= PHPDBG_HAS_FILE_BP;
- if (curlen < filelen && file[filelen - curlen - 1] == '/' && !memcmp(file + filelen - curlen, cur, curlen)) {
- phpdbg_breakfile_t *brake, new_brake;
- HashTable *master = NULL;
- dtor_func_t dtor;
+ if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], file, filelen, (void **) &master) == FAILURE) {
+ HashTable new_ht;
+ zend_hash_init(&new_ht, 8, NULL, phpdbg_file_breaks_dtor, 0);
+ zend_hash_add(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], file, filelen, &new_ht, sizeof(HashTable), (void **) &master);
+ }
- PHPDBG_G(flags) |= PHPDBG_HAS_FILE_BP;
+ for (zend_hash_internal_pointer_reset_ex(fileht, &position);
+ zend_hash_get_current_data_ex(fileht, (void**)&brake, &position) == SUCCESS;
+ zend_hash_move_forward_ex(fileht, &position)) {
+ new_brake = *brake;
+ new_brake.filename = estrndup(file, filelen);
+ PHPDBG_BREAK_UNMAPPING(brake->id);
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], file, filelen, (void **) &master) == FAILURE) {
- dtor = PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING].pDestructor;
- PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING].pDestructor = NULL;
- zend_hash_add(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], file, filelen, fileht, sizeof(HashTable), (void **) &fileht);
+ if (master) {
+ zend_hash_index_update(master, brake->line, (void **) &new_brake, sizeof(phpdbg_breakfile_t), NULL);
+ PHPDBG_BREAK_MAPPING(brake->id, master);
}
+ }
- for (zend_hash_internal_pointer_reset_ex(fileht, &position[1]);
- zend_hash_get_current_data_ex(fileht, (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex(fileht, &position[1])) {
- new_brake = *brake;
- new_brake.filename = estrndup(file, filelen);
- PHPDBG_BREAK_UNMAPPING(brake->id);
-
- if (master) {
- zend_hash_index_update(master, brake->line, (void **) &new_brake, sizeof(phpdbg_breakfile_t), NULL);
- PHPDBG_BREAK_MAPPING(brake->id, master);
- } else {
- efree((char *) brake->filename);
- *brake = new_brake;
- PHPDBG_BREAK_MAPPING(brake->id, fileht);
- }
- }
+ zend_hash_del(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], cur, curlen);
- zend_hash_del(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], cur, curlen);
+ if (!zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING])) {
+ PHPDBG_G(flags) &= ~PHPDBG_HAS_PENDING_FILE_BP;
+ }
- if (!master) {
- PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING].pDestructor = dtor;
- }
+ phpdbg_debug("compiled file: %s, cur bp file: %s\n", file, cur);
- if (!zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING])) {
- PHPDBG_G(flags) &= ~PHPDBG_HAS_PENDING_FILE_BP;
- }
- }
+ return master;
}
+
+ return NULL;
} /* }}} */
+PHPDBG_API void phpdbg_resolve_pending_file_break(const char *file TSRMLS_DC) /* {{{ */
+{
+ HashPosition position;
+ HashTable *fileht;
+ uint filelen = strlen(file);
+
+ phpdbg_debug("was compiled: %s\n", file);
+
+ zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], &position);
+ while (zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], (void**) &fileht, &position) == SUCCESS) {
+ const char *cur;
+ uint curlen;
+
+ zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], (char **) &cur, &curlen, NULL, 0, &position);
+ zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], &position);
+
+ phpdbg_debug("check bp: %s\n", cur);
+
+ phpdbg_resolve_pending_file_break_ex(file, filelen, cur, curlen, fileht TSRMLS_CC);
+ }
+}
+
PHPDBG_API void phpdbg_set_breakpoint_symbol(const char *name, size_t name_len TSRMLS_DC) /* {{{ */
{
if (!zend_hash_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], name, name_len)) {
@@ -850,10 +903,21 @@ static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_file(zend_op_array *op_
{
HashTable *breaks;
phpdbg_breakbase_t *brake;
- size_t name_len = strlen(op_array->filename);
+ size_t path_len;
+ char realpath[MAXPATHLEN];
+ const char *path = op_array->filename;
+
+ if (VCWD_REALPATH(path, realpath)) {
+ path = realpath;
+ }
+
+ path_len = strlen(path);
+
+#if 0
+ phpdbg_debug("Op at: %.*s %d\n", path_len, path, (*EG(opline_ptr))->lineno);
+#endif
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], op_array->filename,
- name_len, (void**)&breaks) == FAILURE) {
+ if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], path, path_len, (void**)&breaks) == FAILURE) {
return NULL;
}
diff --git a/sapi/phpdbg/phpdbg_bp.h b/sapi/phpdbg/phpdbg_bp.h
index 606085ddcf..63a9961d2a 100644
--- a/sapi/phpdbg/phpdbg_bp.h
+++ b/sapi/phpdbg/phpdbg_bp.h
@@ -121,6 +121,7 @@ typedef struct _phpdbg_breakcond_t {
PHPDBG_API void phpdbg_resolve_op_array_breaks(zend_op_array *op_array TSRMLS_DC);
PHPDBG_API int phpdbg_resolve_op_array_break(phpdbg_breakopline_t *brake, zend_op_array *op_array TSRMLS_DC);
PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRMLS_DC);
+PHPDBG_API HashTable *phpdbg_resolve_pending_file_break_ex(const char *file, uint filelen, const char *cur, uint curlen, HashTable *fileht TSRMLS_DC);
PHPDBG_API void phpdbg_resolve_pending_file_break(const char *file TSRMLS_DC); /* }}} */
/* {{{ Breakpoint Creation API */
@@ -156,6 +157,7 @@ PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase(zend_ulong id TSRMLS_DC);
PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable ***table, HashPosition *position TSRMLS_DC); /* }}} */
/* {{{ Breakpoint Exportation API */
-PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC); /* }}} */
+PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC);
+PHPDBG_API void phpdbg_export_breakpoints_to_string(char **str TSRMLS_DC); /* }}} */
#endif /* PHPDBG_BP_H */
diff --git a/sapi/phpdbg/phpdbg_frame.c b/sapi/phpdbg/phpdbg_frame.c
index 437e6d474a..0506c305dc 100644
--- a/sapi/phpdbg/phpdbg_frame.c
+++ b/sapi/phpdbg/phpdbg_frame.c
@@ -25,7 +25,6 @@
#include "phpdbg_list.h"
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
-ZEND_EXTERN_MODULE_GLOBALS(output);
void phpdbg_restore_frame(TSRMLS_D) /* {{{ */
{
diff --git a/sapi/phpdbg/phpdbg_help.c b/sapi/phpdbg/phpdbg_help.c
index 652e170694..d47f8c776a 100644
--- a/sapi/phpdbg/phpdbg_help.c
+++ b/sapi/phpdbg/phpdbg_help.c
@@ -388,7 +388,9 @@ phpdbg_help_text_t phpdbg_help_text[] = {
" **-S** **-S**cli Override SAPI name, careful!" CR
" **-l** **-l**4000 Setup remote console ports" CR
" **-a** **-a**192.168.0.3 Setup remote console bind address" CR
+#if PHPDBG_IN_DEV
" **-x** Enable xml output (instead of normal text output)" CR
+#endif
" **-V** Print version number" CR
" **--** **--** arg1 arg2 Use to delimit phpdbg arguments and php $argv; append any $argv "
"argument after it" CR CR
diff --git a/sapi/phpdbg/phpdbg_io.c b/sapi/phpdbg/phpdbg_io.c
index 6908a687d7..a2a5c5969f 100644
--- a/sapi/phpdbg/phpdbg_io.c
+++ b/sapi/phpdbg/phpdbg_io.c
@@ -187,10 +187,6 @@ PHPDBG_API int phpdbg_mixed_read(int sock, char *ptr, int len, int tmo TSRMLS_DC
PHPDBG_API int phpdbg_mixed_write(int sock, const char *ptr, int len TSRMLS_DC) {
- if (PHPDBG_G(flags) & PHPDBG_DISCARD_OUTPUT) {
- return 0;
- }
-
if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) {
return phpdbg_send_bytes(sock, ptr, len);
}
diff --git a/sapi/phpdbg/phpdbg_out.c b/sapi/phpdbg/phpdbg_out.c
index 365708c71e..7e1dc7b744 100644
--- a/sapi/phpdbg/phpdbg_out.c
+++ b/sapi/phpdbg/phpdbg_out.c
@@ -1168,6 +1168,10 @@ PHPDBG_API int phpdbg_output_err_buf(const char *tag, const char *xmlfmt, const
va_list args;
int errbuf_active = PHPDBG_G(err_buf).active;
+ if (PHPDBG_G(flags) & PHPDBG_DISCARD_OUTPUT) {
+ return 0;
+ }
+
PHPDBG_G(err_buf).active = 0;
#ifdef ZTS
@@ -1188,6 +1192,10 @@ PHPDBG_API int phpdbg_print(int type TSRMLS_DC, int fd, const char *tag, const c
va_list args;
int len;
+ if (PHPDBG_G(flags) & PHPDBG_DISCARD_OUTPUT) {
+ return 0;
+ }
+
va_start(args, strfmt);
len = phpdbg_vprint(type TSRMLS_CC, fd, tag, xmlfmt, strfmt, args);
va_end(args);
@@ -1198,6 +1206,10 @@ PHPDBG_API int phpdbg_print(int type TSRMLS_DC, int fd, const char *tag, const c
PHPDBG_API int phpdbg_xml_internal(int fd TSRMLS_DC, const char *fmt, ...) {
int len = 0;
+ if (PHPDBG_G(flags) & PHPDBG_DISCARD_OUTPUT) {
+ return 0;
+ }
+
if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
va_list args;
char *buffer;
@@ -1243,6 +1255,10 @@ PHPDBG_API int phpdbg_out_internal(int fd TSRMLS_DC, const char *fmt, ...) {
int buflen;
int len = 0;
+ if (PHPDBG_G(flags) & PHPDBG_DISCARD_OUTPUT) {
+ return 0;
+ }
+
va_start(args, fmt);
buflen = phpdbg_xml_vasprintf(&buffer, fmt, 0, args TSRMLS_CC);
va_end(args);
diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c
index 5e2cc03d50..f030654f3b 100644
--- a/sapi/phpdbg/phpdbg_prompt.c
+++ b/sapi/phpdbg/phpdbg_prompt.c
@@ -41,7 +41,6 @@
#include "phpdbg_eol.h"
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
-ZEND_EXTERN_MODULE_GLOBALS(output);
extern int phpdbg_startup_run;
#ifdef HAVE_LIBDL
@@ -83,7 +82,9 @@ const phpdbg_command_t phpdbg_prompt_commands[] = {
PHPDBG_COMMAND_D(export, "export breaks to a .phpdbginit script", '>', NULL, "s", PHPDBG_ASYNC_SAFE),
PHPDBG_COMMAND_D(sh, "shell a command", 0 , NULL, "i", 0),
PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0, PHPDBG_ASYNC_SAFE),
+#if PHPDBG_IN_DEV
PHPDBG_COMMAND_D(wait, "wait for other process", 'W', NULL, 0, 0),
+#endif
PHPDBG_COMMAND_D(watch, "set watchpoint", 'w', phpdbg_watch_commands, "|ss", 0),
PHPDBG_COMMAND_D(eol, "set EOL", 'E', NULL, "|s", 0),
PHPDBG_END_COMMAND
@@ -208,98 +209,128 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ *
return FAILURE;
} /* }}} */
-void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC) /* {{{ */
-{
- struct stat sb;
+struct phpdbg_init_state {
+ int line;
+ zend_bool in_code;
+ char *code;
+ size_t code_len;
+ const char *init_file;
+};
- if (init_file && VCWD_STAT(init_file, &sb) != -1) {
- FILE *fp = fopen(init_file, "r");
- if (fp) {
- int line = 1;
+static void phpdbg_line_init(char *cmd, struct phpdbg_init_state *state TSRMLS_DC) {
+ size_t cmd_len = strlen(cmd);
- char cmd[PHPDBG_MAX_CMD];
- size_t cmd_len = 0L;
- char *code = NULL;
- size_t code_len = 0L;
- zend_bool in_code = 0;
+ state->line++;
- while (fgets(cmd, PHPDBG_MAX_CMD, fp) != NULL) {
- cmd_len = strlen(cmd)-1;
-
- while (cmd_len > 0L && isspace(cmd[cmd_len-1]))
- cmd_len--;
-
- cmd[cmd_len] = '\0';
-
- if (*cmd && cmd_len > 0L && cmd[0] != '#') {
- if (cmd_len == 2) {
- if (memcmp(cmd, "<:", sizeof("<:")-1) == SUCCESS) {
- in_code = 1;
- goto next_line;
- } else {
- if (memcmp(cmd, ":>", sizeof(":>")-1) == SUCCESS) {
- in_code = 0;
- code[code_len] = '\0';
- {
- zend_eval_stringl(code, code_len, NULL, "phpdbginit code" TSRMLS_CC);
- }
- free(code);
- code = NULL;
- goto next_line;
- }
- }
- }
+ while (cmd_len > 0L && isspace(cmd[cmd_len-1])) {
+ cmd_len--;
+ }
- if (in_code) {
- if (code == NULL) {
- code = malloc(cmd_len + 1);
- } else code = realloc(code, code_len + cmd_len + 1);
+ cmd[cmd_len] = '\0';
- if (code) {
- memcpy(
- &code[code_len], cmd, cmd_len);
- code_len += cmd_len;
- }
- goto next_line;
- }
+ if (*cmd && cmd_len > 0L && cmd[0] != '#') {
+ if (cmd_len == 2) {
+ if (memcmp(cmd, "<:", sizeof("<:")-1) == SUCCESS) {
+ state->in_code = 1;
+ return;
+ } else {
+ if (memcmp(cmd, ":>", sizeof(":>")-1) == SUCCESS) {
+ state->in_code = 0;
+ state->code[state->code_len] = '\0';
+ zend_eval_stringl(state->code, state->code_len, NULL, "phpdbginit code" TSRMLS_CC);
+ free(state->code);
+ state->code = NULL;
+ return;
+ }
+ }
+ }
- zend_try {
- char *input = phpdbg_read_input(cmd TSRMLS_CC);
- phpdbg_param_t stack;
+ if (state->in_code) {
+ if (state->code == NULL) {
+ state->code = malloc(cmd_len + 1);
+ } else {
+ state->code = realloc(state->code, state->code_len + cmd_len + 1);
+ }
- phpdbg_init_param(&stack, STACK_PARAM);
+ if (state->code) {
+ memcpy(&state->code[state->code_len], cmd, cmd_len);
+ state->code_len += cmd_len;
+ }
- phpdbg_activate_err_buf(1 TSRMLS_CC);
+ return;
+ }
- if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) {
- switch (phpdbg_stack_execute(&stack, 1 /* allow_async_unsafe == 1 */ TSRMLS_CC)) {
- case FAILURE:
- phpdbg_activate_err_buf(0 TSRMLS_CC);
- if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) {
- phpdbg_output_err_buf("initfailure", "%b file=\"%s\" line=\"%d\" input=\"%s\"", "Unrecognized command in %s:%d: %s, %b!" TSRMLS_CC, init_file, line, input);
- }
- break;
- }
- }
+ zend_try {
+ char *input = phpdbg_read_input(cmd TSRMLS_CC);
+ phpdbg_param_t stack;
+
+ phpdbg_init_param(&stack, STACK_PARAM);
+
+ phpdbg_activate_err_buf(1 TSRMLS_CC);
+ if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) {
+ switch (phpdbg_stack_execute(&stack, 1 /* allow_async_unsafe == 1 */ TSRMLS_CC)) {
+ case FAILURE:
phpdbg_activate_err_buf(0 TSRMLS_CC);
- phpdbg_free_err_buf(TSRMLS_C);
-
- phpdbg_stack_free(&stack);
- phpdbg_destroy_input(&input TSRMLS_CC);
- } zend_catch {
- PHPDBG_G(flags) &= ~(PHPDBG_IS_RUNNING | PHPDBG_IS_CLEANING);
- if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) {
- zend_bailout();
+ if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) {
+ if (state->init_file) {
+ phpdbg_output_err_buf("initfailure", "%b file=\"%s\" line=\"%d\" input=\"%s\"", "Unrecognized command in %s:%d: %s, %b!" TSRMLS_CC, state->init_file, state->line, input);
+ } else {
+ phpdbg_output_err_buf("initfailure", "%b line=\"%d\" input=\"%s\"", "Unrecognized command on line %d: %s, %b!" TSRMLS_CC, state->line, input);
+ }
}
- } zend_end_try();
+ break;
}
-next_line:
- line++;
}
- if (code) {
- free(code);
+ phpdbg_activate_err_buf(0 TSRMLS_CC);
+ phpdbg_free_err_buf(TSRMLS_C);
+
+ phpdbg_stack_free(&stack);
+ phpdbg_destroy_input(&input TSRMLS_CC);
+ } zend_catch {
+ PHPDBG_G(flags) &= ~(PHPDBG_IS_RUNNING | PHPDBG_IS_CLEANING);
+ if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) {
+ zend_bailout();
+ }
+ } zend_end_try();
+ }
+
+}
+
+void phpdbg_string_init(char *buffer TSRMLS_DC) {
+ struct phpdbg_init_state state = {0};
+ char *str = strtok(buffer, "\n");
+
+ while (str) {
+ phpdbg_line_init(str, &state TSRMLS_CC);
+
+ str = strtok(NULL, "\n");
+ }
+
+ if (state.code) {
+ free(state.code);
+ }
+}
+
+void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC) /* {{{ */
+{
+ struct stat sb;
+
+ if (init_file && VCWD_STAT(init_file, &sb) != -1) {
+ FILE *fp = fopen(init_file, "r");
+ if (fp) {
+ char cmd[PHPDBG_MAX_CMD];
+ struct phpdbg_init_state state = {0};
+
+ state.init_file = init_file;
+
+ while (fgets(cmd, PHPDBG_MAX_CMD, fp) != NULL) {
+ phpdbg_line_init(cmd, &state TSRMLS_CC);
+ }
+
+ if (state.code) {
+ free(state.code);
}
fclose(fp);
@@ -653,6 +684,10 @@ PHPDBG_COMMAND(run) /* {{{ */
EG(opline_ptr) = orig_opline;
EG(return_value_ptr_ptr) = orig_retval_ptr;
+ if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) {
+ zend_bailout();
+ }
+
if (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)) {
phpdbg_error("stop", "type=\"bailout\"", "Caught exit/error from VM");
restore = 0;
@@ -672,10 +707,10 @@ PHPDBG_COMMAND(run) /* {{{ */
EG(active_op_array) = orig_op_array;
EG(opline_ptr) = orig_opline;
EG(return_value_ptr_ptr) = orig_retval_ptr;
-
- phpdbg_clean(1 TSRMLS_CC);
}
+ phpdbg_clean(1 TSRMLS_CC);
+
PHPDBG_G(flags) &= ~PHPDBG_IS_RUNNING;
} else {
phpdbg_error("inactive", "type=\"nocontext\"", "Nothing to execute!");
@@ -1128,7 +1163,7 @@ PHPDBG_COMMAND(register) /* {{{ */
phpdbg_notice("register", "function=\"%s\"", "Registered %s", lcname);
} else {
- phpdbg_error("register", "type=\"notfoundc\" function=\"%s\"", "The requested function (%s) could not be found", param->str);
+ phpdbg_error("register", "type=\"notfound\" function=\"%s\"", "The requested function (%s) could not be found", param->str);
}
} else {
phpdbg_error("register", "type=\"inuse\" function=\"%s\"", "The requested name (%s) is already in use", lcname);
@@ -1143,6 +1178,7 @@ PHPDBG_COMMAND(quit) /* {{{ */
/* don't allow this to loop, ever ... */
if (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)) {
PHPDBG_G(flags) |= PHPDBG_IS_QUITTING;
+ PHPDBG_G(flags) &= ~(PHPDBG_IS_RUNNING | PHPDBG_IS_CLEANING);
zend_bailout();
}
@@ -1438,7 +1474,7 @@ void phpdbg_execute_ex(zend_op_array *op_array TSRMLS_DC) /* {{{ */
}
#endif
- if ((PHPDBG_G(flags) & (PHPDBG_IS_STOPPING | PHPDBG_IS_RUNNING)) == PHPDBG_IS_STOPPING) {
+ if ((PHPDBG_G(flags) & PHPDBG_IS_STOPPING) && !(PHPDBG_G(flags) & PHPDBG_IS_RUNNING)) {
zend_bailout();
}
diff --git a/sapi/phpdbg/phpdbg_prompt.h b/sapi/phpdbg/phpdbg_prompt.h
index 94e24df833..f583f2cdcd 100644
--- a/sapi/phpdbg/phpdbg_prompt.h
+++ b/sapi/phpdbg/phpdbg_prompt.h
@@ -22,6 +22,7 @@
#define PHPDBG_PROMPT_H
/* {{{ */
+void phpdbg_string_init(char *buffer TSRMLS_DC);
void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TSRMLS_DC);
void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC);
int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC);
diff --git a/sapi/phpdbg/phpdbg_rinit_hook.c b/sapi/phpdbg/phpdbg_rinit_hook.c
index 049a782d9d..11bd5c99b1 100644
--- a/sapi/phpdbg/phpdbg_rinit_hook.c
+++ b/sapi/phpdbg/phpdbg_rinit_hook.c
@@ -52,7 +52,7 @@ static PHP_RINIT_FUNCTION(phpdbg_webhelper) /* {{{ */
return SUCCESS;
}
-#ifndef _WIN32
+#if PHPDBG_IN_DEV
{
struct sockaddr_un sock;
int s = socket(AF_UNIX, SOCK_STREAM, 0);
@@ -99,3 +99,7 @@ zend_module_entry phpdbg_webhelper_module_entry = {
PHPDBG_VERSION,
STANDARD_MODULE_PROPERTIES
};
+
+#ifdef COMPILE_DL_PHPDBG_WEBHELPER
+ZEND_GET_MODULE(phpdbg_webhelper)
+#endif
diff --git a/sapi/phpdbg/phpdbg_sigio_win32.c b/sapi/phpdbg/phpdbg_sigio_win32.c
index 24e9ac0e0a..158e034872 100644
--- a/sapi/phpdbg/phpdbg_sigio_win32.c
+++ b/sapi/phpdbg/phpdbg_sigio_win32.c
@@ -33,30 +33,31 @@ SigIoWatcherThread(VOID *p)
struct win32_sigio_watcher_data *swd = (struct win32_sigio_watcher_data *)p;
#ifdef ZTS
void ***tsrm_ls = swd->tsrm_ls;
-top:
- (void)phpdbg_consume_bytes(swd->fd, &sig, 1, -1, tsrm_ls);
-#else
-top:
- (void)phpdbg_consume_bytes(swd->fd, &sig, 1, -1);
#endif
+top:
+ (void)phpdbg_consume_bytes(swd->fd, &sig, 1, -1 TSRMLS_CC);
+
if (3 == sig) {
- printf("signaled, got %d", sig);
/* XXX completely not sure it is done right here */
- if (swd->flags & PHPDBG_IS_INTERACTIVE) {
+ if (PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE) {
if (raise(sig)) {
- /* just out*/
- exit(0);
+ goto top;
}
}
- if (swd->flags & PHPDBG_IS_SIGNALED) {
+ if (PHPDBG_G(flags) & PHPDBG_IS_SIGNALED) {
phpdbg_set_sigsafe_mem(&sig TSRMLS_CC);
zend_try {
phpdbg_force_interruption(TSRMLS_C);
} zend_end_try();
phpdbg_clear_sigsafe_mem(TSRMLS_C);
+ goto end;
+ }
+ if (!(PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE)) {
+ PHPDBG_G(flags) |= PHPDBG_IS_SIGNALED;
}
+end:
/* XXX set signaled flag to the caller thread, question is - whether it's needed */
ExitThread(sig);
} else {
@@ -74,8 +75,6 @@ sigio_watcher_start(void)
TSRMLS_FETCH();
PHPDBG_G(swd).fd = PHPDBG_G(io)[PHPDBG_STDIN].fd;
- PHPDBG_G(swd).running = 1;
- PHPDBG_G(swd).flags = PHPDBG_G(flags);
#ifdef ZTS
PHPDBG_G(swd).tsrm_ls = tsrm_ls;
#endif
@@ -113,8 +112,6 @@ sigio_watcher_stop(void)
}
PHPDBG_G(swd).fd = -1;
- PHPDBG_G(swd).running = 0;
- PHPDBG_G(swd).flags = 0;
PHPDBG_G(sigio_watcher_thread) = INVALID_HANDLE_VALUE;
}
diff --git a/sapi/phpdbg/phpdbg_sigio_win32.h b/sapi/phpdbg/phpdbg_sigio_win32.h
index 796b477f93..8c8a381d64 100644
--- a/sapi/phpdbg/phpdbg_sigio_win32.h
+++ b/sapi/phpdbg/phpdbg_sigio_win32.h
@@ -25,12 +25,10 @@
#include "phpdbg_io.h"
struct win32_sigio_watcher_data {
- zend_ulong flags;
#ifdef ZTS
void ***tsrm_ls;
#endif
int fd;
- zend_uchar running;
};
void
diff --git a/sapi/phpdbg/phpdbg_wait.c b/sapi/phpdbg/phpdbg_wait.c
index ea506a2d93..180ae6af3d 100644
--- a/sapi/phpdbg/phpdbg_wait.c
+++ b/sapi/phpdbg/phpdbg_wait.c
@@ -18,11 +18,10 @@
#include "phpdbg_wait.h"
#include "phpdbg_prompt.h"
-#include "ext/json/JSON_parser.h"
+#include "ext/standard/php_var.h"
#include "ext/standard/basic_functions.h"
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
-ZEND_EXTERN_MODULE_GLOBALS(json);
static void phpdbg_rebuild_http_globals_array(int type, const char *name TSRMLS_DC) {
zval **zvpp;
@@ -127,16 +126,18 @@ static int phpdbg_array_intersect(phpdbg_intersect_ptr *info, zval ***ptr) {
}
void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) {
-#ifdef HAVE_JSON
zval *free_zv = NULL;
- zval zv, **zvpp;
+ zval zv, *zvp = &zv, **zvpp;
HashTable *ht;
- php_json_decode(&zv, msg, len, 1, 1000 /* enough */ TSRMLS_CC);
+ php_unserialize_data_t var_hash;
- if (JSON_G(error_code) != PHP_JSON_ERROR_NONE) {
- phpdbg_error("wait", "type=\"invaliddata\" import=\"fail\"", "Malformed JSON was sent to this socket, arborting");
+ PHP_VAR_UNSERIALIZE_INIT(var_hash);
+ if (!php_var_unserialize(&zvp, (const unsigned char **) &msg, (unsigned char *) msg + len, &var_hash TSRMLS_CC)) {
+ PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
+ phpdbg_error("wait", "type=\"invaliddata\" import=\"fail\"", "Malformed serialized was sent to this socket, arborting");
return;
}
+ PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
ht = Z_ARRVAL(zv);
@@ -172,6 +173,7 @@ void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) {
free_zv = *zvpp;
}
+#if PHP_VERSION_ID >= 50600
if (zend_hash_find(ht, "input", sizeof("input"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_STRING) {
if (SG(request_info).request_body) {
php_stream_close(SG(request_info).request_body);
@@ -180,6 +182,7 @@ void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) {
php_stream_truncate_set_size(SG(request_info).request_body, 0);
php_stream_write(SG(request_info).request_body, Z_STRVAL_PP(zvpp), Z_STRLEN_PP(zvpp));
}
+#endif
if (zend_hash_find(ht, "cwd", sizeof("cwd"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_STRING) {
if (VCWD_CHDIR(Z_STRVAL_PP(zvpp)) == SUCCESS) {
@@ -358,12 +361,11 @@ void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) {
/* Reapply raw input */
/* ??? */
-#endif
}
PHPDBG_COMMAND(wait) /* {{{ */
{
-#ifdef HAVE_JSON
+#if PHPDBG_IN_DEV
struct sockaddr_un local, remote;
int rlen, sr, sl;
unlink(PHPDBG_G(socket_path));
@@ -413,7 +415,7 @@ PHPDBG_COMMAND(wait) /* {{{ */
efree(data);
phpdbg_notice("wait", "import=\"success\"", "Successfully imported request data, stopped before executing");
+#endif
return SUCCESS;
-#endif
} /* }}} */
diff --git a/sapi/phpdbg/phpdbg_webdata_transfer.c b/sapi/phpdbg/phpdbg_webdata_transfer.c
index e7438ea01a..7c169ee113 100644
--- a/sapi/phpdbg/phpdbg_webdata_transfer.c
+++ b/sapi/phpdbg/phpdbg_webdata_transfer.c
@@ -17,11 +17,9 @@
*/
#include "phpdbg_webdata_transfer.h"
-#include "ext/json/php_json.h"
+#include "ext/standard/php_var.h"
PHPDBG_API void phpdbg_webdata_compress(char **msg, int *len TSRMLS_DC) {
-#ifdef HAVE_JSON
- smart_str buf = {0};
zval array;
HashTable *ht;
/* I really need to change that to an array of zvals... */
@@ -51,6 +49,7 @@ PHPDBG_API void phpdbg_webdata_compress(char **msg, int *len TSRMLS_DC) {
zend_hash_add(ht, "GLOBALS", sizeof("GLOBALS"), &zvp1, sizeof(zval *), NULL);
}
+#if PHP_VERSION_ID >= 50600
/* save php://input */
{
php_stream *stream;
@@ -66,6 +65,7 @@ PHPDBG_API void phpdbg_webdata_compress(char **msg, int *len TSRMLS_DC) {
Z_SET_REFCOUNT(zv2, 2);
zend_hash_add(ht, "input", sizeof("input"), &zvp2, sizeof(zval *), NULL);
}
+#endif
/* change sapi name */
{
@@ -177,9 +177,17 @@ PHPDBG_API void phpdbg_webdata_compress(char **msg, int *len TSRMLS_DC) {
}
/* encode data */
- php_json_encode(&buf, &array, 0 TSRMLS_CC);
- *msg = buf.c;
- *len = buf.len;
+ {
+ php_serialize_data_t var_hash;
+ smart_str buf = {0};
+ zval *arrayptr = &array;
+
+ PHP_VAR_SERIALIZE_INIT(var_hash);
+ php_var_serialize(&buf, &arrayptr, &var_hash TSRMLS_CC);
+ PHP_VAR_SERIALIZE_DESTROY(var_hash);
+ *msg = buf.c;
+ *len = buf.len;
+ }
+
zval_dtor(&array);
-#endif
}