fix parse_token buffer overrun.

missing tests for parse_token.
this fixes http://bugs.eressea.de/view.php?id=2206
This commit is contained in:
Enno Rehling 2016-06-07 21:47:09 +02:00
parent 5535beed61
commit 4414d7ef57
2 changed files with 53 additions and 1 deletions

View File

@ -192,7 +192,7 @@ char *parse_token(const char **str, char *lbuf, size_t buflen)
copy = true; copy = true;
} }
if (copy) { if (copy) {
if (cursor - buflen < lbuf - 1) { if (cursor - buflen < lbuf - len) {
memcpy(cursor, ctoken, len); memcpy(cursor, ctoken, len);
cursor += len; cursor += len;
} }

View File

@ -3,6 +3,55 @@
#include <CuTest.h> #include <CuTest.h>
static void test_parse_token(CuTest *tc) {
char lbuf[8];
const char *tok;
const char *str, *orig;
orig = str = "SHORT TOKEN";
tok = parse_token(&str, lbuf, sizeof(lbuf));
CuAssertPtrEquals(tc, (void *)(orig+5), (void *)str);
CuAssertStrEquals(tc, "SHORT", tok);
tok = parse_token(&str, lbuf, sizeof(lbuf));
CuAssertPtrEquals(tc, (void *)(orig + 11), (void *)str);
CuAssertStrEquals(tc, "TOKEN", tok);
tok = parse_token(&str, lbuf, sizeof(lbuf));
CuAssertPtrEquals(tc, NULL, (void *)tok);
}
static void test_parse_token_limit(CuTest *tc) {
char lbuf[8];
const char *tok;
const char *str, *orig;
orig = str = "LONG_TOKEN";
tok = parse_token(&str, lbuf, sizeof(lbuf));
CuAssertPtrEquals(tc, (void *)(orig + 10), (void *)str);
CuAssertStrEquals(tc, tok, "LONG_TO");
tok = parse_token(&str, lbuf, sizeof(lbuf));
CuAssertPtrEquals(tc, NULL, (void *)tok);
}
static void test_parse_token_limit_utf8(CuTest *tc) {
char lbuf[8];
const char *tok;
const char *orig = "a\xc3\xa4\xc3\xb6\xc3\xbc\xc3\x9f"; /* auml ouml uuml szlig, 8 bytes long */
const char *str = orig+1;
tok = parse_token(&str, lbuf, sizeof(lbuf));
CuAssertPtrEquals(tc, (void *)(orig + strlen(orig)), (void *)str);
CuAssertStrEquals(tc, tok, "\xc3\xa4\xc3\xb6\xc3\xbc"); // just three letters fit, 6 bytes long
tok = parse_token(&str, lbuf, sizeof(lbuf));
CuAssertPtrEquals(tc, NULL, (void *)tok);
str = orig; // now with an extra byte in the front, maxing out lbuf exactly
tok = parse_token(&str, lbuf, sizeof(lbuf));
CuAssertPtrEquals(tc, (void *)(orig + strlen(orig)), (void *)str);
CuAssertStrEquals(tc, tok, "a\xc3\xa4\xc3\xb6\xc3\xbc");
tok = parse_token(&str, lbuf, sizeof(lbuf));
CuAssertPtrEquals(tc, NULL, (void *)tok);
}
static void test_gettoken(CuTest *tc) { static void test_gettoken(CuTest *tc) {
char token[128]; char token[128];
init_tokens_str("HELP ONE TWO THREE"); init_tokens_str("HELP ONE TWO THREE");
@ -64,6 +113,9 @@ CuSuite *get_parser_suite(void)
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_atoip); SUITE_ADD_TEST(suite, test_atoip);
SUITE_ADD_TEST(suite, test_skip_token); SUITE_ADD_TEST(suite, test_skip_token);
SUITE_ADD_TEST(suite, test_parse_token);
SUITE_ADD_TEST(suite, test_parse_token_limit);
SUITE_ADD_TEST(suite, test_parse_token_limit_utf8);
SUITE_ADD_TEST(suite, test_gettoken); SUITE_ADD_TEST(suite, test_gettoken);
SUITE_ADD_TEST(suite, test_gettoken_short); SUITE_ADD_TEST(suite, test_gettoken_short);
SUITE_ADD_TEST(suite, test_getintegers); SUITE_ADD_TEST(suite, test_getintegers);