Commit 82555dfa authored by Pieter Noordhuis's avatar Pieter Noordhuis
Browse files

Abort if the parser is in an error state

parent 32d86ef9
...@@ -131,6 +131,7 @@ static const char *chrtos(char byte) { ...@@ -131,6 +131,7 @@ static const char *chrtos(char byte) {
void redis_parser_init(redis_parser_t *parser, const redis_parser_callbacks_t *callbacks) { void redis_parser_init(redis_parser_t *parser, const redis_parser_callbacks_t *callbacks) {
parser->stackidx = -1; parser->stackidx = -1;
parser->callbacks = callbacks; parser->callbacks = callbacks;
parser->errno = 0;
} }
/* Execute the parser against len bytes in buf. When a full message was read, /* Execute the parser against len bytes in buf. When a full message was read,
...@@ -152,6 +153,12 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons ...@@ -152,6 +153,12 @@ size_t redis_parser_execute(redis_parser_t *parser, redis_protocol_t **dst, cons
struct redis_parser_int64_s i64; struct redis_parser_int64_s i64;
redis_protocol_t *cur; redis_protocol_t *cur;
/* Abort immediately if the parser is in an error state. It should be
* re-initialized before attempting to execute it with new data. */
if (parser->errno) {
return 0;
}
/* Reset destination */ /* Reset destination */
if (dst) *dst = NULL; if (dst) *dst = NULL;
......
...@@ -491,6 +491,25 @@ void test_error(redis_parser_t *p) { ...@@ -491,6 +491,25 @@ void test_error(redis_parser_t *p) {
test_char_by_char(res, buf, len); test_char_by_char(res, buf, len);
} }
void test_abort_after_error(redis_parser_t *p) {
redis_protocol_t *res;
redis_parser_errno_t errno;
assert_equal_size_t(redis_parser_execute(p, &res, "+ok\r", 4), 4);
assert(res == NULL);
assert_equal_size_t(redis_parser_execute(p, &res, "\r", 1), 0);
assert(res == NULL);
/* Test if the error matches what we expect */
errno = redis_parser_errno(p);
assert(errno == REDIS_PARSER_ERR_EXPECTED_LF);
assert(strcmp("expected \\n", redis_parser_strerror(errno)) == 0);
/* Test that the parser doesn't continue after an error */
assert_equal_size_t(redis_parser_execute(p, &res, "\n", 1), 0);
assert(res == NULL);
}
int main(int argc, char **argv) { int main(int argc, char **argv) {
redis_parser_t *parser = malloc(sizeof(redis_parser_t)); redis_parser_t *parser = malloc(sizeof(redis_parser_t));
redis_parser_init(parser, &callbacks); redis_parser_init(parser, &callbacks);
...@@ -505,6 +524,7 @@ int main(int argc, char **argv) { ...@@ -505,6 +524,7 @@ int main(int argc, char **argv) {
test_integer(parser); test_integer(parser);
test_status(parser); test_status(parser);
test_error(parser); test_error(parser);
test_abort_after_error(parser);
free(parser); free(parser);
return 0; return 0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment