php: supported 5.4.x version

This commit is contained in:
advect 2012-04-20 15:29:20 +09:00
parent 3399148d75
commit 9dd0a6eb86
9 changed files with 215 additions and 99 deletions

View File

@ -1,5 +1,9 @@
msgpack extension changelog msgpack extension changelog
Version 0.5.2
-------------
* Support PHP 5.4.x version.
Version 0.5.1 Version 0.5.1
------------- -------------
* Fixed include path for version check. * Fixed include path for version check.

View File

@ -40,6 +40,9 @@ STD_PHP_INI_BOOLEAN(
STD_PHP_INI_BOOLEAN( STD_PHP_INI_BOOLEAN(
"msgpack.php_only", "1", PHP_INI_ALL, OnUpdateBool, "msgpack.php_only", "1", PHP_INI_ALL, OnUpdateBool,
php_only, zend_msgpack_globals, msgpack_globals) php_only, zend_msgpack_globals, msgpack_globals)
STD_PHP_INI_BOOLEAN(
"msgpack.illegal_key_insert", "0", PHP_INI_ALL, OnUpdateBool,
illegal_key_insert, zend_msgpack_globals, msgpack_globals)
PHP_INI_END() PHP_INI_END()
PS_SERIALIZER_FUNCS(msgpack); PS_SERIALIZER_FUNCS(msgpack);
@ -66,6 +69,8 @@ static void msgpack_init_globals(zend_msgpack_globals *msgpack_globals)
} }
msgpack_globals->php_only = 1; msgpack_globals->php_only = 1;
msgpack_globals->illegal_key_insert = 0;
} }
static ZEND_MINIT_FUNCTION(msgpack) static ZEND_MINIT_FUNCTION(msgpack)
@ -136,11 +141,15 @@ ZEND_GET_MODULE(msgpack)
PS_SERIALIZER_ENCODE_FUNC(msgpack) PS_SERIALIZER_ENCODE_FUNC(msgpack)
{ {
smart_str buf = {0}; smart_str buf = {0};
php_serialize_data_t var_hash; msgpack_serialize_data_t var_hash;
PHP_VAR_SERIALIZE_INIT(var_hash); PHP_VAR_SERIALIZE_INIT(var_hash);
#if PHP_API_VERSION < 20100412
msgpack_serialize_zval(&buf, PS(http_session_vars), &var_hash TSRMLS_CC); msgpack_serialize_zval(&buf, PS(http_session_vars), &var_hash TSRMLS_CC);
#else
msgpack_serialize_zval(&buf, PS(http_session_vars), var_hash TSRMLS_CC);
#endif
if (newlen) if (newlen)
{ {
@ -167,7 +176,7 @@ PS_SERIALIZER_DECODE_FUNC(msgpack)
zval **value; zval **value;
size_t off = 0; size_t off = 0;
msgpack_unpack_t mp; msgpack_unpack_t mp;
php_unserialize_data_t var_hash; msgpack_unserialize_data_t var_hash;
ALLOC_INIT_ZVAL(tmp); ALLOC_INIT_ZVAL(tmp);
@ -176,7 +185,7 @@ PS_SERIALIZER_DECODE_FUNC(msgpack)
msgpack_unserialize_var_init(&var_hash); msgpack_unserialize_var_init(&var_hash);
mp.user.retval = (zval *)tmp; mp.user.retval = (zval *)tmp;
mp.user.var_hash = (php_unserialize_data_t *)&var_hash; mp.user.var_hash = (msgpack_unserialize_data_t *)&var_hash;
ret = template_execute(&mp, (char *)val, (size_t)vallen, &off); ret = template_execute(&mp, (char *)val, (size_t)vallen, &off);
@ -219,11 +228,15 @@ PS_SERIALIZER_DECODE_FUNC(msgpack)
PHP_MSGPACK_API void php_msgpack_serialize(smart_str *buf, zval *val TSRMLS_DC) PHP_MSGPACK_API void php_msgpack_serialize(smart_str *buf, zval *val TSRMLS_DC)
{ {
php_serialize_data_t var_hash; msgpack_serialize_data_t var_hash;
PHP_VAR_SERIALIZE_INIT(var_hash); PHP_VAR_SERIALIZE_INIT(var_hash);
#if PHP_API_VERSION < 20100412
msgpack_serialize_zval(buf, val, &var_hash TSRMLS_CC); msgpack_serialize_zval(buf, val, &var_hash TSRMLS_CC);
#else
msgpack_serialize_zval(buf, val, var_hash TSRMLS_CC);
#endif
PHP_VAR_SERIALIZE_DESTROY(var_hash); PHP_VAR_SERIALIZE_DESTROY(var_hash);
} }
@ -234,7 +247,7 @@ PHP_MSGPACK_API void php_msgpack_unserialize(
int ret; int ret;
size_t off = 0; size_t off = 0;
msgpack_unpack_t mp; msgpack_unpack_t mp;
php_unserialize_data_t var_hash; msgpack_unserialize_data_t var_hash;
if (str_len <= 0) if (str_len <= 0)
{ {
@ -246,7 +259,7 @@ PHP_MSGPACK_API void php_msgpack_unserialize(
msgpack_unserialize_var_init(&var_hash); msgpack_unserialize_var_init(&var_hash);
mp.user.retval = (zval *)return_value; mp.user.retval = (zval *)return_value;
mp.user.var_hash = (php_unserialize_data_t *)&var_hash; mp.user.var_hash = (msgpack_unserialize_data_t *)&var_hash;
ret = template_execute(&mp, str, (size_t)str_len, &off); ret = template_execute(&mp, str, (size_t)str_len, &off);

View File

@ -19,7 +19,7 @@ typedef struct {
zval *retval; zval *retval;
long offset; long offset;
msgpack_unpack_t mp; msgpack_unpack_t mp;
php_unserialize_data_t var_hash; msgpack_unserialize_data_t var_hash;
long php_only; long php_only;
zend_bool finished; zend_bool finished;
int error; int error;
@ -188,8 +188,10 @@ static void php_msgpack_base_free(php_msgpack_base_t *base TSRMLS_DC)
static zend_object_value php_msgpack_base_new(zend_class_entry *ce TSRMLS_DC) static zend_object_value php_msgpack_base_new(zend_class_entry *ce TSRMLS_DC)
{ {
zend_object_value retval; zend_object_value retval;
zval *tmp;
php_msgpack_base_t *base; php_msgpack_base_t *base;
#if PHP_API_VERSION < 20100412
zval *tmp;
#endif
base = emalloc(sizeof(php_msgpack_base_t)); base = emalloc(sizeof(php_msgpack_base_t));
@ -201,9 +203,13 @@ static zend_object_value php_msgpack_base_new(zend_class_entry *ce TSRMLS_DC)
base->object.ce = ce; base->object.ce = ce;
#endif #endif
#if PHP_API_VERSION < 20100412
zend_hash_copy( zend_hash_copy(
base->object.properties, &ce->default_properties, base->object.properties, &ce->default_properties,
(copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *)); (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
#else
object_properties_init(&base->object, ce);
#endif
retval.handle = zend_objects_store_put( retval.handle = zend_objects_store_put(
base, (zend_objects_store_dtor_t)zend_objects_destroy_object, base, (zend_objects_store_dtor_t)zend_objects_destroy_object,
@ -233,8 +239,10 @@ static zend_object_value php_msgpack_unpacker_new(
zend_class_entry *ce TSRMLS_DC) zend_class_entry *ce TSRMLS_DC)
{ {
zend_object_value retval; zend_object_value retval;
zval *tmp;
php_msgpack_unpacker_t *unpacker; php_msgpack_unpacker_t *unpacker;
#if PHP_API_VERSION < 20100412
zval *tmp;
#endif
unpacker = emalloc(sizeof(php_msgpack_unpacker_t)); unpacker = emalloc(sizeof(php_msgpack_unpacker_t));
@ -246,9 +254,13 @@ static zend_object_value php_msgpack_unpacker_new(
unpacker->object.ce = ce; unpacker->object.ce = ce;
#endif #endif
#if PHP_API_VERSION < 20100412
zend_hash_copy( zend_hash_copy(
unpacker->object.properties, &ce->default_properties, unpacker->object.properties, &ce->default_properties,
(copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *)); (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
#else
object_properties_init(&unpacker->object, ce);
#endif
retval.handle = zend_objects_store_put( retval.handle = zend_objects_store_put(
unpacker, (zend_objects_store_dtor_t)zend_objects_destroy_object, unpacker, (zend_objects_store_dtor_t)zend_objects_destroy_object,
@ -410,7 +422,7 @@ static ZEND_METHOD(msgpack_unpacker, __construct)
msgpack_unserialize_var_init(&unpacker->var_hash); msgpack_unserialize_var_init(&unpacker->var_hash);
(&unpacker->mp)->user.var_hash = (&unpacker->mp)->user.var_hash =
(php_unserialize_data_t *)&unpacker->var_hash; (msgpack_unserialize_data_t *)&unpacker->var_hash;
} }
static ZEND_METHOD(msgpack_unpacker, __destruct) static ZEND_METHOD(msgpack_unpacker, __destruct)
@ -533,7 +545,7 @@ static ZEND_METHOD(msgpack_unpacker, execute)
msgpack_unserialize_var_init(&unpacker->var_hash); msgpack_unserialize_var_init(&unpacker->var_hash);
(&unpacker->mp)->user.var_hash = (&unpacker->mp)->user.var_hash =
(php_unserialize_data_t *)&unpacker->var_hash; (msgpack_unserialize_data_t *)&unpacker->var_hash;
} }
(&unpacker->mp)->user.retval = (zval *)unpacker->retval; (&unpacker->mp)->user.retval = (zval *)unpacker->retval;
@ -649,7 +661,7 @@ static ZEND_METHOD(msgpack_unpacker, reset)
msgpack_unserialize_var_init(&unpacker->var_hash); msgpack_unserialize_var_init(&unpacker->var_hash);
(&unpacker->mp)->user.var_hash = (&unpacker->mp)->user.var_hash =
(php_unserialize_data_t *)&unpacker->var_hash; (msgpack_unserialize_data_t *)&unpacker->var_hash;
} }
void msgpack_init_class() void msgpack_init_class()

View File

@ -254,6 +254,12 @@ inline static void msgpack_serialize_array(
} }
if (object) if (object)
{
if (n == 0)
{
msgpack_pack_map(buf, n);
}
else
{ {
if (MSGPACK_G(php_only)) if (MSGPACK_G(php_only))
{ {
@ -278,6 +284,7 @@ inline static void msgpack_serialize_array(
hash = 0; hash = 0;
} }
} }
}
else if (n == 0) else if (n == 0)
{ {
hash = 0; hash = 0;
@ -300,6 +307,8 @@ inline static void msgpack_serialize_array(
} }
if (n > 0) if (n > 0)
{
if (object || hash)
{ {
char *key; char *key;
uint key_len; uint key_len;
@ -366,6 +375,37 @@ inline static void msgpack_serialize_array(
} }
} }
} }
else
{
zval **data;
uint i;
for (i = 0; i < n; i++)
{
if (zend_hash_index_find(ht, i, (void *)&data) != SUCCESS ||
!data || data == &val ||
(Z_TYPE_PP(data) == IS_ARRAY &&
Z_ARRVAL_PP(data)->nApplyCount > 1))
{
msgpack_pack_nil(buf);
}
else
{
if (Z_TYPE_PP(data) == IS_ARRAY)
{
Z_ARRVAL_PP(data)->nApplyCount++;
}
msgpack_serialize_zval(buf, *data, var_hash TSRMLS_CC);
if (Z_TYPE_PP(data) == IS_ARRAY)
{
Z_ARRVAL_PP(data)->nApplyCount--;
}
}
}
}
}
} }
inline static void msgpack_serialize_object( inline static void msgpack_serialize_object(
@ -399,7 +439,7 @@ inline static void msgpack_serialize_object(
msgpack_pack_nil(buf); msgpack_pack_nil(buf);
msgpack_pack_long(buf, MSGPACK_SERIALIZE_TYPE_CUSTOM_OBJECT); msgpack_pack_long(buf, MSGPACK_SERIALIZE_TYPE_CUSTOM_OBJECT);
msgpack_serialize_string(buf, ce->name, ce->name_length); msgpack_serialize_string(buf, (char *)ce->name, ce->name_length);
msgpack_pack_raw(buf, serialized_length); msgpack_pack_raw(buf, serialized_length);
msgpack_pack_raw_body(buf, serialized_data, serialized_length); msgpack_pack_raw_body(buf, serialized_data, serialized_length);
} }

View File

@ -2,7 +2,13 @@
#ifndef MSGPACK_PACK_H #ifndef MSGPACK_PACK_H
#define MSGPACK_PACK_H #define MSGPACK_PACK_H
#include "ext/standard/php_smart_str.h" #include "ext/standard/php_var.h"
#if PHP_API_VERSION < 20100412
#define msgpack_serialize_data_t HashTable
#else
typedef HashTable* msgpack_serialize_data_t;
#endif
enum msgpack_serialize_type enum msgpack_serialize_type
{ {

View File

@ -54,7 +54,7 @@ typedef struct
MSGPACK_UNSERIALIZE_FINISH_ITEM(_unpack, 2); MSGPACK_UNSERIALIZE_FINISH_ITEM(_unpack, 2);
inline static void msgpack_var_push( inline static void msgpack_var_push(
php_unserialize_data_t *var_hashx, zval **rval) msgpack_unserialize_data_t *var_hashx, zval **rval)
{ {
var_entries *var_hash, *prev = NULL; var_entries *var_hash, *prev = NULL;
@ -91,7 +91,7 @@ inline static void msgpack_var_push(
} }
inline static int msgpack_var_access( inline static int msgpack_var_access(
php_unserialize_data_t *var_hashx, long id, zval ***store) msgpack_unserialize_data_t *var_hashx, long id, zval ***store)
{ {
var_entries *var_hash = var_hashx->first; var_entries *var_hash = var_hashx->first;
@ -118,7 +118,7 @@ inline static int msgpack_var_access(
} }
inline static void msgpack_stack_push( inline static void msgpack_stack_push(
php_unserialize_data_t *var_hashx, zval **rval, zend_bool save) msgpack_unserialize_data_t *var_hashx, zval **rval, zend_bool save)
{ {
var_entries *var_hash, *prev = NULL; var_entries *var_hash, *prev = NULL;
@ -162,7 +162,7 @@ inline static void msgpack_stack_push(
} }
inline static void msgpack_stack_pop( inline static void msgpack_stack_pop(
php_unserialize_data_t *var_hashx, long count) msgpack_unserialize_data_t *var_hashx, long count)
{ {
long i; long i;
var_entries *var_hash = var_hashx->first_dtor; var_entries *var_hash = var_hashx->first_dtor;
@ -280,14 +280,14 @@ inline static zend_class_entry* msgpack_unserialize_class(
return ce; return ce;
} }
void msgpack_unserialize_var_init(php_unserialize_data_t *var_hashx) void msgpack_unserialize_var_init(msgpack_unserialize_data_t *var_hashx)
{ {
var_hashx->first = 0; var_hashx->first = 0;
var_hashx->first_dtor = 0; var_hashx->first_dtor = 0;
} }
void msgpack_unserialize_var_destroy( void msgpack_unserialize_var_destroy(
php_unserialize_data_t *var_hashx, zend_bool err) msgpack_unserialize_data_t *var_hashx, zend_bool err)
{ {
void *next; void *next;
long i; long i;
@ -487,7 +487,7 @@ int msgpack_unserialize_array(
array_init(*obj); array_init(*obj);
if (count) unpack->stack[unpack->deps++] = count; unpack->stack[unpack->deps++] = count;
return 0; return 0;
} }
@ -505,12 +505,25 @@ int msgpack_unserialize_array_item(
int msgpack_unserialize_map( int msgpack_unserialize_map(
msgpack_unserialize_data *unpack, unsigned int count, zval **obj) msgpack_unserialize_data *unpack, unsigned int count, zval **obj)
{ {
TSRMLS_FETCH();
MSGPACK_UNSERIALIZE_ALLOC_VALUE(unpack); MSGPACK_UNSERIALIZE_ALLOC_VALUE(unpack);
if (count) unpack->stack[unpack->deps++] = count; unpack->stack[unpack->deps++] = count;
unpack->type = MSGPACK_SERIALIZE_TYPE_NONE; unpack->type = MSGPACK_SERIALIZE_TYPE_NONE;
if (count == 0)
{
if (MSGPACK_G(php_only))
{
object_init(*obj);
}
else
{
array_init(*obj);
}
}
return 0; return 0;
} }
@ -669,6 +682,7 @@ int msgpack_unserialize_map_item(
"[msgpack] (%s) illegal offset type, skip this decoding", "[msgpack] (%s) illegal offset type, skip this decoding",
__FUNCTION__); __FUNCTION__);
} }
zval_ptr_dtor(&key);
break; break;
case IS_STRING: case IS_STRING:
if (zend_symtable_update( if (zend_symtable_update(
@ -680,16 +694,39 @@ int msgpack_unserialize_map_item(
"[msgpack] (%s) illegal offset type, skip this decoding", "[msgpack] (%s) illegal offset type, skip this decoding",
__FUNCTION__); __FUNCTION__);
} }
zval_ptr_dtor(&key);
break; break;
default: default:
MSGPACK_WARNING("[msgpack] (%s) illegal key type", __FUNCTION__);
if (MSGPACK_G(illegal_key_insert))
{
if (zend_hash_next_index_insert(
HASH_OF(*container), &key, sizeof(key), NULL) == FAILURE)
{
zval_ptr_dtor(&val); zval_ptr_dtor(&val);
MSGPACK_WARNING( }
"[msgpack] (%s) illegal offset type, skip this decoding", if (zend_hash_next_index_insert(
__FUNCTION__); HASH_OF(*container), &val, sizeof(val), NULL) == FAILURE)
{
zval_ptr_dtor(&val);
}
}
else
{
convert_to_string(key);
if (zend_symtable_update(
HASH_OF(*container),
Z_STRVAL_P(key), Z_STRLEN_P(key) + 1,
&val, sizeof(val), NULL) == FAILURE)
{
zval_ptr_dtor(&val);
}
zval_ptr_dtor(&key);
}
break; break;
} }
zval_ptr_dtor(&key);
msgpack_stack_pop(unpack->var_hash, 2); msgpack_stack_pop(unpack->var_hash, 2);
deps = unpack->deps - 1; deps = unpack->deps - 1;

View File

@ -16,17 +16,19 @@ typedef enum
MSGPACK_UNPACK_PARSE_ERROR = -1, MSGPACK_UNPACK_PARSE_ERROR = -1,
} msgpack_unpack_return; } msgpack_unpack_return;
typedef struct php_unserialize_data msgpack_unserialize_data_t;
typedef struct { typedef struct {
zval *retval; zval *retval;
long deps; long deps;
php_unserialize_data_t *var_hash; msgpack_unserialize_data_t *var_hash;
long stack[MSGPACK_EMBED_STACK_SIZE]; long stack[MSGPACK_EMBED_STACK_SIZE];
int type; int type;
} msgpack_unserialize_data; } msgpack_unserialize_data;
void msgpack_unserialize_var_init(php_unserialize_data_t *var_hashx); void msgpack_unserialize_var_init(msgpack_unserialize_data_t *var_hashx);
void msgpack_unserialize_var_destroy( void msgpack_unserialize_var_destroy(
php_unserialize_data_t *var_hashx, zend_bool err); msgpack_unserialize_data_t *var_hashx, zend_bool err);
void msgpack_unserialize_init(msgpack_unserialize_data *unpack); void msgpack_unserialize_init(msgpack_unserialize_data *unpack);

View File

@ -2,7 +2,7 @@
#ifndef PHP_MSGPACK_H #ifndef PHP_MSGPACK_H
#define PHP_MSGPACK_H #define PHP_MSGPACK_H
#define MSGPACK_EXTENSION_VERSION "0.5.1" #define MSGPACK_EXTENSION_VERSION "0.5.2"
#include "ext/standard/php_smart_str.h" #include "ext/standard/php_smart_str.h"
@ -24,6 +24,7 @@ extern zend_module_entry msgpack_module_entry;
ZEND_BEGIN_MODULE_GLOBALS(msgpack) ZEND_BEGIN_MODULE_GLOBALS(msgpack)
zend_bool error_display; zend_bool error_display;
zend_bool php_only; zend_bool php_only;
zend_bool illegal_key_insert;
ZEND_END_MODULE_GLOBALS(msgpack) ZEND_END_MODULE_GLOBALS(msgpack)
ZEND_EXTERN_MODULE_GLOBALS(msgpack) ZEND_EXTERN_MODULE_GLOBALS(msgpack)

View File

@ -44,4 +44,5 @@ header Version => %s
Directive => Local Value => Master Value Directive => Local Value => Master Value
msgpack.error_display => On => On msgpack.error_display => On => On
msgpack.illegal_key_insert => Off => Off
msgpack.php_only => On => On msgpack.php_only => On => On