mirror of
https://github.com/redis/redis.git
synced 2026-05-28 04:02:46 -04:00
Prevent negative expire parameter in HEXPIRE/HEXPIREAT/HPEXPIRE/HPEXPIREAT commands (#13310)
1. Don't allow HEXPIRE/HEXPIREAT/HPEXPIRE/HPEXPIREAT command expire
parameters is negative
2. Remove a dead code reported from Coverity.
when `unit` is not `UNIT_SECONDS`, the second `if (expire > (long long)
EB_EXPIRE_TIME_MAX)` will be dead code.
```c
# t_hash.c
2988 /* Check expire overflow */
cond_at_most: Condition expire > 281474976710655LL, taking false branch. Now the value of expire is at most 281474976710655.
2989 if (expire > (long long) EB_EXPIRE_TIME_MAX) {
2990 addReplyErrorExpireTime(c);
2991 return;
2992 }
2994 if (unit == UNIT_SECONDS) {
2995 if (expire > (long long) EB_EXPIRE_TIME_MAX / 1000) {
2996 addReplyErrorExpireTime(c);
2997 return;
2998 }
2999 expire *= 1000;
3000 } else {
at_most: At condition expire > 281474976710655LL, the value of expire must be at most 281474976710655.
dead_error_condition: The condition expire > 281474976710655LL cannot be true.
3001 if (expire > (long long) EB_EXPIRE_TIME_MAX) {
CID 494223: (#1 of 1): Logically dead code (DEADCODE)
dead_error_begin: Execution cannot reach this statement: addReplyErrorExpireTime(c);.
3002 addReplyErrorExpireTime(c);
3003 return;
3004 }
3005 }
```
---------
Co-authored-by: Ozan Tezcan <ozantezcan@gmail.com>
This commit is contained in:
parent
f36b5a8586
commit
9a2c6ba4e7
2 changed files with 20 additions and 13 deletions
18
src/t_hash.c
18
src/t_hash.c
|
|
@ -2869,7 +2869,7 @@ static void httlGenericCommand(client *c, const char *cmd, long long basetime, i
|
|||
|
||||
/* Verify `numFields` is consistent with number of arguments */
|
||||
if (numFields > (c->argc - numFieldsAt - 1)) {
|
||||
addReplyError(c, "Parameter `numFileds` is more than number of arguments");
|
||||
addReplyError(c, "Parameter `numFields` is more than number of arguments");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2983,10 +2983,8 @@ static void hexpireGenericCommand(client *c, const char *cmd, long long basetime
|
|||
/* Read the expiry time from command */
|
||||
if (getLongLongFromObjectOrReply(c, expireArg, &expire, NULL) != C_OK)
|
||||
return;
|
||||
|
||||
/* Check expire overflow */
|
||||
if (expire > (long long) EB_EXPIRE_TIME_MAX) {
|
||||
addReplyErrorExpireTime(c);
|
||||
if (expire < 0) {
|
||||
addReplyError(c,"invalid expire time, must be >= 0");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2996,13 +2994,9 @@ static void hexpireGenericCommand(client *c, const char *cmd, long long basetime
|
|||
return;
|
||||
}
|
||||
expire *= 1000;
|
||||
} else {
|
||||
if (expire > (long long) EB_EXPIRE_TIME_MAX) {
|
||||
addReplyErrorExpireTime(c);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure that the final absolute Unix timestamp does not exceed EB_EXPIRE_TIME_MAX. */
|
||||
if (expire > (long long) EB_EXPIRE_TIME_MAX - basetime) {
|
||||
addReplyErrorExpireTime(c);
|
||||
return;
|
||||
|
|
@ -3033,7 +3027,7 @@ static void hexpireGenericCommand(client *c, const char *cmd, long long basetime
|
|||
|
||||
/* Verify `numFields` is consistent with number of arguments */
|
||||
if (numFields > (c->argc - numFieldsAt - 1)) {
|
||||
addReplyError(c, "Parameter `numFileds` is more than number of arguments");
|
||||
addReplyError(c, "Parameter `numFields` is more than number of arguments");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -3130,7 +3124,7 @@ void hpersistCommand(client *c) {
|
|||
|
||||
/* Verify `numFields` is consistent with number of arguments */
|
||||
if (numFields > (c->argc - numFieldsAt - 1)) {
|
||||
addReplyError(c, "Parameter `numFileds` is more than number of arguments");
|
||||
addReplyError(c, "Parameter `numFields` is more than number of arguments");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -128,6 +128,19 @@ start_server {tags {"external:skip needs:debug"}} {
|
|||
r readraw 0
|
||||
}
|
||||
|
||||
test "HEXPIRE/HEXPIREAT/HPEXPIRE/HPEXPIREAT - Verify that the expire time does not overflow" {
|
||||
r del myhash
|
||||
r hset myhash f1 v1
|
||||
# The expire time can't be negative.
|
||||
assert_error {ERR invalid expire time, must be >= 0} {r HEXPIRE myhash -1 FIELDS 1 f1}
|
||||
assert_error {ERR invalid expire time, must be >= 0} {r HEXPIRE myhash -9223372036854775808 FIELDS 1 f1}
|
||||
# The expire time can't be greater than the EB_EXPIRE_TIME_MAX
|
||||
assert_error {ERR invalid expire time in 'hexpire' command} {r HEXPIRE myhash [expr (1<<48) / 1000] FIELDS 1 f1}
|
||||
assert_error {ERR invalid expire time in 'hexpireat' command} {r HEXPIREAT myhash [expr (1<<48) / 1000 + [clock seconds] + 100] FIELDS 1 f1}
|
||||
assert_error {ERR invalid expire time in 'hpexpire' command} {r HPEXPIRE myhash [expr (1<<48)] FIELDS 1 f1}
|
||||
assert_error {ERR invalid expire time in 'hpexpireat' command} {r HPEXPIREAT myhash [expr (1<<48) + [clock milliseconds] + 100] FIELDS 1 f1}
|
||||
}
|
||||
|
||||
test "HPEXPIRE(AT) - Test 'NX' flag ($type)" {
|
||||
r del myhash
|
||||
r hset myhash field1 value1 field2 value2 field3 value3
|
||||
|
|
@ -192,7 +205,7 @@ start_server {tags {"external:skip needs:debug"}} {
|
|||
r del myhash
|
||||
r hset myhash f1 v1
|
||||
assert_error {*Parameter `numFields` should be greater than 0} {r hpexpire myhash 1000 NX FIELDS 0 f1 f2 f3}
|
||||
assert_error {*Parameter `numFileds` is more than number of arguments} {r hpexpire myhash 1000 NX FIELDS 4 f1 f2 f3}
|
||||
assert_error {*Parameter `numFields` is more than number of arguments} {r hpexpire myhash 1000 NX FIELDS 4 f1 f2 f3}
|
||||
}
|
||||
|
||||
test "HPEXPIRE - parameter expire-time near limit of 2^48 ($type)" {
|
||||
|
|
|
|||
Loading…
Reference in a new issue