Sitelet https://github.com/phpredis/phpredis/commit/504810a5
Skip to content

Commit 504810a

Browse files
committed
Issue #2068, Refactor ACL command
1 parent f2cef8b commit 504810a

5 files changed

Lines changed: 120 additions & 62 deletions

File tree

‎library.c‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2168,6 +2168,27 @@ redis_xinfo_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_t
21682168
return FAILURE;
21692169
}
21702170

2171+
PHP_REDIS_API int
2172+
redis_acl_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx)
2173+
{
2174+
if (ctx == NULL) {
2175+
return redis_read_variant_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, NULL);
2176+
} else if (ctx == PHPREDIS_CTX_PTR) {
2177+
return redis_boolean_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, NULL);
2178+
} else if (ctx == PHPREDIS_CTX_PTR + 1) {
2179+
return redis_string_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, NULL);
2180+
} else if (ctx == PHPREDIS_CTX_PTR + 2) {
2181+
return redis_long_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, NULL);
2182+
} else if (ctx == PHPREDIS_CTX_PTR + 3) {
2183+
return redis_acl_getuser_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, NULL);
2184+
} else if (ctx == PHPREDIS_CTX_PTR + 4) {
2185+
return redis_acl_log_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, NULL);
2186+
} else {
2187+
ZEND_ASSERT(!"memory corruption?");
2188+
return FAILURE;
2189+
}
2190+
}
2191+
21712192
PHP_REDIS_API int
21722193
redis_read_acl_log_reply(RedisSock *redis_sock, zval *zret, long count) {
21732194
zval zsub;

‎library.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ PHP_REDIS_API int
161161
redis_read_mpop_response(RedisSock *redis_sock, zval *zdst, int elements, void *ctx);
162162

163163
/* Specialized ACL reply handlers */
164+
PHP_REDIS_API int redis_acl_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
164165
PHP_REDIS_API int redis_read_acl_getuser_reply(RedisSock *redis_sock, zval *zret, long len);
165166
PHP_REDIS_API int redis_acl_getuser_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx);
166167
PHP_REDIS_API int redis_read_acl_log_reply(RedisSock *redis_sock, zval *zret, long count);

‎redis.c‎

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,49 +1129,7 @@ PHP_METHOD(Redis, type)
11291129

11301130
/* {{{ proto mixed Redis::acl(string $op, ...) }}} */
11311131
PHP_METHOD(Redis, acl) {
1132-
RedisSock *redis_sock;
1133-
FailableResultCallback cb;
1134-
zval *zargs;
1135-
zend_string *op;
1136-
char *cmd;
1137-
int cmdlen, argc = ZEND_NUM_ARGS();
1138-
1139-
if (argc < 1 || (redis_sock = redis_sock_get(getThis(), 0)) == NULL) {
1140-
if (argc < 1) {
1141-
php_error_docref(NULL, E_WARNING, "ACL command requires at least one argument");
1142-
}
1143-
RETURN_FALSE;
1144-
}
1145-
1146-
zargs = emalloc(argc * sizeof(*zargs));
1147-
if (zend_get_parameters_array(ht, argc, zargs) == FAILURE) {
1148-
efree(zargs);
1149-
RETURN_FALSE;
1150-
}
1151-
1152-
/* Read the subcommand and set response callback */
1153-
op = zval_get_string(&zargs[0]);
1154-
if (zend_string_equals_literal_ci(op, "GETUSER")) {
1155-
cb = redis_acl_getuser_reply;
1156-
} else if (zend_string_equals_literal_ci(op, "LOG")) {
1157-
cb = redis_acl_log_reply;
1158-
} else {
1159-
cb = redis_read_variant_reply;
1160-
}
1161-
1162-
/* Make our command and free args */
1163-
cmd = redis_variadic_str_cmd("ACL", zargs, argc, &cmdlen);
1164-
1165-
zend_string_release(op);
1166-
efree(zargs);
1167-
1168-
REDIS_PROCESS_REQUEST(redis_sock, cmd, cmdlen);
1169-
if (IS_ATOMIC(redis_sock)) {
1170-
if (cb(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL) < 0) {
1171-
RETURN_FALSE;
1172-
}
1173-
}
1174-
REDIS_PROCESS_RESPONSE(cb);
1132+
REDIS_PROCESS_CMD(acl, redis_acl_response);
11751133
}
11761134

11771135
/* {{{ proto long Redis::append(string key, string val) */

‎redis_commands.c‎

Lines changed: 94 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2100,6 +2100,100 @@ redis_pop_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
21002100
return SUCCESS;
21012101
}
21022102

2103+
int
2104+
redis_acl_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
2105+
char **cmd, int *cmd_len, short *slot, void **ctx)
2106+
{
2107+
smart_string cmdstr = {0};
2108+
zend_string *zstr;
2109+
zval *z_args;
2110+
int argc, i;
2111+
2112+
if ((argc = ZEND_NUM_ARGS()) < 1) {
2113+
php_error_docref(NULL, E_WARNING, "ACL command requires at least one argument");
2114+
return FAILURE;
2115+
}
2116+
2117+
z_args = ecalloc(argc, sizeof(*z_args));
2118+
if (zend_get_parameters_array(ht, argc, z_args) == FAILURE) {
2119+
goto failure;
2120+
}
2121+
2122+
zstr = zval_get_string(&z_args[0]);
2123+
if (zend_string_equals_literal_ci(zstr, "CAT") ||
2124+
zend_string_equals_literal_ci(zstr, "LIST") ||
2125+
zend_string_equals_literal_ci(zstr, "USERS")
2126+
) {
2127+
*ctx = NULL;
2128+
} else if (zend_string_equals_literal_ci(zstr, "LOAD") ||
2129+
zend_string_equals_literal_ci(zstr, "SAVE")
2130+
) {
2131+
*ctx = PHPREDIS_CTX_PTR;
2132+
} else if (zend_string_equals_literal_ci(zstr, "GENPASS") ||
2133+
zend_string_equals_literal_ci(zstr, "WHOAMI")
2134+
) {
2135+
*ctx = PHPREDIS_CTX_PTR + 1;
2136+
} else if (zend_string_equals_literal_ci(zstr, "SETUSER")) {
2137+
if (argc < 2) {
2138+
php_error_docref(NULL, E_WARNING, "ACL SETUSER requires at least one argument");
2139+
zend_string_release(zstr);
2140+
goto failure;
2141+
}
2142+
*ctx = PHPREDIS_CTX_PTR;
2143+
} else if (zend_string_equals_literal_ci(zstr, "DELUSER")) {
2144+
if (argc < 2) {
2145+
php_error_docref(NULL, E_WARNING, "ACL DELUSER requires at least one argument");
2146+
zend_string_release(zstr);
2147+
goto failure;
2148+
}
2149+
*ctx = PHPREDIS_CTX_PTR + 2;
2150+
} else if (zend_string_equals_literal_ci(zstr, "GETUSER")) {
2151+
if (argc < 2) {
2152+
php_error_docref(NULL, E_WARNING, "ACL GETUSER requires at least one argument");
2153+
zend_string_release(zstr);
2154+
goto failure;
2155+
}
2156+
*ctx = PHPREDIS_CTX_PTR + 3;
2157+
} else if (zend_string_equals_literal_ci(zstr, "DRYRUN")) {
2158+
if (argc < 3) {
2159+
php_error_docref(NULL, E_WARNING, "ACL DRYRUN requires at least two arguments");
2160+
zend_string_release(zstr);
2161+
goto failure;
2162+
}
2163+
*ctx = PHPREDIS_CTX_PTR;
2164+
} else if (zend_string_equals_literal_ci(zstr, "LOG")) {
2165+
if (argc > 1 && Z_TYPE(z_args[1]) == IS_STRING && ZVAL_STRICMP_STATIC(&z_args[1], "RESET")) {
2166+
*ctx = PHPREDIS_CTX_PTR;
2167+
} else {
2168+
*ctx = PHPREDIS_CTX_PTR + 4;
2169+
}
2170+
} else {
2171+
php_error_docref(NULL, E_WARNING, "Unknown ACL operation '%s'", ZSTR_VAL(zstr));
2172+
zend_string_release(zstr);
2173+
goto failure;
2174+
}
2175+
2176+
REDIS_CMD_INIT_SSTR_STATIC(&cmdstr, argc, "ACL");
2177+
redis_cmd_append_sstr_zstr(&cmdstr, zstr);
2178+
zend_string_release(zstr);
2179+
2180+
for (i = 1; i < argc; ++i) {
2181+
zstr = zval_get_string(&z_args[i]);
2182+
redis_cmd_append_sstr_zstr(&cmdstr, zstr);
2183+
zend_string_release(zstr);
2184+
}
2185+
efree(z_args);
2186+
2187+
*cmd = cmdstr.c;
2188+
*cmd_len = cmdstr.len;
2189+
2190+
return SUCCESS;
2191+
2192+
failure:
2193+
efree(z_args);
2194+
return FAILURE;
2195+
}
2196+
21032197
/* Attempt to pull a long expiry from a zval. We're more restrictave than zval_get_long
21042198
* because that function will return integers from things like open file descriptors
21052199
* which should simply fail as a TTL */
@@ -3168,23 +3262,6 @@ int redis_pfcount_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
31683262
return SUCCESS;
31693263
}
31703264

3171-
char *redis_variadic_str_cmd(char *kw, zval *argv, int argc, int *cmd_len) {
3172-
smart_string cmdstr = {0};
3173-
zend_string *zstr;
3174-
int i;
3175-
3176-
redis_cmd_init_sstr(&cmdstr, argc, kw, strlen(kw));
3177-
3178-
for (i = 0; i < argc; i++) {
3179-
zstr = zval_get_string(&argv[i]);
3180-
redis_cmd_append_sstr_zstr(&cmdstr, zstr);
3181-
zend_string_release(zstr);
3182-
}
3183-
3184-
*cmd_len = cmdstr.len;
3185-
return cmdstr.c;
3186-
}
3187-
31883265
int redis_auth_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
31893266
char **cmd, int *cmd_len, short *slot, void **ctx)
31903267
{

‎redis_commands.h‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ int redis_build_raw_cmd(zval *z_args, int argc, char **cmd, int *cmd_len);
3131
/* Construct a script command */
3232
smart_string *redis_build_script_cmd(smart_string *cmd, int argc, zval *z_args);
3333

34-
char *redis_variadic_str_cmd(char *kw, zval *argv, int argc, int *cmd_len);
35-
3634
/* Redis command generics. Many commands share common prototypes meaning that
3735
* we can write one function to handle all of them. For example, there are
3836
* many COMMAND key value commands, or COMMAND key commands. */
@@ -187,6 +185,9 @@ int redis_geosearchstore_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock
187185
* specific processing we do (e.g. verifying subarguments) that make them
188186
* unique */
189187

188+
int redis_acl_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
189+
char **cmd, int *cmd_len, short *slot, void **ctx);
190+
190191
int redis_set_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
191192
char **cmd, int *cmd_len, short *slot, void **ctx);
192193

0 commit comments

Comments
 (0)