Skip to content

Extended key checking to match the language of the memcached spec #167

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions php_memcached.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,21 @@ static int php_memc_list_entry(void)
return le_memc;
}

static int php_memc_valid_key(char *key)
{
if (!*key) {
return 0;
}

for ( ; *key; ++key) {
if (iscntrl(*key) || isspace(*key)) {
return 0;
}
}

return 1;
}

/* {{{ Memcached::__construct([string persistent_id[, callback on_new[, string connection_str]]]))
Creates a Memcached object, optionally using persistent memcache connection */
static PHP_METHOD(Memcached, __construct)
Expand Down Expand Up @@ -576,7 +591,7 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
MEMC_METHOD_FETCH_OBJECT;
i_obj->rescode = MEMCACHED_SUCCESS;

if (key_len == 0 || strchr(key, ' ')) {
if (key_len == 0 || !php_memc_valid_key(key)) {
i_obj->rescode = MEMCACHED_BAD_KEY_PROVIDED;
RETURN_FROM_GET;
}
Expand Down Expand Up @@ -1448,7 +1463,7 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool
MEMC_METHOD_FETCH_OBJECT;
i_obj->rescode = MEMCACHED_SUCCESS;

if (key_len == 0 || strchr(key, ' ')) {
if (key_len == 0 || !php_memc_valid_key(key)) {
i_obj->rescode = MEMCACHED_BAD_KEY_PROVIDED;
RETURN_FALSE;
}
Expand Down Expand Up @@ -1599,7 +1614,7 @@ static void php_memc_cas_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
MEMC_METHOD_FETCH_OBJECT;
i_obj->rescode = MEMCACHED_SUCCESS;

if (key_len == 0 || strchr(key, ' ')) {
if (key_len == 0 || !php_memc_valid_key(key)) {
i_obj->rescode = MEMCACHED_BAD_KEY_PROVIDED;
RETURN_FALSE;
}
Expand Down Expand Up @@ -1717,7 +1732,7 @@ static void php_memc_delete_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
MEMC_METHOD_FETCH_OBJECT;
i_obj->rescode = MEMCACHED_SUCCESS;

if (key_len == 0 || strchr(key, ' ')) {
if (key_len == 0 || !php_memc_valid_key(key)) {
i_obj->rescode = MEMCACHED_BAD_KEY_PROVIDED;
RETURN_FALSE;
}
Expand Down Expand Up @@ -1817,7 +1832,7 @@ static void php_memc_incdec_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key,
MEMC_METHOD_FETCH_OBJECT;
i_obj->rescode = MEMCACHED_SUCCESS;

if (key_len == 0 || strchr(key, ' ')) {
if (key_len == 0 || !php_memc_valid_key(key)) {
i_obj->rescode = MEMCACHED_BAD_KEY_PROVIDED;
RETURN_FALSE;
}
Expand Down Expand Up @@ -4483,6 +4498,7 @@ int php_memc_sess_list_entry(void)
return le_memc_sess;
}


/* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(memcached)
{
Expand Down
2 changes: 2 additions & 0 deletions php_memcached_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <php.h>
#include <php_main.h>

Expand Down Expand Up @@ -189,6 +190,7 @@ typedef struct {
} memcached_sess;

int php_memc_sess_list_entry(void);
int php_memc_valid_key(char *);

char *php_memc_printable_func (zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TSRMLS_DC);

Expand Down
74 changes: 74 additions & 0 deletions tests/keys.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED);
var_dump ($ascii->set ('ascii key with spaces', 'this is a test'));
var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED);

var_dump ($ascii->set ('', 'this is a test'));
var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED);

for ($i=0;$i<32;$i++) {
var_dump ($ascii->set ('ascii key with non-printable char "' . chr($i) . '"newline', 'this is a test'));
var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED);
}

var_dump ($ascii->set (str_repeat ('1234567890', 512), 'this is a test'));
var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED);

Expand All @@ -30,4 +38,70 @@ bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
bool(false)
bool(true)
OK