From f8efdc2b4bca2a8f7e57aae36a01df044ba3d0b5 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 22 Jul 2013 00:56:45 -0700 Subject: [PATCH 01/10] fix bug #65028 Phar::buildFromDirectory creates corrupt archives for some specific contents --- NEWS | 4 + ext/phar/phar.c | 23 ++++++ ext/phar/tests/bug65028.phpt | 156 +++++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+) create mode 100644 ext/phar/tests/bug65028.phpt diff --git a/NEWS b/NEWS index e71d0727357..f76497b3e44 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,10 @@ PHP NEWS . Fixed bug #50308 (session id not appended properly for empty anchor tags). (Arpad) +- Phar: + . Fixed bug #65028 (Phar::buildFromDirectory creates corrupt archives for + some specific contents). (Stas) + ?? ??? 2013, PHP 5.4.18 - Core: diff --git a/ext/phar/phar.c b/ext/phar/phar.c index c5042cc34ac..c85687ef5ce 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -2579,6 +2579,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert, php_serialize_data_t metadata_hash; smart_str main_metadata_str = {0}; int free_user_stub, free_fp = 1, free_ufp = 1; + int manifest_hack = 0; if (phar->is_persistent) { if (error) { @@ -2930,6 +2931,12 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert, manifest_len = offset + phar->alias_len + sizeof(manifest) + main_metadata_str.len; phar_set_32(manifest, manifest_len); + /* Hack - see bug #65028, add padding byte to the end of the manifest */ + if(manifest[0] == '\r' || manifest[0] == '\n') { + manifest_len++; + phar_set_32(manifest, manifest_len); + manifest_hack = 1; + } phar_set_32(manifest+4, new_manifest_count); if (has_dirs) { *(manifest + 8) = (unsigned char) (((PHAR_API_VERSION) >> 8) & 0xFF); @@ -3054,6 +3061,22 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert, return EOF; } } + /* Hack - see bug #65028, add padding byte to the end of the manifest */ + if(manifest_hack) { + if(1 != php_stream_write(newfile, manifest, 1)) { + if (closeoldfile) { + php_stream_close(oldfile); + } + + php_stream_close(newfile); + + if (error) { + spprintf(error, 0, "unable to write manifest padding byte"); + } + + return EOF; + } + } /* now copy the actual file data to the new phar */ offset = php_stream_tell(newfile); diff --git a/ext/phar/tests/bug65028.phpt b/ext/phar/tests/bug65028.phpt new file mode 100644 index 00000000000..74273b850b0 --- /dev/null +++ b/ext/phar/tests/bug65028.phpt @@ -0,0 +1,156 @@ +--TEST-- +Phar - test specific manifest length +--INI-- +phar.readonly=0 +--SKIPIF-- + +--FILE-- +addFromString($file, ""); +} + +// Copy phar +copy(__DIR__ . "/bug65028.phar", __DIR__ . "/bug65028-copy.phar"); + +// Open phar +try +{ + $phar = new Phar(__DIR__ . "/bug65028-copy.phar"); + echo "No exception thrown.\n"; +} +catch(UnexpectedValueException $ex) +{ + echo "Exception thrown: " . $ex->getMessage() . "\n"; +} +?> +--CLEAN-- + +--EXPECT-- +No exception thrown. + From 9b6aa268a3ab431b7dcd592b922dbc399202e58d Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 23 Jul 2013 09:59:08 +0200 Subject: [PATCH 02/10] fixed bug #65311 testsuite failure due to incomplete fix to bug28985.phpt --- ext/soap/tests/bugs/bug28985.phpt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/soap/tests/bugs/bug28985.phpt b/ext/soap/tests/bugs/bug28985.phpt index 5134cbf0995..73ff899c395 100644 --- a/ext/soap/tests/bugs/bug28985.phpt +++ b/ext/soap/tests/bugs/bug28985.phpt @@ -44,7 +44,7 @@ array(42) { string iUserPassword; }" [8]=> - string(86) "struct MGCodeLibelle { + string(87) "struct MGCodeLibelle { string Code; string Libelle; boolean Default; @@ -203,4 +203,4 @@ array(42) { string(76) "struct GetEnvironnementResponse { MGEnvironnement GetEnvironnementResult; }" -} \ No newline at end of file +} From 063e10b275159dc9d50228f451f94d6990a41f6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Schl=C3=BCter?= Date: Tue, 23 Jul 2013 12:41:24 +0200 Subject: [PATCH 03/10] Fix comment --- Zend/zend_hash.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index bf3577124d7..69732cd5975 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -28,7 +28,7 @@ #define HASH_KEY_IS_STRING 1 #define HASH_KEY_IS_LONG 2 #define HASH_KEY_NON_EXISTENT 3 -#define HASH_KEY_NON_EXISTANT HASH_KEY_NON_EXISTENT // Keeping old define (with typo) for backward compatibility +#define HASH_KEY_NON_EXISTANT HASH_KEY_NON_EXISTENT /* Keeping old define (with typo) for backward compatibility */ #define HASH_UPDATE (1<<0) #define HASH_ADD (1<<1) From c28ab73d7346e332594c30a9a544cfd74b8bc5bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Schl=C3=BCter?= Date: Tue, 23 Jul 2013 12:50:37 +0200 Subject: [PATCH 04/10] Fix compiler warning on redefined constant --- ext/pdo_mysql/mysql_driver.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c index a703f93e7cf..32d13bafaf3 100644 --- a/ext/pdo_mysql/mysql_driver.c +++ b/ext/pdo_mysql/mysql_driver.c @@ -527,9 +527,9 @@ static struct pdo_dbh_methods mysql_methods = { /* }}} */ #ifdef PHP_WIN32 -# define MYSQL_UNIX_ADDR NULL +# define PDO_DEFAULT_MYSQL_UNIX_ADDR NULL #else -# define MYSQL_UNIX_ADDR PDO_MYSQL_G(default_socket) +# define PDO_DEFAULT_MYSQL_UNIX_ADDR PDO_MYSQL_G(default_socket) #endif /* {{{ pdo_mysql_handle_factory */ @@ -545,7 +545,7 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_ { "dbname", "", 0 }, { "host", "localhost", 0 }, { "port", "3306", 0 }, - { "unix_socket", MYSQL_UNIX_ADDR, 0 }, + { "unix_socket", PDO_DEFAULT_MYSQL_UNIX_ADDR, 0 }, }; int connect_opts = 0 #ifdef CLIENT_MULTI_RESULTS From 7b92a227726106917a65c42676f87a88267a4770 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Schl=C3=BCter?= Date: Tue, 23 Jul 2013 14:13:22 +0200 Subject: [PATCH 05/10] Fix bug 65299 --- NEWS | 3 +++ ext/pdo_mysql/mysql_driver.c | 2 +- ext/pdo_mysql/pdo_mysql.c | 2 +- ext/pdo_mysql/php_pdo_mysql_int.h | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 18bb2fd013f..12ab1191300 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,9 @@ PHP NEWS . Fixed bug #65291 (get_defined_constants() causes PHP to crash in a very limited case). (Arpad) +- PDO_mysql: + . Fixed bug #65299 (pdo mysql parsing errors). (Johannes) + - SPL: . Added RecursiveTreeIterator setPostfix and getPostifx methods. (Joshua Thijssen) diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c index bf90f431611..cd86503dd76 100644 --- a/ext/pdo_mysql/mysql_driver.c +++ b/ext/pdo_mysql/mysql_driver.c @@ -710,7 +710,7 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_ } } -#if MYSQL_VERSION_ID > 50605 || defined(MYSQLI_USE_MYSQLND) +#if MYSQL_VERSION_ID > 50605 || defined(PDO_USE_MYSQLND) { char *public_key = pdo_attr_strval(driver_options, PDO_MYSQL_ATTR_SERVER_PUBLIC_KEY, NULL TSRMLS_CC); if (public_key) { diff --git a/ext/pdo_mysql/pdo_mysql.c b/ext/pdo_mysql/pdo_mysql.c index 401d20d8b3b..78c4ceefe91 100644 --- a/ext/pdo_mysql/pdo_mysql.c +++ b/ext/pdo_mysql/pdo_mysql.c @@ -118,7 +118,7 @@ static PHP_MINIT_FUNCTION(pdo_mysql) REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SSL_CA", (long)PDO_MYSQL_ATTR_SSL_CA); REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SSL_CAPATH", (long)PDO_MYSQL_ATTR_SSL_CAPATH); REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SSL_CIPHER", (long)PDO_MYSQL_ATTR_SSL_CIPHER); -#if MYSQL_VERSION_ID > 50605 || defined(MYSQLI_USE_MYSQLND) +#if MYSQL_VERSION_ID > 50605 || defined(PDO_USE_MYSQLND) REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SERVER_PUBLIC_KEY", (long)PDO_MYSQL_ATTR_SERVER_PUBLIC_KEY); #endif diff --git a/ext/pdo_mysql/php_pdo_mysql_int.h b/ext/pdo_mysql/php_pdo_mysql_int.h index 42debf07e93..24f7aa2182d 100644 --- a/ext/pdo_mysql/php_pdo_mysql_int.h +++ b/ext/pdo_mysql/php_pdo_mysql_int.h @@ -171,7 +171,7 @@ enum { PDO_MYSQL_ATTR_SSL_CA, PDO_MYSQL_ATTR_SSL_CAPATH, PDO_MYSQL_ATTR_SSL_CIPHER, -#if MYSQL_VERSION_ID > 50605 || defined(MYSQLI_USE_MYSQLND) +#if MYSQL_VERSION_ID > 50605 || defined(PDO_USE_MYSQLND) PDO_MYSQL_ATTR_SERVER_PUBLIC_KEY #endif }; From f00d796b7ef290b4fa515ae09afc34f17201528f Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 23 Jul 2013 18:06:51 +0200 Subject: [PATCH 06/10] fix missing include --- ext/openssl/openssl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index c939c01b2b8..655980e20c8 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -35,6 +35,9 @@ #include "ext/standard/php_fopen_wrappers.h" #include "ext/standard/md5.h" #include "ext/standard/base64.h" +#ifdef PHP_WIN32 +# include "win32/winutil.h" +#endif /* OpenSSL includes */ #include From f9000fde98195844b4d1c1d6209f9796da3ebee8 Mon Sep 17 00:00:00 2001 From: Adam Harvey Date: Tue, 23 Jul 2013 11:15:43 -0700 Subject: [PATCH 07/10] Expand the ZEND_STRL macro to handle platforms where strncmp() is a macro. On most platforms, this works fine, but on Linux armhf, strncmp() is a macro rather than a real function, ergo the macro expansion of ZEND_STRL doesn't occur until after the compiler knows it needs three parameters for strncmp() and we get a compile error. Fixes the fix for bug #61697. --- ext/spl/php_spl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index c3a774ea96d..a5ffdb7d140 100644 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -744,7 +744,7 @@ PHP_FUNCTION(spl_autoload_functions) add_next_index_string(tmp, alfi->func_ptr->common.function_name, 1); add_next_index_zval(return_value, tmp); } else { - if (strncmp(alfi->func_ptr->common.function_name, ZEND_STRL("__lambda_func"))) { + if (strncmp(alfi->func_ptr->common.function_name, "__lambda_func", sizeof("__lambda_func") - 1)) { add_next_index_string(return_value, alfi->func_ptr->common.function_name, 1); } else { char *key; From 9909c4d4c4eb15a64dea0f10e10a8e3a2c0d879d Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Thu, 25 Jul 2013 22:43:41 +0800 Subject: [PATCH 08/10] Fixed bug #65328 (Segfault when getting SplStack object Value) --- NEWS | 3 + ext/spl/spl_array.c | 2 +- ext/spl/tests/bug65328.phpt | 348 ++++++++++++++++++++++++++++++++++++ 3 files changed, 352 insertions(+), 1 deletion(-) create mode 100644 ext/spl/tests/bug65328.phpt diff --git a/NEWS b/NEWS index f76497b3e44..a7255473793 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,9 @@ PHP NEWS . Fixed bug #50308 (session id not appended properly for empty anchor tags). (Arpad) +- Spl: + . Fixed bug #65328 (Segfault when getting SplStack object Value). (Laruence) + - Phar: . Fixed bug #65028 (Phar::buildFromDirectory creates corrupt archives for some specific contents). (Stas) diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 40fbb4c8f67..0bfb65890c3 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -1658,7 +1658,7 @@ SPL_METHOD(Array, getChildren) return; } if (instanceof_function(Z_OBJCE_PP(entry), Z_OBJCE_P(getThis()) TSRMLS_CC)) { - RETURN_ZVAL(*entry, 0, 0); + RETURN_ZVAL(*entry, 1, 0); } } diff --git a/ext/spl/tests/bug65328.phpt b/ext/spl/tests/bug65328.phpt new file mode 100644 index 00000000000..32e6c24fa77 --- /dev/null +++ b/ext/spl/tests/bug65328.phpt @@ -0,0 +1,348 @@ +--TEST-- +Bug #65328 (Segfault when getting SplStack object Value) +--FILE-- +head = $head ? : new Node('HEAD'); + } + + /** + * @return Node + */ + public function getHead() + { + return $this->head; + } + + /** + * @param mixed $uid + * @return Node|bool + */ + public function find($uid) + { + $iterator = $this->getIterator(); + + /** @var Node $node */ + foreach($iterator as $node) { + if($node->getUid() === $uid) { + return $node; + } + } + + return false; + } + + /** + * @param mixed $uid + * @return \SplStack + */ + public function & findAll($uid) + { + $result = new \SplStack(); + + /** @var Node $node */ + foreach($this->getIterator() as $node) { + if($node->getUid() == $uid) { + $result->push($node); + } + } + + return $result; + } + + /** + * @return \RecursiveIteratorIterator + */ + public function getIterator() + { + return new \RecursiveIteratorIterator( + $this->head->getChildren(), + \RecursiveIteratorIterator::SELF_FIRST + ); + } +} + +class Node extends \RecursiveArrayIterator implements \Countable +{ + /** + * @var array + */ + protected $children = []; + + /** + * @var Node + */ + protected $parent; + + /** + * @var mixed + */ + protected $data; + + /** + * @var mixed + */ + protected $uid; + + /** + * @var int + */ + protected $index = 0; + + /** + * @var bool + */ + protected $assureUnique; + + /** + * @param mixed $data + * @param mixed $uid + * @param Node $parent + * @param bool $assureUnique + */ + public function __construct($data, $uid = null, Node $parent = null, $assureUnique = false) + { + if(null !== $parent) { + $this->parent = $parent; + } + + $this->data = $data; + $this->uid = $uid ? : uniqid(sha1(serialize($data)), true); + $this->assureUnique = $assureUnique; + } + + /** + * @param mixed $uid + */ + public function setUid($uid) + { + $this->uid = $uid; + } + + /** + * @return mixed + */ + public function getUid() + { + return $this->uid; + } + + /** + * @param Node $child + */ + public function addChild(Node $child) + { + $child->setParent($this); + $this->children[] = $child; + } + + /** + * @param array $children + */ + public function setChildren(array $children) + { + $this->children = $children; + } + + /** + * @return array + */ + public function getChildrenArray() + { + return $this->children; + } + + /** + * @param mixed $data + */ + public function setData($data) + { + $this->data = $data; + } + + /** + * @return mixed + */ + public function getData() + { + return $this->data; + } + + /** + * @param Node $parent + * @throws \RuntimeException + */ + public function setParent(Node $parent) + { + if(true === $this->assureUnique && !self::checkUnique($parent, $this->uid)) { + throw new \RuntimeException("Node uid is not unique in assigned node tree"); + } + + $this->parent = $parent; + } + + /** + * @param Node $node + * @param mixed $uid + * @return bool + */ + protected static function checkUnique(Node $node, $uid) + { + $headNode = $node; + do { + $headNode = $node; + } while($node = $node->getParent()); + + $tree = new Tree($headNode); + + return !$tree->find($uid); + } + + /** + * @return \IJsonRPC\Helpers\Tree\Node + */ + public function getParent() + { + return $this->parent; + } + + /** + * @return Node + */ + public function current() + { + return $this->children[$this->index]; + } + + /** + * @return scalar + */ + public function key() + { + return $this->index; + } + + /** + * @return void + */ + public function next() + { + ++$this->index; + } + + /** + * @return void + */ + public function rewind() + { + $this->index = 0; + } + + /** + * @return bool + */ + public function valid() + { + return array_key_exists($this->index, $this->children); + } + + /** + * @return int + */ + public function count() + { + return count($this->children); + } + + /** + * @return bool + */ + public function hasChildren() + { + return !empty($this->children); + } + + /** + * @return \RecursiveArrayIterator + */ + public function getChildren() + { + return new \RecursiveArrayIterator($this->children); + } +} + +$tree = new Tree(); +$node1 = new Node('value1', 1); +$tree->getHead()->addChild($node1); +$node2 = new Node('value2', 2); +$node1->addChild($node2); + +print_r($tree->findAll(2)->offsetGet(0)); +--EXPECTF-- +Node Object +( + [children:protected] => Array + ( + ) + + [parent:protected] => Node Object + ( + [children:protected] => Array + ( + [0] => Node Object + *RECURSION* + ) + + [parent:protected] => Node Object + ( + [children:protected] => Array + ( + [0] => Node Object + *RECURSION* + ) + + [parent:protected] => + [data:protected] => HEAD + [uid:protected] => %s + [index:protected] => 0 + [assureUnique:protected] => + [storage:ArrayIterator:private] => Array + ( + ) + + ) + + [data:protected] => value1 + [uid:protected] => 1 + [index:protected] => 1 + [assureUnique:protected] => + [storage:ArrayIterator:private] => Array + ( + ) + + ) + + [data:protected] => value2 + [uid:protected] => 2 + [index:protected] => 0 + [assureUnique:protected] => + [storage:ArrayIterator:private] => Array + ( + ) + +) From 1fbcfc9bdba79772ea3d426ee55c055411dfad79 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Thu, 25 Jul 2013 22:44:59 +0800 Subject: [PATCH 09/10] Update NEWs --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index d1ff284323e..ff6ed35b128 100644 --- a/NEWS +++ b/NEWS @@ -18,6 +18,7 @@ PHP NEWS some specific contents). (Stas) - SPL: + . Fixed bug #65328 (Segfault when getting SplStack object Value). (Laruence) . Added RecursiveTreeIterator setPostfix and getPostifx methods. (Joshua Thijssen) . Fixed bug #61697 (spl_autoload_functions returns lambda functions From 515092917d8c31ea4fb2d80598dd672511717e4e Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Thu, 25 Jul 2013 22:45:15 +0800 Subject: [PATCH 10/10] Upper section name --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index a7255473793..8f7bbd8c7cf 100644 --- a/NEWS +++ b/NEWS @@ -14,7 +14,7 @@ PHP NEWS . Fixed bug #50308 (session id not appended properly for empty anchor tags). (Arpad) -- Spl: +- SPL: . Fixed bug #65328 (Segfault when getting SplStack object Value). (Laruence) - Phar: