Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 732e466

Browse files
Improve warning when we encounter an invalid EXPIRY in SET
We actually had two different bits of logic to handle EXPIRY values in the `SET` command. One for the legacy `SET` -> `SETEX` mapping and another for the newer `SET foo bar EX <expiry>`. Additionally the error message could be confusing. Passing 3.1415 for an `EX` expiry would fail as we didn't allow floats. This commit consolidates expiry parsing to our existing helper function as well as improves the `php_error_docref` warning in the event that the user passes invalid data. The warning will now tell the user the type they tried to pass as an EXPIRY to make it easier to track down what's going wrong. Fixes #2448
1 parent 37c5f8d commit 732e466

File tree

1 file changed

+18
-20
lines changed

1 file changed

+18
-20
lines changed

redis_commands.c

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2291,21 +2291,27 @@ static int redis_try_get_expiry(zval *zv, zend_long *lval) {
22912291
int redis_set_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
22922292
char **cmd, int *cmd_len, short *slot, void **ctx)
22932293
{
2294-
smart_string cmdstr = {0};
2295-
zval *z_value, *z_opts=NULL;
22962294
char *key = NULL, *exp_type = NULL, *set_type = NULL;
2297-
long exp_set = 0, keep_ttl = 0;
2295+
zval *z_value, *z_opts=NULL;
2296+
smart_string cmdstr = {0};
22982297
zend_long expire = -1;
22992298
zend_bool get = 0;
2299+
long keep_ttl = 0;
23002300
size_t key_len;
23012301

2302+
#define setExpiryWarning(zv) \
2303+
php_error_docref(NULL, E_WARNING, "%s passed as EXPIRY is invalid " \
2304+
"(must be an int, float, or numeric string >= 1)", \
2305+
zend_zval_type_name((zv)))
2306+
23022307
// Make sure the function is being called correctly
23032308
if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz|z", &key, &key_len,
23042309
&z_value, &z_opts) == FAILURE)
23052310
{
23062311
return FAILURE;
23072312
}
23082313

2314+
23092315
// Check for an options array
23102316
if (z_opts && Z_TYPE_P(z_opts) == IS_ARRAY) {
23112317
HashTable *kt = Z_ARRVAL_P(z_opts);
@@ -2321,17 +2327,12 @@ int redis_set_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
23212327
zend_string_equals_literal_ci(zkey, "EXAT") ||
23222328
zend_string_equals_literal_ci(zkey, "PXAT"))
23232329
) {
2324-
exp_set = 1;
2330+
if (redis_try_get_expiry(v, &expire) == FAILURE || expire < 1) {
2331+
setExpiryWarning(v);
2332+
return FAILURE;
2333+
}
23252334

2326-
/* Set expire type */
23272335
exp_type = ZSTR_VAL(zkey);
2328-
2329-
/* Try to extract timeout */
2330-
if (Z_TYPE_P(v) == IS_LONG) {
2331-
expire = Z_LVAL_P(v);
2332-
} else if (Z_TYPE_P(v) == IS_STRING) {
2333-
expire = atol(Z_STRVAL_P(v));
2334-
}
23352336
} else if (Z_TYPE_P(v) == IS_STRING) {
23362337
if (zend_string_equals_literal_ci(Z_STR_P(v), "KEEPTTL")) {
23372338
keep_ttl = 1;
@@ -2345,19 +2346,14 @@ int redis_set_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
23452346
}
23462347
} ZEND_HASH_FOREACH_END();
23472348
} else if (z_opts && Z_TYPE_P(z_opts) != IS_NULL) {
2348-
if (redis_try_get_expiry(z_opts, &expire) == FAILURE) {
2349-
php_error_docref(NULL, E_WARNING, "Expire must be a long, double, or a numeric string");
2349+
if (redis_try_get_expiry(z_opts, &expire) == FAILURE || expire < 1) {
2350+
setExpiryWarning(z_opts);
23502351
return FAILURE;
23512352
}
2352-
2353-
exp_set = 1;
23542353
}
23552354

23562355
/* Protect the user from syntax errors but give them some info about what's wrong */
2357-
if (exp_set && expire < 1) {
2358-
php_error_docref(NULL, E_WARNING, "EXPIRE can't be < 1");
2359-
return FAILURE;
2360-
} else if (exp_type && keep_ttl) {
2356+
if (exp_type && keep_ttl) {
23612357
php_error_docref(NULL, E_WARNING, "KEEPTTL can't be combined with EX or PX option");
23622358
return FAILURE;
23632359
}
@@ -2396,6 +2392,8 @@ int redis_set_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
23962392
*cmd_len = cmdstr.len;
23972393

23982394
return SUCCESS;
2395+
2396+
#undef setExpiryWarning
23992397
}
24002398

24012399
/* MGET */

0 commit comments

Comments
 (0)