diff --git a/package.xml b/package.xml index ec44bd1b..519de583 100644 --- a/package.xml +++ b/package.xml @@ -87,6 +87,7 @@ Fixes + diff --git a/php_memcached.c b/php_memcached.c index 1e218a00..8e4fa41d 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -228,7 +228,7 @@ zend_bool s_memc_valid_key_ascii(zend_string *key) size_t i, len = ZSTR_LEN(key); for (i = 0; i < len; i++) { - if (iscntrl(str[i]) || isspace(str[i])) + if (!isgraph(str[i]) || isspace(str[i])) return 0; } return 1; @@ -3450,6 +3450,24 @@ static PHP_METHOD(Memcached, isPristine) } /* }}} */ +/* {{{ bool Memcached::checkKey(string key) + Checks if a key is valid */ +PHP_METHOD(Memcached, checkKey) +{ + zend_string *key; + MEMC_METHOD_INIT_VARS; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(key) + ZEND_PARSE_PARAMETERS_END(); + + MEMC_METHOD_FETCH_OBJECT; + s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); + MEMC_CHECK_KEY(intern, key); + RETURN_TRUE; +} +/* }}} */ + /**************************************** Internal support code ****************************************/ diff --git a/php_memcached.stub.php b/php_memcached.stub.php index 5a735b57..819186f4 100644 --- a/php_memcached.stub.php +++ b/php_memcached.stub.php @@ -8,17 +8,17 @@ class Memcached { - public function __construct(string $persistent_id=null, callable $callback=null, string $connection_str=null) {} + public function __construct(?string $persistent_id=null, ?callable $callback=null, ?string $connection_str=null) {} public function getResultCode(): int {} public function getResultMessage(): string {} - public function get(string $key, callable $cache_cb=null, int $get_flags=0): mixed {} - public function getByKey(string $server_key, string $key, callable $cache_cb=null, int $get_flags=0): mixed {} + public function get(string $key, ?callable $cache_cb=null, int $get_flags=0): mixed {} + public function getByKey(string $server_key, string $key, ?callable $cache_cb=null, int $get_flags=0): mixed {} public function getMulti(array $keys, int $get_flags=0): false|array {} public function getMultiByKey(string $server_key, array $keys, int $get_flags=0): false|array {} - public function getDelayed(array $keys, bool $with_cas=false, callable $value_cb=null): bool {} - public function getDelayedByKey(string $server_key, array $keys, bool $with_cas=false, callable $value_cb=null): bool {} + public function getDelayed(array $keys, bool $with_cas=false, ?callable $value_cb=null): bool {} + public function getDelayedByKey(string $server_key, array $keys, bool $with_cas=false, ?callable $value_cb=null): bool {} public function fetch(): false|array {} public function fetchAll(): false|array {} @@ -64,7 +64,7 @@ public function getLastErrorCode(): int {} public function getLastErrorErrno(): int {} public function getLastDisconnectedServer(): false|array {} - public function getStats(string $type=null): false|array {} + public function getStats(?string $type=null): false|array {} public function getVersion(): false|array {} public function getAllKeys(): false|array {} @@ -83,6 +83,7 @@ public function setEncodingKey(string $key): bool {} #endif public function isPersistent(): bool {} public function isPristine(): bool {} + public function checkKey(string $key): bool {} } #ifdef HAVE_MEMCACHED_PROTOCOL diff --git a/php_memcached_arginfo.h b/php_memcached_arginfo.h index 4c8a6845..3373624e 100644 --- a/php_memcached_arginfo.h +++ b/php_memcached_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 573d35c5c6b6c397943e0f8ab9c505e2f4ce9e34 */ + * Stub hash: 3f4694d4e1f3d1647a832acd8539b056b2ab5e7a */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Memcached___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, persistent_id, IS_STRING, 1, "null") @@ -249,6 +249,10 @@ ZEND_END_ARG_INFO() #define arginfo_class_Memcached_isPristine arginfo_class_Memcached_resetServerList +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_checkKey, 0, 1, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) +ZEND_END_ARG_INFO() + #if defined(HAVE_MEMCACHED_PROTOCOL) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_MemcachedServer_run, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, address, IS_STRING, 0) @@ -325,6 +329,7 @@ ZEND_METHOD(Memcached, setEncodingKey); #endif ZEND_METHOD(Memcached, isPersistent); ZEND_METHOD(Memcached, isPristine); +ZEND_METHOD(Memcached, checkKey); #if defined(HAVE_MEMCACHED_PROTOCOL) ZEND_METHOD(MemcachedServer, run); #endif @@ -396,6 +401,7 @@ static const zend_function_entry class_Memcached_methods[] = { #endif ZEND_ME(Memcached, isPersistent, arginfo_class_Memcached_isPersistent, ZEND_ACC_PUBLIC) ZEND_ME(Memcached, isPristine, arginfo_class_Memcached_isPristine, ZEND_ACC_PUBLIC) + ZEND_ME(Memcached, checkKey, arginfo_class_Memcached_checkKey, ZEND_ACC_PUBLIC) ZEND_FE_END }; diff --git a/php_memcached_legacy_arginfo.h b/php_memcached_legacy_arginfo.h index a615e3a6..ad6d6562 100644 --- a/php_memcached_legacy_arginfo.h +++ b/php_memcached_legacy_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 573d35c5c6b6c397943e0f8ab9c505e2f4ce9e34 */ + * Stub hash: 3f4694d4e1f3d1647a832acd8539b056b2ab5e7a */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Memcached___construct, 0, 0, 0) ZEND_ARG_INFO(0, persistent_id) @@ -245,6 +245,10 @@ ZEND_END_ARG_INFO() #define arginfo_class_Memcached_isPristine arginfo_class_Memcached_getResultCode +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Memcached_checkKey, 0, 0, 1) + ZEND_ARG_INFO(0, key) +ZEND_END_ARG_INFO() + #if defined(HAVE_MEMCACHED_PROTOCOL) ZEND_BEGIN_ARG_INFO_EX(arginfo_class_MemcachedServer_run, 0, 0, 1) ZEND_ARG_INFO(0, address) @@ -321,6 +325,7 @@ ZEND_METHOD(Memcached, setEncodingKey); #endif ZEND_METHOD(Memcached, isPersistent); ZEND_METHOD(Memcached, isPristine); +ZEND_METHOD(Memcached, checkKey); #if defined(HAVE_MEMCACHED_PROTOCOL) ZEND_METHOD(MemcachedServer, run); #endif @@ -392,6 +397,7 @@ static const zend_function_entry class_Memcached_methods[] = { #endif ZEND_ME(Memcached, isPersistent, arginfo_class_Memcached_isPersistent, ZEND_ACC_PUBLIC) ZEND_ME(Memcached, isPristine, arginfo_class_Memcached_isPristine, ZEND_ACC_PUBLIC) + ZEND_ME(Memcached, checkKey, arginfo_class_Memcached_checkKey, ZEND_ACC_PUBLIC) ZEND_FE_END }; diff --git a/tests/check_key.phpt b/tests/check_key.phpt new file mode 100644 index 00000000..74ec6214 --- /dev/null +++ b/tests/check_key.phpt @@ -0,0 +1,132 @@ +--TEST-- +Memcached::checkKey() +--SKIPIF-- + +--FILE-- + false, + Memcached::OPT_VERIFY_KEY => true + )); + +$keys = [ + 'foo', + 'foo bar', + str_repeat('a',65), + str_repeat('b',250), + str_repeat('c',251), + 'Montréal', + 'København', + 'Düsseldorf', + 'Kraków', + 'İstanbul', + 'ﺎﺨﺘﺑﺍﺭ PHP', + '測試', + 'Тестирование', + 'پی ایچ پی کی جانچ ہو رہی ہے', + 'Testataan PHP: tä', + 'Að prófa PHP', + 'د پی ایچ پی ازمول', + 'Pruvà PHP' +]; +foreach($keys as $key) { + echo "Checking \"$key\"" . PHP_EOL; + echo "MEMC_CHECK_KEY: "; + var_dump($m->checkKey($key)); + echo "libmemcached: "; + var_dump($m->set($key, "this is a test")); + var_dump($m->getResultMessage()); + echo "\n"; +} +--EXPECT-- +Checking "foo" +MEMC_CHECK_KEY: bool(true) +libmemcached: bool(true) +string(7) "SUCCESS" + +Checking "foo bar" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +MEMC_CHECK_KEY: bool(true) +libmemcached: bool(true) +string(7) "SUCCESS" + +Checking "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" +MEMC_CHECK_KEY: bool(true) +libmemcached: bool(true) +string(7) "SUCCESS" + +Checking "ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "Montréal" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "København" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "Düsseldorf" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "Kraków" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "İstanbul" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "ﺎﺨﺘﺑﺍﺭ PHP" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "測試" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "Тестирование" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "پی ایچ پی کی جانچ ہو رہی ہے" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "Testataan PHP: tä" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "Að prófa PHP" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "د پی ایچ پی ازمول" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "Pruvà PHP" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" +