memcached_return memcached_purge(memcached_server_st *ptr);
+static inline memcached_return memcached_validate_key_length(size_t key_length,
+ bool binary) {
+ unlikely (key_length == 0)
+ return MEMCACHED_BAD_KEY_PROVIDED;
+
+ if (binary)
+ {
+ unlikely (key_length > 0xffff)
+ return MEMCACHED_BAD_KEY_PROVIDED;
+ }
+ else
+ {
+ unlikely (key_length > 250)
+ return MEMCACHED_BAD_KEY_PROVIDED;
+ }
+
+ return MEMCACHED_SUCCESS;
+}
+
#endif /* __COMMON_H__ */
char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
unsigned int server_key;
- unlikely (key_length == 0)
- return MEMCACHED_NO_KEY_PROVIDED;
-
unlikely (ptr->hosts == NULL || ptr->number_of_hosts == 0)
return MEMCACHED_NO_SERVERS;
{
unsigned int server_key;
- unlikely (key_length == 0)
- return MEMCACHED_NO_KEY_PROVIDED;
-
unlikely (ptr->hosts == NULL || ptr->number_of_hosts == 0)
return MEMCACHED_NO_SERVERS;
- if ((ptr->flags & MEM_VERIFY_KEY) && (memcachd_key_test((char **)&key, &key_length, 1) == MEMCACHED_BAD_KEY_PROVIDED))
- return MEMCACHED_BAD_KEY_PROVIDED;
-
server_key= memcached_generate_hash(ptr, key, key_length);
protocol_binary_request_incr request= {.bytes= {0}};
uint32_t offset,
uint64_t *value)
{
- memcached_return rc;
+ memcached_return rc= memcached_validate_key_length(key_length, ptr->flags & MEM_BINARY_PROTOCOL);
+ unlikely (rc != MEMCACHED_SUCCESS)
+ return rc;
LIBMEMCACHED_MEMCACHED_INCREMENT_START();
if (ptr->flags & MEM_BINARY_PROTOCOL)
uint32_t offset,
uint64_t *value)
{
- memcached_return rc;
+ memcached_return rc= memcached_validate_key_length(key_length, ptr->flags & MEM_BINARY_PROTOCOL);
+ unlikely (rc != MEMCACHED_SUCCESS)
+ return rc;
LIBMEMCACHED_MEMCACHED_DECREMENT_START();
if (ptr->flags & MEM_BINARY_PROTOCOL)
MEMCACHED_ERRNO,
MEMCACHED_FAIL_UNIX_SOCKET,
MEMCACHED_NOT_SUPPORTED,
- MEMCACHED_NO_KEY_PROVIDED,
+ MEMCACHED_NO_KEY_PROVIDED, /* Deprecated. Use MEMCACHED_BAD_KEY_PROVIDED! */
MEMCACHED_FETCH_NOTFINISHED,
MEMCACHED_TIMEOUT,
MEMCACHED_BUFFERED,
LIBMEMCACHED_MEMCACHED_DELETE_START();
- unlikely (key_length == 0)
- return MEMCACHED_NO_KEY_PROVIDED;
+ rc= memcached_validate_key_length(key_length,
+ ptr->flags & MEM_BINARY_PROTOCOL);
+ unlikely (rc != MEMCACHED_SUCCESS)
+ return rc;
unlikely (ptr->hosts == NULL || ptr->number_of_hosts == 0)
return MEMCACHED_NO_SERVERS;
else
request.message.header.request.opcode= PROTOCOL_BINARY_CMD_GETKQ;
+ memcached_return vk;
+ vk= memcached_validate_key_length(key_length[x],
+ ptr->flags & MEM_BINARY_PROTOCOL);
+ unlikely (vk != MEMCACHED_SUCCESS) {
+ if (x > 0)
+ memcached_io_reset(ptr);
+ return vk;
+ }
+
request.message.header.request.keylen= htons((uint16_t)key_length[x]);
request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES;
request.message.header.request.bodylen= htonl(key_length[x]);
unsigned int number_of_keys)
{
uint32_t x;
+ memcached_return rc;
for (x= 0; x < number_of_keys; x++)
{
size_t y;
- if (*(key_length + x) == 0)
- return MEMCACHED_BAD_KEY_PROVIDED;
+ rc= memcached_validate_key_length(*(key_length + x), false);
+ if (rc != MEMCACHED_SUCCESS)
+ return rc;
+
+
for (y= 0; y < *(key_length + x); y++)
{
{
uint32_t server_key;
- unlikely (key_length == 0)
- {
- *error= MEMCACHED_NO_KEY_PROVIDED;
+ *error= memcached_validate_key_length(key_length,
+ ptr->flags & MEM_BINARY_PROTOCOL);
+ unlikely (*error != MEMCACHED_SUCCESS)
return NULL;
- }
unlikely (ptr->number_of_hosts == 0)
{
if (args != NULL)
{
int len= strlen(args);
+
+ rc= memcached_validate_key_length(len, true);
+ unlikely (rc != MEMCACHED_SUCCESS)
+ return rc;
+
request.message.header.request.keylen= htons((uint16_t)len);
request.message.header.request.bodylen= htonl(len);
WATCHPOINT_ASSERT(!(value == NULL && value_length > 0));
- unlikely (key_length == 0)
- return MEMCACHED_NO_KEY_PROVIDED;
-
+ rc= memcached_validate_key_length(key_length, ptr->flags & MEM_BINARY_PROTOCOL);
+ unlikely (rc != MEMCACHED_SUCCESS)
+ return rc;
+
unlikely (ptr->number_of_hosts == 0)
return MEMCACHED_NO_SERVERS;
uint32_t flags;
memcached_st *clone;
unsigned int set= 1;
+ size_t max_keylen= 0xffff;
clone= memcached_clone(NULL, memc);
assert(clone);
rc= memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
assert(rc == MEMCACHED_SUCCESS);
- string= memcached_get(clone, key, strlen(key),
- &string_length, &flags, &rc);
- assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
- assert(string_length == 0);
- assert(!string);
+ /* All keys are valid in the binary protocol (except for length) */
+ if (memcached_behavior_get(clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 0)
+ {
+ string= memcached_get(clone, key, strlen(key),
+ &string_length, &flags, &rc);
+ assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
+ assert(string_length == 0);
+ assert(!string);
- set= 0;
- rc= memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
- assert(rc == MEMCACHED_SUCCESS);
- string= memcached_get(clone, key, strlen(key),
- &string_length, &flags, &rc);
- assert(rc == MEMCACHED_NOTFOUND);
- assert(string_length == 0);
- assert(!string);
+ set= 0;
+ rc= memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
+ assert(rc == MEMCACHED_SUCCESS);
+ string= memcached_get(clone, key, strlen(key),
+ &string_length, &flags, &rc);
+ assert(rc == MEMCACHED_NOTFOUND);
+ assert(string_length == 0);
+ assert(!string);
- /* Test multi key for bad keys */
- {
+ /* Test multi key for bad keys */
char *keys[] = { "GoodKey", "Bad Key", "NotMine" };
size_t key_lengths[] = { 7, 7, 7 };
set= 1;
rc= memcached_mget_by_key(clone, "foo daddy", 9, keys, key_lengths, 1);
assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
+
+ max_keylen= 250;
+
+ /* The following test should be moved to the end of this function when the
+ memcached server is updated to allow max size length of the keys in the
+ binary protocol
+ */
+ rc= memcached_callback_set(clone, MEMCACHED_CALLBACK_PREFIX_KEY, NULL);
+ assert(rc == MEMCACHED_SUCCESS);
+
+ char *longkey= malloc(max_keylen + 1);
+ if (longkey != NULL)
+ {
+ memset(longkey, 'a', max_keylen + 1);
+ string= memcached_get(clone, longkey, max_keylen,
+ &string_length, &flags, &rc);
+ assert(rc == MEMCACHED_NOTFOUND);
+ assert(string_length == 0);
+ assert(!string);
+
+ string= memcached_get(clone, longkey, max_keylen + 1,
+ &string_length, &flags, &rc);
+ assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
+ assert(string_length == 0);
+ assert(!string);
+
+ free(longkey);
+ }
}
/* Make sure zero length keys are marked as bad */