@@ -311,7 +311,7 @@ PHP_INI_END()
311311****************************************/
312312static int php_memc_handle_error (php_memc_t * i_obj , memcached_return status TSRMLS_DC );
313313static 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 );
314- static int php_memc_zval_from_payload (zval * value , char * payload , size_t payload_len , uint32_t flags , enum memcached_serializer serializer TSRMLS_DC );
314+ 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 );
315315static void php_memc_get_impl (INTERNAL_FUNCTION_PARAMETERS , zend_bool by_key );
316316static void php_memc_getMulti_impl (INTERNAL_FUNCTION_PARAMETERS , zend_bool by_key );
317317static void php_memc_store_impl (INTERNAL_FUNCTION_PARAMETERS , int op , zend_bool by_key );
@@ -321,9 +321,14 @@ static void php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by
321321static void php_memc_getDelayed_impl (INTERNAL_FUNCTION_PARAMETERS , zend_bool by_key );
322322static 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 );
323323static int php_memc_do_result_callback (zval * memc_obj , zend_fcall_info * fci , zend_fcall_info_cache * fcc , memcached_result_st * result TSRMLS_DC );
324- static memcached_return php_memc_do_serverlist_callback (const memcached_st * ptr , memcached_server_instance_st instance , void * in_context );
325- static memcached_return php_memc_do_stats_callback (const memcached_st * ptr , memcached_server_instance_st instance , void * in_context );
326- static memcached_return php_memc_do_version_callback (const memcached_st * ptr , memcached_server_instance_st instance , void * in_context );
324+
325+ // Cursor callbacks
326+ static memcached_return php_memc_do_serverlist_callback (const memcached_st * ptr , const memcached_instance_st * instance , void * in_context );
327+ static memcached_return php_memc_do_stats_callback (const memcached_st * ptr , const memcached_instance_st * instance , void * in_context );
328+ static memcached_return php_memc_do_version_callback (const memcached_st * ptr , const memcached_instance_st * instance , void * in_context );
329+
330+
331+
327332static void php_memc_destroy (struct memc_obj * m_obj , zend_bool persistent TSRMLS_DC );
328333
329334/****************************************
@@ -514,7 +519,6 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
514519 int key_len = 0 ;
515520 char * server_key = NULL ;
516521 int server_key_len = 0 ;
517- char * payload = NULL ;
518522 size_t payload_len = 0 ;
519523 uint32_t flags = 0 ;
520524 uint64_t cas = 0 ;
@@ -551,6 +555,7 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
551555 key_lens [0 ] = key_len ;
552556
553557 if (cas_token ) {
558+ const char * payload = NULL ;
554559 uint64_t orig_cas_flag ;
555560
556561 /*
@@ -619,6 +624,7 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
619624 memcached_result_free (& result );
620625
621626 } else {
627+ char * payload = NULL ;
622628 int rc ;
623629 zend_bool return_value_set = 0 ;
624630
@@ -691,11 +697,11 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
691697 int server_key_len = 0 ;
692698 size_t num_keys = 0 ;
693699 zval * * entry = NULL ;
694- char * payload = NULL ;
700+ const char * payload = NULL ;
695701 size_t payload_len = 0 ;
696702 const char * * mkeys = NULL ;
697703 size_t * mkeys_len = NULL ;
698- char * res_key = NULL ;
704+ const char * res_key = NULL ;
699705 size_t res_key_len = 0 ;
700706 uint32_t flags ;
701707 uint64_t cas = 0 ;
@@ -806,12 +812,6 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
806812 res_key = memcached_result_key_value (& result );
807813 res_key_len = memcached_result_key_length (& result );
808814
809- /*
810- * This may be a bug in libmemcached, the key is not null terminated
811- * whe using the binary protocol.
812- */
813- res_key [res_key_len ] = 0 ;
814-
815815 MAKE_STD_ZVAL (value );
816816
817817 if (php_memc_zval_from_payload (value , payload , payload_len , flags , m_obj -> serializer TSRMLS_CC ) < 0 ) {
@@ -829,7 +829,21 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
829829 continue ;
830830 }
831831
832- add_assoc_zval_ex (return_value , res_key , res_key_len + 1 , value );
832+ if (res_key [res_key_len - 1 ] != '\0' ) {
833+ /* Terminate if needed */
834+ char key_buffer [MEMCACHED_MAX_KEY ];
835+
836+ if (res_key_len < MEMCACHED_MAX_KEY ) {
837+ memcpy (key_buffer , res_key , res_key_len );
838+ key_buffer [res_key_len ] = '\0' ;
839+
840+ add_assoc_zval_ex (return_value , key_buffer , res_key_len + 1 , value );
841+ }
842+ }
843+ else {
844+ add_assoc_zval_ex (return_value , res_key , res_key_len + 1 , value );
845+ }
846+
833847 if (cas_tokens ) {
834848 cas = memcached_result_cas (& result );
835849 add_assoc_double_ex (cas_tokens , res_key , res_key_len + 1 , (double )cas );
@@ -992,9 +1006,9 @@ static void php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_
9921006 Returns the next result from a previous delayed request */
9931007PHP_METHOD (Memcached , fetch )
9941008{
995- char * res_key = NULL ;
1009+ const char * res_key = NULL ;
9961010 size_t res_key_len = 0 ;
997- char * payload = NULL ;
1011+ const char * payload = NULL ;
9981012 size_t payload_len = 0 ;
9991013 zval * value ;
10001014 uint32_t flags = 0 ;
@@ -1049,9 +1063,9 @@ PHP_METHOD(Memcached, fetch)
10491063 Returns all the results from a previous delayed request */
10501064PHP_METHOD (Memcached , fetchAll )
10511065{
1052- char * res_key = NULL ;
1066+ const char * res_key = NULL ;
10531067 size_t res_key_len = 0 ;
1054- char * payload = NULL ;
1068+ const char * payload = NULL ;
10551069 size_t payload_len = 0 ;
10561070 zval * value , * entry ;
10571071 uint32_t flags ;
@@ -1965,7 +1979,7 @@ PHP_METHOD(Memcached, getServerByKey)
19651979{
19661980 char * server_key ;
19671981 int server_key_len ;
1968- memcached_server_instance_st * server_instance ;
1982+ const memcached_instance_st * server_instance ;
19691983 memcached_return error ;
19701984 MEMC_METHOD_INIT_VARS ;
19711985
@@ -2083,7 +2097,7 @@ PHP_METHOD(Memcached, getLastErrorErrno)
20832097 Was added in 0.34 according to libmemcached's Changelog */
20842098PHP_METHOD (Memcached , getLastDisconnectedServer )
20852099{
2086- memcached_server_instance_st * server_instance ;
2100+ const memcached_instance_st * server_instance ;
20872101 MEMC_METHOD_INIT_VARS ;
20882102
20892103 if (zend_parse_parameters_none () == FAILURE ) {
@@ -2398,12 +2412,7 @@ static int php_memc_set_option(php_memc_t *i_obj, long option, zval *value TSRML
23982412 */
23992413 flag = (memcached_behavior ) option ;
24002414 convert_to_long (value );
2401- if (flag < 0 ||
2402- /* MEMCACHED_BEHAVIOR_MAX was added in somewhere around 0.36 or 0.37 */
2403- #if defined(LIBMEMCACHED_VERSION_HEX ) & & LIBMEMCACHED_VERSION_HEX >= 0x00037000
2404- flag >= MEMCACHED_BEHAVIOR_MAX ||
2405- #endif
2406- memcached_behavior_set (m_obj -> memc , flag , (uint64_t )Z_LVAL_P (value )) != MEMCACHED_SUCCESS ) {
2415+ if (memcached_behavior_set (m_obj -> memc , flag , (uint64_t ) Z_LVAL_P (value )) != MEMCACHED_SUCCESS ) {
24072416 php_error_docref (NULL TSRMLS_CC , E_WARNING , "error setting memcached option" );
24082417 return 0 ;
24092418 }
@@ -2660,7 +2669,7 @@ ZEND_RSRC_DTOR_FUNC(php_memc_sess_dtor)
26602669/* }}} */
26612670
26622671/* {{{ internal API functions */
2663- static memcached_return php_memc_do_serverlist_callback (const memcached_st * ptr , memcached_server_instance_st instance , void * in_context )
2672+ static memcached_return php_memc_do_serverlist_callback (const memcached_st * ptr , const memcached_instance_st * instance , void * in_context )
26642673{
26652674 struct callbackContext * context = (struct callbackContext * ) in_context ;
26662675 zval * array ;
@@ -2671,14 +2680,17 @@ static memcached_return php_memc_do_serverlist_callback(const memcached_st *ptr,
26712680 add_assoc_long (array , "port" , memcached_server_port (instance ));
26722681 /*
26732682 * API does not allow to get at this field.
2683+ *
2684+ * If you comment out stuff like this, please fix tests. -- Mikko
2685+ *
26742686 add_assoc_long(array, "weight", instance->weight);
26752687 */
26762688
26772689 add_next_index_zval (context -> return_value , array );
26782690 return MEMCACHED_SUCCESS ;
26792691}
26802692
2681- static memcached_return php_memc_do_stats_callback (const memcached_st * ptr , memcached_server_instance_st instance , void * in_context )
2693+ static memcached_return php_memc_do_stats_callback (const memcached_st * ptr , const memcached_instance_st * instance , void * in_context )
26822694{
26832695 char * hostport = NULL ;
26842696 int hostport_len ;
@@ -2722,7 +2734,7 @@ static memcached_return php_memc_do_stats_callback(const memcached_st *ptr, memc
27222734 return MEMCACHED_SUCCESS ;
27232735}
27242736
2725- static memcached_return php_memc_do_version_callback (const memcached_st * ptr , memcached_server_instance_st instance , void * in_context )
2737+ static memcached_return php_memc_do_version_callback (const memcached_st * ptr , const memcached_instance_st * instance , void * in_context )
27262738{
27272739 char * hostport = NULL ;
27282740 char version [16 ];
@@ -2953,19 +2965,26 @@ static char *php_memc_zval_to_payload(zval *value, size_t *payload_len, uint32_t
29532965}
29542966
29552967/* The caller MUST free the payload */
2956- static int php_memc_zval_from_payload (zval * value , char * payload , size_t payload_len , uint32_t flags , enum memcached_serializer serializer TSRMLS_DC )
2968+ 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 )
29572969{
2970+ char * pl ;
2971+ size_t pl_len ;
2972+
29582973 /*
29592974 A NULL payload is completely valid if length is 0, it is simply empty.
29602975 */
29612976 zend_bool payload_emalloc = 0 ;
2962- char * buffer = NULL ;
29632977
2964- if (payload == NULL && payload_len > 0 ) {
2978+ // Explicit cast
2979+ pl = (char * ) payload ;
2980+ pl_len = payload_len ;
2981+
2982+
2983+ if (pl == NULL && pl_len > 0 ) {
29652984 php_error_docref (NULL TSRMLS_CC , E_WARNING ,
2966- "Could not handle non-existing value of length %zu" , payload_len );
2985+ "Could not handle non-existing value of length %zu" , pl_len );
29672986 return -1 ;
2968- } else if (payload == NULL ) {
2987+ } else if (pl == NULL ) {
29692988 if (MEMC_VAL_GET_TYPE (flags ) == MEMC_VAL_IS_BOOL ) {
29702989 ZVAL_FALSE (value );
29712990 } else {
@@ -2976,6 +2995,7 @@ static int php_memc_zval_from_payload(zval *value, char *payload, size_t payload
29762995
29772996 if (flags & MEMC_VAL_COMPRESSED ) {
29782997 uint32_t len ;
2998+ char * buffer = NULL ;
29792999 unsigned long length ;
29803000 zend_bool decompress_status = 0 ;
29813001
@@ -3017,49 +3037,47 @@ static int php_memc_zval_from_payload(zval *value, char *payload, size_t payload
30173037 efree (buffer );
30183038 return -1 ;
30193039 }
3020- payload = buffer ;
3021- payload_len = length ;
3040+ pl = buffer ;
3041+ pl_len = length ;
30223042 payload_emalloc = 1 ;
30233043 }
30243044
3025- payload [payload_len ] = 0 ;
3026-
30273045 switch (MEMC_VAL_GET_TYPE (flags )) {
30283046 case MEMC_VAL_IS_STRING :
30293047 if (payload_emalloc ) {
3030- ZVAL_STRINGL (value , payload , payload_len , 0 );
3048+ ZVAL_STRINGL (value , pl , pl_len , 0 );
30313049 payload_emalloc = 0 ;
30323050 } else {
3033- ZVAL_STRINGL (value , payload , payload_len , 1 );
3051+ ZVAL_STRINGL (value , pl , pl_len , 1 );
30343052 }
30353053 break ;
30363054
30373055 case MEMC_VAL_IS_LONG :
30383056 {
3039- long lval = strtol (payload , NULL , 10 );
3057+ long lval = strtol (pl , NULL , 10 );
30403058 ZVAL_LONG (value , lval );
30413059 break ;
30423060 }
30433061
30443062 case MEMC_VAL_IS_DOUBLE :
3045- if (payload_len == 8 && memcmp (payload , "Infinity" , 8 ) == 0 ) {
3063+ if (pl_len == 8 && memcmp (pl , "Infinity" , 8 ) == 0 ) {
30463064 ZVAL_DOUBLE (value , php_get_inf ());
3047- } else if (payload_len == 9 && memcmp (payload , "-Infinity" , 9 ) == 0 ) {
3065+ } else if (pl_len == 9 && memcmp (pl , "-Infinity" , 9 ) == 0 ) {
30483066 ZVAL_DOUBLE (value , - php_get_inf ());
3049- } else if (payload_len == 3 && memcmp (payload , "NaN" , 3 ) == 0 ) {
3067+ } else if (pl_len == 3 && memcmp (pl , "NaN" , 3 ) == 0 ) {
30503068 ZVAL_DOUBLE (value , php_get_nan ());
30513069 } else {
3052- ZVAL_DOUBLE (value , zend_strtod (payload , NULL ));
3070+ ZVAL_DOUBLE (value , zend_strtod (pl , NULL ));
30533071 }
30543072 break ;
30553073
30563074 case MEMC_VAL_IS_BOOL :
3057- ZVAL_BOOL (value , payload_len > 0 && payload [0 ] == '1' );
3075+ ZVAL_BOOL (value , pl_len > 0 && pl [0 ] == '1' );
30583076 break ;
30593077
30603078 case MEMC_VAL_IS_SERIALIZED :
30613079 {
3062- const char * payload_tmp = payload ;
3080+ const char * payload_tmp = pl ;
30633081 php_unserialize_data_t var_hash ;
30643082
30653083 PHP_VAR_UNSERIALIZE_INIT (var_hash );
@@ -3075,7 +3093,7 @@ static int php_memc_zval_from_payload(zval *value, char *payload, size_t payload
30753093
30763094 case MEMC_VAL_IS_IGBINARY :
30773095#ifdef HAVE_MEMCACHED_IGBINARY
3078- if (igbinary_unserialize ((uint8_t * )payload , payload_len , & value TSRMLS_CC )) {
3096+ if (igbinary_unserialize ((uint8_t * )pl , pl_len , & value TSRMLS_CC )) {
30793097 ZVAL_FALSE (value );
30803098 php_error_docref (NULL TSRMLS_CC , E_WARNING , "could not unserialize value with igbinary" );
30813099 goto my_error ;
@@ -3089,9 +3107,9 @@ static int php_memc_zval_from_payload(zval *value, char *payload, size_t payload
30893107 case MEMC_VAL_IS_JSON :
30903108#ifdef HAVE_JSON_API
30913109# if HAVE_JSON_API_5_2
3092- php_json_decode (value , payload , payload_len , (serializer == SERIALIZER_JSON_ARRAY ) TSRMLS_CC );
3110+ php_json_decode (value , pl , pl_len , (serializer == SERIALIZER_JSON_ARRAY ) TSRMLS_CC );
30933111# elif HAVE_JSON_API_5_3
3094- php_json_decode (value , payload , payload_len , (serializer == SERIALIZER_JSON_ARRAY ), JSON_PARSER_DEFAULT_DEPTH TSRMLS_CC );
3112+ php_json_decode (value , pl , pl_len , (serializer == SERIALIZER_JSON_ARRAY ), JSON_PARSER_DEFAULT_DEPTH TSRMLS_CC );
30953113# endif
30963114#else
30973115 php_error_docref (NULL TSRMLS_CC , E_WARNING , "could not unserialize value, no json support" );
@@ -3105,14 +3123,14 @@ static int php_memc_zval_from_payload(zval *value, char *payload, size_t payload
31053123 }
31063124
31073125 if (payload_emalloc ) {
3108- efree (payload );
3126+ efree (pl );
31093127 }
31103128
31113129 return 0 ;
31123130
31133131my_error :
31143132 if (payload_emalloc ) {
3115- efree (payload );
3133+ efree (pl );
31163134 }
31173135 return -1 ;
31183136}
@@ -3269,9 +3287,9 @@ static int php_memc_do_result_callback(zval *zmemc_obj, zend_fcall_info *fci,
32693287 zend_fcall_info_cache * fcc ,
32703288 memcached_result_st * result TSRMLS_DC )
32713289{
3272- char * res_key = NULL ;
3290+ const char * res_key = NULL ;
32733291 size_t res_key_len = 0 ;
3274- char * payload = NULL ;
3292+ const char * payload = NULL ;
32753293 size_t payload_len = 0 ;
32763294 zval * value , * retval = NULL ;
32773295 uint64_t cas = 0 ;
0 commit comments