summaryrefslogtreecommitdiff
path: root/tests/modules/basics.c
diff options
context:
space:
mode:
authorchenyang8094 <chenyang8094@users.noreply.github.com>2021-09-09 16:03:05 +0800
committerGitHub <noreply@github.com>2021-09-09 11:03:05 +0300
commitbc0c22fabca058f4b23c9a634a37f6753dd963bd (patch)
tree23c204f53ba7336a32d19117a0cd46c7abe69203 /tests/modules/basics.c
parent7c80a65484b31f397426189620bc32e68e8fd842 (diff)
downloadredis-bc0c22fabca058f4b23c9a634a37f6753dd963bd.tar.gz
Fix callReplyParseCollection memleak when use AutoMemory (#9446)
When parsing an array type reply, ctx will be lost when recursively parsing its elements, which will cause a memory leak in automemory mode. This is a result of the changes in #9202 Add test for callReplyParseCollection fix
Diffstat (limited to 'tests/modules/basics.c')
-rw-r--r--tests/modules/basics.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/tests/modules/basics.c b/tests/modules/basics.c
index aa11fb967..a743b9edf 100644
--- a/tests/modules/basics.c
+++ b/tests/modules/basics.c
@@ -33,6 +33,7 @@
#define REDISMODULE_EXPERIMENTAL_API
#include "redismodule.h"
#include <string.h>
+#include <stdlib.h>
/* --------------------------------- Helpers -------------------------------- */
@@ -457,6 +458,38 @@ int TestUnlink(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
return RedisModule_ReplyWithSimpleString(ctx, "OK");
}
+int TestNestedCallReplyArrayElement(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
+ RedisModule_AutoMemory(ctx);
+ REDISMODULE_NOT_USED(argv);
+ REDISMODULE_NOT_USED(argc);
+
+ RedisModuleString *expect_key = RedisModule_CreateString(ctx, "mykey", strlen("mykey"));
+ RedisModule_SelectDb(ctx, 1);
+ RedisModule_Call(ctx, "LPUSH", "sc", expect_key, "myvalue");
+
+ RedisModuleCallReply *scan_reply = RedisModule_Call(ctx, "SCAN", "l", 0);
+ RedisModule_Assert(scan_reply != NULL && RedisModule_CallReplyType(scan_reply) == REDISMODULE_REPLY_ARRAY);
+ RedisModule_Assert(RedisModule_CallReplyLength(scan_reply) == 2);
+
+ long long scan_cursor;
+ RedisModuleCallReply *cursor_reply = RedisModule_CallReplyArrayElement(scan_reply, 0);
+ RedisModule_Assert(RedisModule_CallReplyType(cursor_reply) == REDISMODULE_REPLY_STRING);
+ RedisModule_Assert(RedisModule_StringToLongLong(RedisModule_CreateStringFromCallReply(cursor_reply), &scan_cursor) == REDISMODULE_OK);
+ RedisModule_Assert(scan_cursor == 0);
+
+ RedisModuleCallReply *keys_reply = RedisModule_CallReplyArrayElement(scan_reply, 1);
+ RedisModule_Assert(RedisModule_CallReplyType(keys_reply) == REDISMODULE_REPLY_ARRAY);
+ RedisModule_Assert( RedisModule_CallReplyLength(keys_reply) == 1);
+
+ RedisModuleCallReply *key_reply = RedisModule_CallReplyArrayElement(keys_reply, 0);
+ RedisModule_Assert(RedisModule_CallReplyType(key_reply) == REDISMODULE_REPLY_STRING);
+ RedisModuleString *key = RedisModule_CreateStringFromCallReply(key_reply);
+ RedisModule_Assert(RedisModule_StringCompare(key, expect_key) == 0);
+
+ RedisModule_ReplyWithSimpleString(ctx, "OK");
+ return REDISMODULE_OK;
+}
+
/* TEST.STRING.TRUNCATE -- Test truncating an existing string object. */
int TestStringTruncate(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
RedisModule_AutoMemory(ctx);
@@ -795,6 +828,9 @@ int TestBasics(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
T("test.unlink","");
if (!TestAssertStringReply(ctx,reply,"OK",2)) goto fail;
+ T("test.nestedcallreplyarray","");
+ if (!TestAssertStringReply(ctx,reply,"OK",2)) goto fail;
+
T("test.string.append.am","");
if (!TestAssertStringReply(ctx,reply,"foobar",6)) goto fail;
@@ -894,6 +930,10 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
TestUnlink,"write deny-oom",1,1,1) == REDISMODULE_ERR)
return REDISMODULE_ERR;
+ if (RedisModule_CreateCommand(ctx,"test.nestedcallreplyarray",
+ TestNestedCallReplyArrayElement,"write deny-oom",1,1,1) == REDISMODULE_ERR)
+ return REDISMODULE_ERR;
+
if (RedisModule_CreateCommand(ctx,"test.basics",
TestBasics,"readonly",1,1,1) == REDISMODULE_ERR)
return REDISMODULE_ERR;