@@ -202,15 +202,28 @@ static inline php_memc_object_t *php_memc_fetch_object(zend_object *obj) {
202202 } \
203203 memc_user_data = (php_memc_user_data_t *) memcached_get_user_data(intern->memc);
204204
205- #define MEMC_CHECK_KEY (intern , key ) \
206- if (UNEXPECTED(ZSTR_LEN(key) == 0 || \
207- ZSTR_LEN(key) > MEMC_OBJECT_KEY_MAX_LENGTH || \
208- (memcached_behavior_get(intern->memc, \
209- MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? \
210- strchr(ZSTR_VAL(key), '\n') : \
211- strchr(ZSTR_VAL(key), ' ')))) { \
212- intern->rescode = MEMCACHED_BAD_KEY_PROVIDED; \
213- RETURN_FALSE; \
205+ static
206+ zend_bool s_memc_valid_key_binary (const char * key )
207+ {
208+ return strchr (key , '\n' ) == NULL ;
209+ }
210+
211+ static
212+ zend_bool s_memc_valid_key_ascii (const char * key )
213+ {
214+ while (* key && !iscntrl (* key ) && !isspace (* key )) ++ key ;
215+ return * key == '\0' ;
216+ }
217+
218+ #define MEMC_CHECK_KEY (intern , key ) \
219+ if (UNEXPECTED(ZSTR_LEN(key) == 0 || \
220+ ZSTR_LEN(key) > MEMC_OBJECT_KEY_MAX_LENGTH || \
221+ (memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) \
222+ ? !s_memc_valid_key_binary(ZSTR_VAL(key)) \
223+ : !s_memc_valid_key_ascii(ZSTR_VAL(key)) \
224+ ))) { \
225+ intern->rescode = MEMCACHED_BAD_KEY_PROVIDED; \
226+ RETURN_FALSE; \
214227 }
215228
216229#ifdef HAVE_MEMCACHED_PROTOCOL
@@ -307,18 +320,14 @@ static
307320PHP_INI_MH (OnUpdateSessionPrefixString )
308321{
309322 if (new_value && ZSTR_LEN (new_value ) > 0 ) {
310- char * ptr = ZSTR_VAL (new_value );
311-
312- while (* ptr != '\0' ) {
313- if (isspace (* ptr ++ )) {
314- php_error_docref (NULL , E_WARNING , "memcached.sess_prefix cannot contain whitespace characters" );
315- return FAILURE ;
316- }
317- }
318323 if (ZSTR_LEN (new_value ) > MEMCACHED_MAX_KEY ) {
319324 php_error_docref (NULL , E_WARNING , "memcached.sess_prefix too long (max: %d)" , MEMCACHED_MAX_KEY - 1 );
320325 return FAILURE ;
321326 }
327+ if (!s_memc_valid_key_ascii (ZSTR_VAL (new_value ))) {
328+ php_error_docref (NULL , E_WARNING , "memcached.sess_prefix cannot contain whitespace or control characters" );
329+ return FAILURE ;
330+ }
322331 }
323332 return OnUpdateString (entry , new_value , mh_arg1 , mh_arg2 , mh_arg3 , stage );
324333}
0 commit comments