Skip to content

Commit f73f5fc

Browse files
yatsukhnenkomichael-grunder
authored andcommitted
Fix arguments order for SET command
Redis and Valkey doesn't consider command as invalid if order of arguments is changed but other servers like DragonflyDB does. In this commit `SET` command is fixed to more strictly follow the specs. Also fixed usage of `zend_tmp_string` for `ifeq` argument.
1 parent e73130f commit f73f5fc

File tree

1 file changed

+13
-18
lines changed

1 file changed

+13
-18
lines changed

redis_commands.c

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2293,8 +2293,8 @@ int redis_set_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
22932293
char **cmd, int *cmd_len, short *slot, void **ctx)
22942294
{
22952295
char *key = NULL, *exp_type = NULL, *set_type = NULL;
2296-
zend_string *ifeq = NULL, *tmp = NULL;
2297-
zval *z_value, *z_opts = NULL;
2296+
zval *z_value, *z_opts = NULL, *ifeq = NULL;
2297+
zend_string *zstr = NULL, *tmp = NULL;
22982298
smart_string cmdstr = {0};
22992299
zend_long expire = -1;
23002300
zend_bool get = 0;
@@ -2329,14 +2329,13 @@ int redis_set_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
23292329
zend_string_equals_literal_ci(zkey, "PXAT"))
23302330
) {
23312331
if (redis_try_get_expiry(v, &expire) == FAILURE || expire < 1) {
2332-
zend_tmp_string_release(tmp);
23332332
setExpiryWarning(v);
23342333
return FAILURE;
23352334
}
23362335

23372336
exp_type = ZSTR_VAL(zkey);
2338-
} else if (zkey && !ifeq && zend_string_equals_literal_ci(zkey, "IFEQ")) {
2339-
ifeq = zval_get_tmp_string(v, &tmp);
2337+
} else if (zkey && zend_string_equals_literal_ci(zkey, "IFEQ")) {
2338+
ifeq = v;
23402339
} else if (Z_TYPE_P(v) == IS_STRING) {
23412340
if (zend_string_equals_literal_ci(Z_STR_P(v), "KEEPTTL")) {
23422341
keep_ttl = 1;
@@ -2351,7 +2350,6 @@ int redis_set_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
23512350
} ZEND_HASH_FOREACH_END();
23522351
} else if (z_opts && Z_TYPE_P(z_opts) != IS_NULL) {
23532352
if (redis_try_get_expiry(z_opts, &expire) == FAILURE || expire < 1) {
2354-
zend_tmp_string_release(tmp);
23552353
setExpiryWarning(z_opts);
23562354
return FAILURE;
23572355
}
@@ -2360,22 +2358,19 @@ int redis_set_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
23602358
/* Protect the user from syntax errors but give them some info about what's wrong */
23612359
if (exp_type && keep_ttl) {
23622360
php_error_docref(NULL, E_WARNING, "KEEPTTL can't be combined with EX or PX option");
2363-
zend_tmp_string_release(tmp);
23642361
return FAILURE;
23652362
}
23662363

23672364
/* You can't use IFEQ with NX or XX */
23682365
if (set_type && ifeq) {
23692366
php_error_docref(NULL, E_WARNING, "IFEQ can't be combined with NX or XX option");
2370-
zend_tmp_string_release(tmp);
23712367
return FAILURE;
23722368
}
23732369

23742370
/* Backward compatibility: If we are passed no options except an EXPIRE ttl, we
23752371
* actually execute a SETEX command */
23762372
if (expire > 0 && !exp_type && !set_type && !keep_ttl) {
23772373
*cmd_len = REDIS_CMD_SPPRINTF(cmd, "SETEX", "klv", key, key_len, expire, z_value);
2378-
zend_tmp_string_release(tmp);
23792374
return SUCCESS;
23802375
}
23812376

@@ -2388,26 +2383,26 @@ int redis_set_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
23882383
redis_cmd_append_sstr_key(&cmdstr, key, key_len, redis_sock, slot);
23892384
redis_cmd_append_sstr_zval(&cmdstr, z_value, redis_sock);
23902385

2391-
if (exp_type) {
2392-
redis_cmd_append_sstr(&cmdstr, exp_type, strlen(exp_type));
2393-
redis_cmd_append_sstr_long(&cmdstr, (long)expire);
2394-
}
2395-
23962386
if (ifeq) {
2387+
zstr = zval_get_tmp_string(ifeq, &tmp);
23972388
REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "IFEQ");
2398-
redis_cmd_append_sstr_zstr(&cmdstr, ifeq);
2389+
redis_cmd_append_sstr_zstr(&cmdstr, zstr);
2390+
zend_tmp_string_release(tmp);
23992391
} else if (set_type) {
24002392
redis_cmd_append_sstr(&cmdstr, set_type, strlen(set_type));
24012393
}
24022394

2403-
if (keep_ttl)
2404-
redis_cmd_append_sstr(&cmdstr, "KEEPTTL", 7);
24052395
if (get) {
24062396
REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "GET");
24072397
*ctx = PHPREDIS_CTX_PTR;
24082398
}
24092399

2410-
zend_tmp_string_release(tmp);
2400+
if (exp_type) {
2401+
redis_cmd_append_sstr(&cmdstr, exp_type, strlen(exp_type));
2402+
redis_cmd_append_sstr_long(&cmdstr, (long)expire);
2403+
} else if (keep_ttl) {
2404+
REDIS_CMD_APPEND_SSTR_STATIC(&cmdstr, "KEEPTTL");
2405+
}
24112406

24122407
/* Push command and length to the caller */
24132408
*cmd = cmdstr.c;

0 commit comments

Comments
 (0)