Skip to content

Commit

Permalink
Merge pull request #1635 from sjinks/beanstalk-queue
Browse files Browse the repository at this point in the history
Safe serialization/unserialization of Phalcon\Beanstalk\Queue
  • Loading branch information
Phalcon committed Dec 5, 2013
2 parents fab567a + 4311f65 commit f1b0d5a
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 8 deletions.
54 changes: 46 additions & 8 deletions ext/queue/beanstalk.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ PHALCON_INIT_CLASS(Phalcon_Queue_Beanstalk){
*/
PHP_METHOD(Phalcon_Queue_Beanstalk, __construct){

zval *options = NULL, *parameters = NULL;
zval *options = NULL, *parameters = NULL, *tmp;

PHALCON_MM_GROW();

Expand All @@ -86,20 +86,26 @@ PHP_METHOD(Phalcon_Queue_Beanstalk, __construct){

if (Z_TYPE_P(options) != IS_ARRAY) {
PHALCON_INIT_VAR(parameters);
array_init(parameters);
array_init_size(parameters, 2);
} else {
PHALCON_CPY_WRT(parameters, options);
PHALCON_CPY_WRT_CTOR(parameters, options);
}
if (!phalcon_array_isset_string(parameters, SS("host"))) {
phalcon_array_update_string_string(&parameters, SL("host"), SL("127.0.0.1"), PH_SEPARATE);

if (!phalcon_array_isset_string_fetch(&tmp, parameters, SS("host"))) {
phalcon_array_update_string_string(&parameters, SL("host"), SL("127.0.0.1"), 0);
}
else {
convert_to_string(tmp);
}

if (!phalcon_array_isset_string(parameters, SS("port"))) {
phalcon_array_update_string_long(&parameters, SL("port"), 11300, PH_SEPARATE);
if (!phalcon_array_isset_string_fetch(&tmp, parameters, SS("port"))) {
phalcon_array_update_string_long(&parameters, SL("port"), 11300, 0);
}
else {
convert_to_long(tmp);
}

phalcon_update_property_this(this_ptr, SL("_parameters"), parameters TSRMLS_CC);

PHALCON_MM_RESTORE();
}

Expand Down Expand Up @@ -600,3 +606,35 @@ PHP_METHOD(Phalcon_Queue_Beanstalk, disconnect){
RETURN_TRUE;
}

PHP_METHOD(Phalcon_Queue_Beanstalk, __sleep){

array_init_size(return_value, 1);
add_next_index_string(return_value, "_parameters", 1);
}

PHP_METHOD(Phalcon_Queue_Beanstalk, __wakeup){

zval *params, *host, *port;
int fail;

zend_update_property_null(phalcon_queue_beanstalk_ce, getThis(), SL("_connection") TSRMLS_CC);

params = phalcon_fetch_nproperty_this(this_ptr, SL("_parameters"), PH_NOISY_CC);
if (
Z_TYPE_P(params) != IS_ARRAY
|| !phalcon_array_isset_string_fetch(&host, params, SS("host"))
|| !phalcon_array_isset_string_fetch(&port, params, SS("port"))
) {
fail = 1;
}
else if (Z_TYPE_P(host) != IS_STRING || Z_TYPE_P(port) != IS_LONG) {
fail = 1;
}
else {
fail = 0;
}

if (fail) {
zend_throw_exception_ex(phalcon_exception_ce, 0 TSRMLS_CC, "Invalid serialization data");
}
}
4 changes: 4 additions & 0 deletions ext/queue/beanstalk.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ PHP_METHOD(Phalcon_Queue_Beanstalk, readStatus);
PHP_METHOD(Phalcon_Queue_Beanstalk, read);
PHP_METHOD(Phalcon_Queue_Beanstalk, write);
PHP_METHOD(Phalcon_Queue_Beanstalk, disconnect);
PHP_METHOD(Phalcon_Queue_Beanstalk, __sleep);
PHP_METHOD(Phalcon_Queue_Beanstalk, __wakeup);

ZEND_BEGIN_ARG_INFO_EX(arginfo_phalcon_queue_beanstalk___construct, 0, 0, 0)
ZEND_ARG_INFO(0, options)
Expand Down Expand Up @@ -70,6 +72,8 @@ PHALCON_INIT_FUNCS(phalcon_queue_beanstalk_method_entry){
PHP_ME(Phalcon_Queue_Beanstalk, read, arginfo_phalcon_queue_beanstalk_read, ZEND_ACC_PUBLIC)
PHP_ME(Phalcon_Queue_Beanstalk, write, NULL, ZEND_ACC_PROTECTED)
PHP_ME(Phalcon_Queue_Beanstalk, disconnect, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Phalcon_Queue_Beanstalk, __sleep, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Phalcon_Queue_Beanstalk, __wakeup, NULL, ZEND_ACC_PUBLIC)
PHP_FE_END
};

73 changes: 73 additions & 0 deletions ext/tests/issue-1635.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
--TEST--
Safe serialization/unserialization of Phalcon\Beanstalk\Queue - https://github.com/phalcon/cphalcon/pull/1635
--SKIPIF--
<?php include('skipif.inc'); ?>
--FILE--
<?php

class Test extends \Phalcon\Queue\Beanstalk
{
public function getParams()
{
return $this->_parameters;
}

public function getConnection()
{
return $this->_connection;
}

public function setParams($v)
{
$this->_parameters = $v;
}

public function setConnection($v)
{
$this->_connection = $v;
}
}

$x = new \Test(array('host' => 127, 'port' => '11300'));
var_dump($x->getParams());

$x->setConnection(123.0);
assert($x->getConnection() === 123.0);
var_export(serialize($x));
echo PHP_EOL;

$s = 'O:4:"Test":2:{s:14:"' . "\0" . '*' . "\0" . '_connection";d:123;s:14:"' . "\0" . '*' . "\0" . '_parameters";a:2:{s:4:"host";s:3:"127";s:4:"port";i:11300;}}';
$x = unserialize($s);
var_dump($x->getConnection());

$samples = array(
'O:4:"Test":1:{s:14:"' . "\0" . '*' . "\0" . '_parameters";a:2:{s:4:"Host";s:3:"127";s:4:"port";i:11300;}}',
'O:4:"Test":1:{s:14:"' . "\0" . '*' . "\0" . '_parameters";a:2:{s:4:"host";s:3:"127";s:4:"Port";i:11300;}}',
'O:4:"Test":1:{s:14:"' . "\0" . '*' . "\0" . '_parameters";a:2:{s:4:"host";i:127;s:4:"port";i:11300;}}',
'O:4:"Test":1:{s:14:"' . "\0" . '*' . "\0" . '_parameters";a:2:{s:4:"host";s:3:"127";s:4:"port";s:5:"11300";}}',
);

foreach ($samples as $sample) {
try {
unserialize($sample);
assert(false);
}
catch (\Phalcon\Exception $e) {
echo $e->getMessage(), PHP_EOL;
}
}

?>
--EXPECT--
array(2) {
["host"]=>
string(3) "127"
["port"]=>
int(11300)
}
'O:4:"Test":1:{s:14:"' . "\0" . '*' . "\0" . '_parameters";a:2:{s:4:"host";s:3:"127";s:4:"port";i:11300;}}'
NULL
Invalid serialization data
Invalid serialization data
Invalid serialization data
Invalid serialization data

0 comments on commit f1b0d5a

Please sign in to comment.