diff options
author | Rasmus Lerdorf <rasmus@php.net> | 2014-11-06 10:19:45 -0800 |
---|---|---|
committer | Rasmus Lerdorf <rasmus@php.net> | 2014-11-06 10:19:45 -0800 |
commit | 2375d659d7ba006429d4b3a28cf8a158f24b30db (patch) | |
tree | 608223966abbd29a02080b3cd99ca4847149c10a | |
parent | 50756b515c76bb9c43a01bfce03207906f596005 (diff) | |
parent | 8fccf0bac9eab67412612b2df14da58b9129c6b2 (diff) | |
download | php-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...
...
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 @@ -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(¶m->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 } |