Skip to content

Commit

Permalink
Revert "A bit of general maintenance, mainly related to issue php-mem…
Browse files Browse the repository at this point in the history
…cached-dev#69"

This reverts commit 3c4cca7.
  • Loading branch information
mkoppanen committed Oct 17, 2013
1 parent 484583a commit 5fef634
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 75 deletions.
120 changes: 51 additions & 69 deletions php_memcached.c
Expand Up @@ -311,7 +311,7 @@ PHP_INI_END()
****************************************/
static int php_memc_handle_error(php_memc_t *i_obj, memcached_return status TSRMLS_DC);
static char *php_memc_zval_to_payload(zval *value, size_t *payload_len, uint32_t *flags, enum memcached_serializer serializer, enum memcached_compression_type compression_type TSRMLS_DC);
static int php_memc_zval_from_payload(zval *value, const char *payload, size_t payload_len, uint32_t flags, enum memcached_serializer serializer TSRMLS_DC);
static int php_memc_zval_from_payload(zval *value, char *payload, size_t payload_len, uint32_t flags, enum memcached_serializer serializer TSRMLS_DC);
static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key);
static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key);
static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool by_key);
Expand All @@ -321,14 +321,9 @@ static void php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by
static void php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key);
static memcached_return php_memc_do_cache_callback(zval *memc_obj, zend_fcall_info *fci, zend_fcall_info_cache *fcc, char *key, size_t key_len, zval *value TSRMLS_DC);
static int php_memc_do_result_callback(zval *memc_obj, zend_fcall_info *fci, zend_fcall_info_cache *fcc, memcached_result_st *result TSRMLS_DC);

// Cursor callbacks
static memcached_return php_memc_do_serverlist_callback(const memcached_st *ptr, const memcached_instance_st *instance, void *in_context);
static memcached_return php_memc_do_stats_callback(const memcached_st *ptr, const memcached_instance_st *instance, void *in_context);
static memcached_return php_memc_do_version_callback(const memcached_st *ptr, const memcached_instance_st *instance, void *in_context);



static memcached_return php_memc_do_serverlist_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context);
static memcached_return php_memc_do_stats_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context);
static memcached_return php_memc_do_version_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context);
static void php_memc_destroy(struct memc_obj *m_obj, zend_bool persistent TSRMLS_DC);

/****************************************
Expand Down Expand Up @@ -519,6 +514,7 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
int key_len = 0;
char *server_key = NULL;
int server_key_len = 0;
char *payload = NULL;
size_t payload_len = 0;
uint32_t flags = 0;
uint64_t cas = 0;
Expand Down Expand Up @@ -555,7 +551,6 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
key_lens[0] = key_len;

if (cas_token) {
const char *payload = NULL;
uint64_t orig_cas_flag;

/*
Expand Down Expand Up @@ -624,7 +619,6 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
memcached_result_free(&result);

} else {
char *payload = NULL;
int rc;
zend_bool return_value_set = 0;

Expand Down Expand Up @@ -697,11 +691,11 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
int server_key_len = 0;
size_t num_keys = 0;
zval **entry = NULL;
const char *payload = NULL;
char *payload = NULL;
size_t payload_len = 0;
const char **mkeys = NULL;
size_t *mkeys_len = NULL;
const char *res_key = NULL;
char *res_key = NULL;
size_t res_key_len = 0;
uint32_t flags;
uint64_t cas = 0;
Expand Down Expand Up @@ -812,6 +806,12 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
res_key = memcached_result_key_value(&result);
res_key_len = memcached_result_key_length(&result);

/*
* This may be a bug in libmemcached, the key is not null terminated
* whe using the binary protocol.
*/
res_key[res_key_len] = 0;

MAKE_STD_ZVAL(value);

if (php_memc_zval_from_payload(value, payload, payload_len, flags, m_obj->serializer TSRMLS_CC) < 0) {
Expand All @@ -829,21 +829,7 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
continue;
}

if (res_key [res_key_len - 1] != '\0') {
/* Terminate if needed */
char key_buffer [MEMCACHED_MAX_KEY];

if (res_key_len < MEMCACHED_MAX_KEY) {
memcpy (key_buffer, res_key, res_key_len);
key_buffer [res_key_len] = '\0';

add_assoc_zval_ex(return_value, key_buffer, res_key_len + 1, value);
}
}
else {
add_assoc_zval_ex(return_value, res_key, res_key_len + 1, value);
}

add_assoc_zval_ex(return_value, res_key, res_key_len+1, value);
if (cas_tokens) {
cas = memcached_result_cas(&result);
add_assoc_double_ex(cas_tokens, res_key, res_key_len+1, (double)cas);
Expand Down Expand Up @@ -1006,9 +992,9 @@ static void php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_
Returns the next result from a previous delayed request */
PHP_METHOD(Memcached, fetch)
{
const char *res_key = NULL;
char *res_key = NULL;
size_t res_key_len = 0;
const char *payload = NULL;
char *payload = NULL;
size_t payload_len = 0;
zval *value;
uint32_t flags = 0;
Expand Down Expand Up @@ -1063,9 +1049,9 @@ PHP_METHOD(Memcached, fetch)
Returns all the results from a previous delayed request */
PHP_METHOD(Memcached, fetchAll)
{
const char *res_key = NULL;
char *res_key = NULL;
size_t res_key_len = 0;
const char *payload = NULL;
char *payload = NULL;
size_t payload_len = 0;
zval *value, *entry;
uint32_t flags;
Expand Down Expand Up @@ -1979,7 +1965,7 @@ PHP_METHOD(Memcached, getServerByKey)
{
char *server_key;
int server_key_len;
const memcached_instance_st *server_instance;
memcached_server_instance_st *server_instance;
memcached_return error;
MEMC_METHOD_INIT_VARS;

Expand Down Expand Up @@ -2097,7 +2083,7 @@ PHP_METHOD(Memcached, getLastErrorErrno)
Was added in 0.34 according to libmemcached's Changelog */
PHP_METHOD(Memcached, getLastDisconnectedServer)
{
const memcached_instance_st *server_instance;
memcached_server_instance_st *server_instance;
MEMC_METHOD_INIT_VARS;

if (zend_parse_parameters_none() == FAILURE) {
Expand Down Expand Up @@ -2412,7 +2398,12 @@ static int php_memc_set_option(php_memc_t *i_obj, long option, zval *value TSRML
*/
flag = (memcached_behavior) option;
convert_to_long(value);
if (memcached_behavior_set(m_obj->memc, flag, (uint64_t) Z_LVAL_P(value)) != MEMCACHED_SUCCESS) {
if (flag < 0 ||
/* MEMCACHED_BEHAVIOR_MAX was added in somewhere around 0.36 or 0.37 */
#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x00037000
flag >= MEMCACHED_BEHAVIOR_MAX ||
#endif
memcached_behavior_set(m_obj->memc, flag, (uint64_t)Z_LVAL_P(value)) != MEMCACHED_SUCCESS) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "error setting memcached option");
return 0;
}
Expand Down Expand Up @@ -2669,7 +2660,7 @@ ZEND_RSRC_DTOR_FUNC(php_memc_sess_dtor)
/* }}} */

/* {{{ internal API functions */
static memcached_return php_memc_do_serverlist_callback(const memcached_st *ptr, const memcached_instance_st *instance, void *in_context)
static memcached_return php_memc_do_serverlist_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context)
{
struct callbackContext* context = (struct callbackContext*) in_context;
zval *array;
Expand All @@ -2680,17 +2671,14 @@ static memcached_return php_memc_do_serverlist_callback(const memcached_st *ptr,
add_assoc_long(array, "port", memcached_server_port(instance));
/*
* API does not allow to get at this field.
*
* If you comment out stuff like this, please fix tests. -- Mikko
*
add_assoc_long(array, "weight", instance->weight);
*/

add_next_index_zval(context->return_value, array);
return MEMCACHED_SUCCESS;
}

static memcached_return php_memc_do_stats_callback(const memcached_st *ptr, const memcached_instance_st *instance, void *in_context)
static memcached_return php_memc_do_stats_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context)
{
char *hostport = NULL;
int hostport_len;
Expand Down Expand Up @@ -2734,7 +2722,7 @@ static memcached_return php_memc_do_stats_callback(const memcached_st *ptr, cons
return MEMCACHED_SUCCESS;
}

static memcached_return php_memc_do_version_callback(const memcached_st *ptr, const memcached_instance_st *instance, void *in_context)
static memcached_return php_memc_do_version_callback(const memcached_st *ptr, memcached_server_instance_st instance, void *in_context)
{
char *hostport = NULL;
char version[16];
Expand Down Expand Up @@ -2965,20 +2953,13 @@ static char *php_memc_zval_to_payload(zval *value, size_t *payload_len, uint32_t
}

/* The caller MUST free the payload */
static int php_memc_zval_from_payload(zval *value, const char *payload, size_t payload_len, uint32_t flags, enum memcached_serializer serializer TSRMLS_DC)
static int php_memc_zval_from_payload(zval *value, char *payload, size_t payload_len, uint32_t flags, enum memcached_serializer serializer TSRMLS_DC)
{
char *pl;
size_t pl_len;

/*
A NULL payload is completely valid if length is 0, it is simply empty.
*/
zend_bool payload_emalloc = 0;

// Explicit cast
pl = (char *) payload;
pl_len = payload_len;

char *buffer = NULL;

if (payload == NULL && payload_len > 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING,
Expand All @@ -2995,7 +2976,6 @@ static int php_memc_zval_from_payload(zval *value, const char *payload, size_t p

if (flags & MEMC_VAL_COMPRESSED) {
uint32_t len;
char *buffer = NULL;
unsigned long length;
zend_bool decompress_status = 0;

Expand Down Expand Up @@ -3037,47 +3017,49 @@ static int php_memc_zval_from_payload(zval *value, const char *payload, size_t p
efree(buffer);
return -1;
}
pl = buffer;
pl_len = length;
payload = buffer;
payload_len = length;
payload_emalloc = 1;
}

payload[payload_len] = 0;

switch (MEMC_VAL_GET_TYPE(flags)) {
case MEMC_VAL_IS_STRING:
if (payload_emalloc) {
ZVAL_STRINGL(value, pl, pl_len, 0);
ZVAL_STRINGL(value, payload, payload_len, 0);
payload_emalloc = 0;
} else {
ZVAL_STRINGL(value, pl, pl_len, 1);
ZVAL_STRINGL(value, payload, payload_len, 1);
}
break;

case MEMC_VAL_IS_LONG:
{
long lval = strtol(pl, NULL, 10);
long lval = strtol(payload, NULL, 10);
ZVAL_LONG(value, lval);
break;
}

case MEMC_VAL_IS_DOUBLE:
if (pl_len == 8 && memcmp(pl, "Infinity", 8) == 0) {
if (payload_len == 8 && memcmp(payload, "Infinity", 8) == 0) {
ZVAL_DOUBLE(value, php_get_inf());
} else if (pl_len == 9 && memcmp(pl, "-Infinity", 9) == 0) {
} else if (payload_len == 9 && memcmp(payload, "-Infinity", 9) == 0) {
ZVAL_DOUBLE(value, -php_get_inf());
} else if (pl_len == 3 && memcmp(pl, "NaN", 3) == 0) {
} else if (payload_len == 3 && memcmp(payload, "NaN", 3) == 0) {
ZVAL_DOUBLE(value, php_get_nan());
} else {
ZVAL_DOUBLE(value, zend_strtod(pl, NULL));
ZVAL_DOUBLE(value, zend_strtod(payload, NULL));
}
break;

case MEMC_VAL_IS_BOOL:
ZVAL_BOOL(value, pl_len > 0 && pl[0] == '1');
ZVAL_BOOL(value, payload_len > 0 && payload[0] == '1');
break;

case MEMC_VAL_IS_SERIALIZED:
{
const char *payload_tmp = pl;
const char *payload_tmp = payload;
php_unserialize_data_t var_hash;

PHP_VAR_UNSERIALIZE_INIT(var_hash);
Expand All @@ -3093,7 +3075,7 @@ static int php_memc_zval_from_payload(zval *value, const char *payload, size_t p

case MEMC_VAL_IS_IGBINARY:
#ifdef HAVE_MEMCACHED_IGBINARY
if (igbinary_unserialize((uint8_t *)pl, pl_len, &value TSRMLS_CC)) {
if (igbinary_unserialize((uint8_t *)payload, payload_len, &value TSRMLS_CC)) {
ZVAL_FALSE(value);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not unserialize value with igbinary");
goto my_error;
Expand All @@ -3107,9 +3089,9 @@ static int php_memc_zval_from_payload(zval *value, const char *payload, size_t p
case MEMC_VAL_IS_JSON:
#ifdef HAVE_JSON_API
# if HAVE_JSON_API_5_2
php_json_decode(value, pl, pl_len, (serializer == SERIALIZER_JSON_ARRAY) TSRMLS_CC);
php_json_decode(value, payload, payload_len, (serializer == SERIALIZER_JSON_ARRAY) TSRMLS_CC);
# elif HAVE_JSON_API_5_3
php_json_decode(value, pl, pl_len, (serializer == SERIALIZER_JSON_ARRAY), JSON_PARSER_DEFAULT_DEPTH TSRMLS_CC);
php_json_decode(value, payload, payload_len, (serializer == SERIALIZER_JSON_ARRAY), JSON_PARSER_DEFAULT_DEPTH TSRMLS_CC);
# endif
#else
php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not unserialize value, no json support");
Expand All @@ -3123,14 +3105,14 @@ static int php_memc_zval_from_payload(zval *value, const char *payload, size_t p
}

if (payload_emalloc) {
efree(pl);
efree(payload);
}

return 0;

my_error:
if (payload_emalloc) {
efree(pl);
efree(payload);
}
return -1;
}
Expand Down Expand Up @@ -3287,9 +3269,9 @@ static int php_memc_do_result_callback(zval *zmemc_obj, zend_fcall_info *fci,
zend_fcall_info_cache *fcc,
memcached_result_st *result TSRMLS_DC)
{
const char *res_key = NULL;
char *res_key = NULL;
size_t res_key_len = 0;
const char *payload = NULL;
char *payload = NULL;
size_t payload_len = 0;
zval *value, *retval = NULL;
uint64_t cas = 0;
Expand Down
4 changes: 3 additions & 1 deletion tests/bug_16084.phpt
Expand Up @@ -13,10 +13,12 @@ var_dump($m->getServerList());
bool(true)
array(1) {
[0]=>
array(2) {
array(3) {
["host"]=>
string(9) "localhost"
["port"]=>
int(11211)
["weight"]=>
int(3)
}
}
16 changes: 12 additions & 4 deletions tests/getserverlist.phpt
Expand Up @@ -20,35 +20,43 @@ array(0) {
}
array(1) {
[0]=>
array(2) {
array(3) {
["host"]=>
string(9) "localhost"
["port"]=>
int(11211)
["weight"]=>
int(3)
}
}
array(2) {
[0]=>
array(2) {
array(3) {
["host"]=>
string(9) "localhost"
["port"]=>
int(11211)
["weight"]=>
int(3)
}
[1]=>
array(2) {
array(3) {
["host"]=>
string(9) "localhost"
["port"]=>
int(11211)
["weight"]=>
int(3)
}
}
array(1) {
[0]=>
array(2) {
array(3) {
["host"]=>
string(9) "127.0.0.1"
["port"]=>
int(11211)
["weight"]=>
int(%r[01]%r)
}
}

0 comments on commit 5fef634

Please sign in to comment.