diff --git a/coroio/sockutils.cpp b/coroio/sockutils.cpp index af5ede6..9551219 100644 --- a/coroio/sockutils.cpp +++ b/coroio/sockutils.cpp @@ -28,7 +28,7 @@ TLine TLineSplitter::Pop() { Size -= end.size() + p2 + 1; return TLine { end, begin.substr(0, p2 + 1) }; } else { - RPos += p1 + 1; + RPos = (RPos + p1 + 1) % Cap; Size -= p1 + 1; return TLine { end.substr(0, p1 + 1), {} }; } @@ -70,7 +70,7 @@ TLine TZeroCopyLineSplitter::Pop() { Size -= end.size() + p2 + 1; return TLine { end, begin.substr(0, p2 + 1) }; } else { - RPos += p1 + 1; + RPos = (RPos + p1 + 1) % Cap; Size -= p1 + 1; return TLine { end.substr(0, p1 + 1), {} }; } diff --git a/tests/tests.cpp b/tests/tests.cpp index 6f0c81e..bf05a95 100644 --- a/tests/tests.cpp +++ b/tests/tests.cpp @@ -753,6 +753,34 @@ void test_zero_copy_line_splitter(void**) { } } +void test_line_splitter_wrap(void**) { + TLineSplitter splitter(4); // Cap=8 + splitter.Push("aaa\n", 4); + splitter.Pop(); + splitter.Push("bbb\n", 4); + splitter.Pop(); // RPos hits Cap without fix + + splitter.Push("cc\n", 3); + auto l = splitter.Pop(); + assert_true(static_cast(l)); + std::string result = std::string(l.Part1) + std::string(l.Part2); + assert_string_equal("cc\n", result.data()); +} + +void test_zero_copy_line_splitter_wrap(void**) { + TZeroCopyLineSplitter splitter(4); // Cap=8 + splitter.Push("aaa\n", 4); + splitter.Pop(); + splitter.Push("bbb\n", 4); + splitter.Pop(); // RPos hits Cap without fix + + splitter.Push("cc\n", 3); + auto l = splitter.Pop(); + assert_true(static_cast(l)); + std::string result = std::string(l.Part1) + std::string(l.Part2); + assert_string_equal("cc\n", result.data()); +} + void test_self_id(void**) { void* id; TFuture h = [](void** id) -> TFuture { @@ -1308,6 +1336,8 @@ int main(int argc, char* argv[]) { ADD_TEST(cmocka_unit_test, test_timespec); ADD_TEST(cmocka_unit_test, test_line_splitter); ADD_TEST(cmocka_unit_test, test_zero_copy_line_splitter); + ADD_TEST(cmocka_unit_test, test_line_splitter_wrap); + ADD_TEST(cmocka_unit_test, test_zero_copy_line_splitter_wrap); ADD_TEST(cmocka_unit_test, test_self_id); ADD_TEST(cmocka_unit_test, test_resolv_nameservers); ADD_TEST(my_unit_poller, test_listen);