Skip to content

Commit

Permalink
Fix code for XREAD and XREADGROUP and add test case (#187)
Browse files Browse the repository at this point in the history
The code for finding keys in XREAD and XREADGROUP commands was untested and incorrect. Here it is fixed and a tests are added.
  • Loading branch information
zuiderkwast authored Sep 1, 2023
1 parent 7c18baf commit 075ee49
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 16 deletions.
33 changes: 17 additions & 16 deletions command.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,28 +274,29 @@ void redis_parse_cmd(struct cmd *r) {
goto error;
}

/* Skip forward to the 'startfrom' arg index. */
/* Skip forward to the 'startfrom' arg index, then search for the keyword. */
arg = arg1;
arglen = arg1_len;
while (argidx < startfrom) {
while (argidx < (int)rnarg - 1) {
if ((p = redis_parse_bulk(p, end, &arg, &arglen)) == NULL)
goto error; /* Keyword not provided, thus no keys. */
argidx++;
if (argidx++ < startfrom)
continue; /* Keyword can't appear in a position before 'startfrom' */
if (!strncasecmp(keyword, arg, arglen)) {
/* Keyword found. Now the first key is the next arg. */
if ((p = redis_parse_bulk(p, end, &arg, &arglen)) == NULL)
goto error;
struct keypos *kpos = hiarray_push(r->keys);
if (kpos == NULL)
goto oom;
kpos->start = arg;
kpos->end = arg + arglen;
goto done;
}
}

/* Check that we found the keyword. */
if (strncasecmp(keyword, arg, arglen))
goto error;

/* Now find key is the next arg. */
if ((p = redis_parse_bulk(p, end, &arg, &arglen)) == NULL)
goto error;
struct keypos *kpos = hiarray_push(r->keys);
if (kpos == NULL)
goto oom;
kpos->start = arg;
kpos->end = arg + arglen;
goto done;
/* Keyword not provided. */
goto error;
}

/* Find first key arg. */
Expand Down
26 changes: 26 additions & 0 deletions tests/ut_parse_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,30 @@ void test_redis_parse_cmd_xgroup_destroy_ok(void) {
command_destroy(c);
}

void test_redis_parse_cmd_xreadgroup_ok(void) {
struct cmd *c = command_get();
/* Use group name and consumer name "streams" just to try to confuse the
* parser. The parser shouldn't mistake those for the STREAMS keyword. */
int len = redisFormatCommand(
&c->cmd, "XREADGROUP GROUP streams streams COUNT 1 streams mystream >");
ASSERT_MSG(len >= 0, "Format command error");
c->clen = len;
redis_parse_cmd(c);
ASSERT_KEYS(c, "mystream");
command_destroy(c);
}

void test_redis_parse_cmd_xread_ok(void) {
struct cmd *c = command_get();
int len = redisFormatCommand(&c->cmd,
"XREAD BLOCK 42 STREAMS mystream another $ $");
ASSERT_MSG(len >= 0, "Format command error");
c->clen = len;
redis_parse_cmd(c);
ASSERT_KEYS(c, "mystream");
command_destroy(c);
}

int main(void) {
test_redis_parse_error_nonresp();
test_redis_parse_cmd_get();
Expand All @@ -140,5 +164,7 @@ int main(void) {
test_redis_parse_cmd_xgroup_no_subcommand();
test_redis_parse_cmd_xgroup_destroy_no_key();
test_redis_parse_cmd_xgroup_destroy_ok();
test_redis_parse_cmd_xreadgroup_ok();
test_redis_parse_cmd_xread_ok();
return 0;
}

0 comments on commit 075ee49

Please sign in to comment.