8000 * off-by-one in hash iteration when dealing with string keys from cha… · jrtkcoder/phpredis@9d51c89 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9d51c89

Browse files
committed
* off-by-one in hash iteration when dealing with string keys from char+int -> zend_string
* emalloc -> safe_emalloc * dump cmd used redis_ping_response, instead of the proper redis_string_response
1 parent 9ff8f49 commit 9d51c89

File tree

4 files changed

+31
-36
lines changed

4 files changed

+31
-36
lines changed

redis.c

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1877,11 +1877,6 @@ generic_mset(INTERNAL_FUNCTION_PARAMETERS, char *kw, ResultCallback fun) {
18771877
} else {
18781878
key_len = key_zstr->len;
18791879
key = key_zstr->val;
1880-
1881-
// When not an integer key, the length will include the \0
1882-
if (key_len > 0) {
1883-
key_len--;
1884-
}
18851880
}
18861881

18871882
if(step == 0)
@@ -3277,7 +3272,7 @@ PHP_METHOD(Redis, script) {
32773272
argc = ZEND_NUM_ARGS();
32783273

32793274
/* Allocate an array big enough to store our arguments */
3280-
z_args = emalloc(argc * sizeof(zval*));
3275+
z_args = (zval *) safe_emalloc(sizeof(zval), argc, 0);
32813276

32823277
/* Make sure we can grab our arguments, we have a string directive */
32833278
if(zend_get_parameters_array(ht, argc, z_args) == FAILURE ||
@@ -3336,7 +3331,7 @@ PHP_METHOD(Redis, script) {
33363331

33373332
/* {{{ proto DUMP key */
33383333
PHP_METHOD(Redis, dump) {
3339-
REDIS_PROCESS_KW_CMD("DUMP", redis_key_cmd, redis_ping_response);
3334+
REDIS_PROCESS_KW_CMD("DUMP", redis_key_cmd, redis_string_response);
33403335
}
33413336
/* }}} */
33423337

@@ -3643,9 +3638,9 @@ PHP_METHOD(Redis, getAuth) {
36433638
PHP_METHOD(Redis, client) {
36443639
zval *object;
36453640
RedisSock *redis_sock;
3646-
char *cmd, *opt=NULL, *arg=NULL;
3647-
int cmd_len;
3648-
size_t opt_len, arg_len;
3641+
char *cmd, *opt = NULL, *arg = NULL;
3642+
int cmd_len = 0;
3643+
size_t opt_len = 0, arg_len = 0;
36493644

36503645
// Parse our method parameters
36513646
if(zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
@@ -3690,13 +3685,13 @@ PHP_METHOD(Redis, client) {
36903685

36913686
/* {{{ proto mixed Redis::rawcommand(string $command, [ $arg1 ... $argN]) */
36923687
PHP_METHOD(Redis, rawcommand) {
3693-
int argc = ZEND_NUM_ARGS(), cmd_len;
3688+
int argc = ZEND_NUM_ARGS(), cmd_len = 0;
36943689
char *cmd = NULL;
36953690
RedisSock *redis_sock;
36963691
zval *z_args;
36973692

36983693< 8000 /code>
/* Sanity check on arguments */
3699-
z_args = emalloc(argc * sizeof(zval*));
3694+
z_args = (zval *) safe_emalloc(sizeof(zval), argc, 0);
37003695
if (argc < 1) {
37013696
php_error_docref(NULL TSRMLS_CC, E_WARNING,
37023697
"Must pass at least one command keyword");
@@ -3707,7 +3702,7 @@ PHP_METHOD(Redis, rawcommand) {
37073702
"Internal PHP error parsing arguments");
37083703
efree(z_args);
37093704
RETURN_FALSE;
3710-
} else if (redis_build_raw_cmd(&z_args, argc, &cmd, &cmd_len TSRMLS_CC) < 0 ||
3705+
} else if (redis_build_raw_cmd(z_args, argc, &cmd, &cmd_len TSRMLS_CC) < 0 ||
37113706
redis_sock_get(getThis(), &redis_sock TSRMLS_CC, 0) < 0)
37123707
{
37133708
if (cmd) efree(cmd);

redis_cluster.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2883,7 +2883,7 @@ PHP_METHOD(RedisCluster, rawcommand) {
28832883
"Internal PHP error parsing method parameters.");
28842884
efree(z_args);
28852885
RETURN_FALSE;
2886-
} else if (redis_build_raw_cmd(&z_args+1, argc-1, &cmd, &cmd_len TSRMLS_CC) ||
2886+
} else if (redis_build_raw_cmd(z_args+1, argc-1, &cmd, &cmd_len TSRMLS_CC) ||
28872887
(slot = cluster_cmd_get_slot(c, &z_args[0] TSRMLS_CC))<0)
28882888
{
28892889
if (cmd) efree(cmd);

redis_commands.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,32 +41,32 @@ int redis_empty_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
4141
/* Helper to construct a raw command. Given that the cluster and non cluster
4242
* versions are different (RedisCluster needs an additional argument to direct
4343
* the command) we take the start of our array and count */
44-
int redis_build_raw_cmd(zval **z_args, int argc, char **cmd, int *cmd_len TSRMLS_DC)
44+
int redis_build_raw_cmd(zval *z_args, int argc, char **cmd, int *cmd_len TSRMLS_DC)
4545
{
4646
smart_string cmdstr = {0};
4747
int i;
4848

4949
/* Make sure our first argument is a string */
50-
if (Z_TYPE_P(z_args[0]) != IS_STRING) {
50+
if (Z_TYPE(z_args[0]) != IS_STRING) {
5151
php_error_docref(NULL TSRMLS_CC, E_WARNING,
5252
"When sending a 'raw' command, the first argument must be a string!");
5353
return FAILURE;
5454
}
5555

5656
/* Initialize our command string */
57-
redis_cmd_init_sstr(&cmdstr, argc-1, Z_STRVAL_P(z_args[0]), Z_STRLEN_P(z_args[0]));
57+
redis_cmd_init_sstr(&cmdstr, argc-1, Z_STRVAL(z_args[0]), Z_STRLEN(z_args[0]));
5858

5959
for (i = 1; i < argc; i++) {
60-
switch (Z_TYPE_P(z_args[i])) {
60+
switch (Z_TYPE(z_args[i])) {
6161
case IS_STRING:
62-
redis_cmd_append_sstr(&cmdstr, Z_STRVAL_P(z_args[i]),
63-
Z_STRLEN_P(z_args[i]));
62+
redis_cmd_append_sstr(&cmdstr, Z_STRVAL(z_args[i]),
63+
Z_STRLEN(z_args[i]));
6464
break;
6565
case IS_LONG:
66-
redis_cmd_append_sstr_long(&cmdstr,Z_LVAL_P(z_args[i]));
66+
redis_cmd_append_sstr_long(&cmdstr,Z_LVAL(z_args[i]));
6767
break;
6868
case IS_DOUBLE:
69-
redis_cmd_append_sstr_dbl(&cmdstr,Z_DVAL_P(z_args[i]));
69+
redis_cmd_append_sstr_dbl(&cmdstr,Z_DVAL(z_args[i]));
7070
break;
7171
default:
7272
php_error_docref(NULL TSRMLS_CC, E_WARNING,
@@ -1616,7 +1616,7 @@ int redis_hmset_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
16161616
} else {
16171617
// Length returned includes the \0
16181618
mem = mem_zstring->val;
1619-
mem_len = mem_zstring->len - 1;
1619+
mem_len = mem_zstring->len;
16201620
}
16211621

16221622
// Serialize value (if directed)

redis_commands.h

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ typedef struct subscribeContext {
2222
} subscribeContext;
2323

2424
/* Construct a raw command */
25-
int redis_build_raw_cmd(zval **z_args, int argc, char **cmd, int *cmd_len TSRMLS_DC);
25+
int redis_build_raw_cmd(zval *z_args, int argc, char **cmd, int *cmd_len TSRMLS_DC);
2626

2727
/* Redis command generics. Many commands share common prototypes meaning that
2828
* we can write one function to handle all of them. For example, there are
@@ -44,7 +44,7 @@ int redis_kv_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
4444
char *kw, char **cmd, int *cmd_len, short *slot, void **ctx);
4545

4646
int redis_key_str_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
47-
char *kw, char **cmd, int *cmd_len, short *slot, void **ctx);
47+
char *kw, char **cmd, int *cmd_len, short *slot, void **ctx);
4848

4949
int redis_key_key_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
5050
char *kw, char **cmd, int *cmd_len, short *slot, void **ctx);
@@ -79,11 +79,11 @@ typedef int (*zrange_cb)(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
7979
char *,char**,int*,int*,short*,void**);
8080

8181
int redis_zrange_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
82-
char *kw, char **cmd, int *cmd_len, int *withscores, short *slot,
82+
char *kw, char **cmd, int *cmd_len, int *withscores, short *slot,
8383
void **ctx);
8484

8585
int redis_zrangebyscore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
86-
char *kw, char **cmd, int *cmd_len, int *withscores, short *slot,
86+
char *kw, char **cmd, int *cmd_len, int *withscores, short *slot,
8787
void **ctx);
8888

8989
int redis_zinter_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
@@ -102,7 +102,7 @@ int redis_gen_zlex_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
102102
char *kw, char **cmd, int *cmd_len, short *slot, void **ctx);
103103

104104
/* Commands which need a unique construction mechanism. This is either because
105-
* they don't share a signature with any other command, or because there is
105+
* they don't share a signature with any other command, or because there is
106106
* specific processing we do (e.g. verifying subarguments) that make them
107107
* unique */
108108

@@ -130,7 +130,7 @@ int redis_hmget_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
130130
int redis_hmset_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
131131
char **cmd, int *cmd_len, short *slot, void **ctx);
132132

133-
int redis_bitop_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
133+
int redis_bitop_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
134134
char **cmd, int *cmd_len, short *slot, void **ctx);
135135

136136
int redis_bitcount_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
@@ -224,20 +224,20 @@ int redis_command_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
224224
int redis_fmt_scan_cmd(char **cmd, REDIS_SCAN_TYPE type, char *key, int key_len,
225225
long it, char *pat, int pat_len, long count);
226226

227-
/* Commands that don't communicate with Redis at all (such as getOption,
227+
/* Commands that don't communicate with Redis at all (such as getOption,
228228
* setOption, _prefix, _serialize, etc). These can be handled in one place
229-
* with the method of grabbing our RedisSock* object in different ways
229+
* with the method of grabbing our RedisSock* object in different ways
230230
* depending if this is a Redis object or a RedisCluster object. */
231231

232-
void redis_getoption_handler(INTERNAL_FUNCTION_PARAMETERS,
232+
void redis_getoption_handler(INTERNAL_FUNCTION_PARAMETERS,
233233
RedisSock *redis_sock, redisCluster *c);
234-
void redis_setoption_handler(INTERNAL_FUNCTION_PARAMETERS,
234+
void redis_setoption_handler(INTERNAL_FUNCTION_PARAMETERS,
235235
RedisSock *redis_sock, redisCluster *c);
236-
void redis_prefix_handler(INTERNAL_FUNCTION_PARAMETERS,
236+
void redis_prefix_handler(INTERNAL_FUNCTION_PARAMETERS,
237237
RedisSock *redis_sock);
238-
void redis_serialize_handler(INTERNAL_FUNCTION_PARAMETERS,
238+
void redis_serialize_handler(INTERNAL_FUNCTION_PARAMETERS,
239239
RedisSock *redis_sock);
240-
void redis_unserialize_handler(INTERNAL_FUNCTION_PARAMETERS,
240+
void redis_unserialize_handler(INTERNAL_FUNCTION_PARAMETERS,
241241
RedisSock *redis_sock, zend_class_entry *ex);
242242

243243
#endif

0 commit comments

Comments
 (0)
0