diff options
author | Nick Mathewson <nickm@torproject.org> | 2020-07-30 14:27:29 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2020-07-30 14:27:29 -0400 |
commit | 69d775293714f3fdb582f7877191ade48f8f8124 (patch) | |
tree | 52a1a91f923615bc2d06f4ffa65364e0ff655a09 | |
parent | 3b8bf743ae6eca261dd46cde94371a4cca0c0689 (diff) | |
parent | c2d5ec5e43c2690656ea5a5a384683108782d149 (diff) | |
download | tor-69d775293714f3fdb582f7877191ade48f8f8124.tar.gz tor-69d775293714f3fdb582f7877191ade48f8f8124.zip |
Merge branch 'bug40076_042' into bug40076_043
-rw-r--r-- | changes/bug40076 | 5 | ||||
-rw-r--r-- | src/lib/buf/buffers.c | 2 | ||||
-rw-r--r-- | src/test/test_buffers.c | 64 |
3 files changed, 71 insertions, 0 deletions
diff --git a/changes/bug40076 b/changes/bug40076 new file mode 100644 index 0000000000..9ef5969ae8 --- /dev/null +++ b/changes/bug40076 @@ -0,0 +1,5 @@ + o Minor bugfixes (correctness, buffers): + - Fix a correctness bug that could cause an assertion failure if we ever + tried using the buf_move_all() function with an empty input. + As far as we know, no released versions of Tor do this. + Fixes bug 40076; bugfix on 0.3.3.1-alpha. diff --git a/src/lib/buf/buffers.c b/src/lib/buf/buffers.c index 09a074edcc..d7b73e3807 100644 --- a/src/lib/buf/buffers.c +++ b/src/lib/buf/buffers.c @@ -692,6 +692,8 @@ buf_move_all(buf_t *buf_out, buf_t *buf_in) tor_assert(buf_out); if (!buf_in) return; + if (buf_datalen(buf_in) == 0) + return; if (BUG(buf_out->datalen >= INT_MAX || buf_in->datalen >= INT_MAX)) return; if (BUG(buf_out->datalen >= INT_MAX - buf_in->datalen)) diff --git a/src/test/test_buffers.c b/src/test/test_buffers.c index cc79426c1e..fbaa628fd7 100644 --- a/src/test/test_buffers.c +++ b/src/test/test_buffers.c @@ -303,6 +303,69 @@ test_buffer_pullup(void *arg) } static void +test_buffers_move_all(void *arg) +{ + (void)arg; + buf_t *input = buf_new(); + buf_t *output = buf_new(); + char *s = NULL; + + /* Move from empty buffer to nonempty buffer. (This is a regression test for + * #40076) */ + buf_add(output, "abc", 3); + buf_assert_ok(input); + buf_assert_ok(output); + buf_move_all(output, input); + buf_assert_ok(input); + buf_assert_ok(output); + tt_int_op(buf_datalen(output), OP_EQ, 3); + s = buf_extract(output, NULL); + tt_str_op(s, OP_EQ, "abc"); + buf_free(output); + buf_free(input); + tor_free(s); + + /* Move from empty to empty. */ + output = buf_new(); + input = buf_new(); + buf_move_all(output, input); + buf_assert_ok(input); + buf_assert_ok(output); + tt_int_op(buf_datalen(output), OP_EQ, 0); + buf_free(output); + buf_free(input); + + /* Move from nonempty to empty. */ + output = buf_new(); + input = buf_new(); + buf_add(input, "longstanding bugs", 17); + buf_move_all(output, input); + buf_assert_ok(input); + buf_assert_ok(output); + s = buf_extract(output, NULL); + tt_str_op(s, OP_EQ, "longstanding bugs"); + buf_free(output); + buf_free(input); + tor_free(s); + + /* Move from nonempty to nonempty. */ + output = buf_new(); + input = buf_new(); + buf_add(output, "the start of", 12); + buf_add(input, " a string", 9); + buf_move_all(output, input); + buf_assert_ok(input); + buf_assert_ok(output); + s = buf_extract(output, NULL); + tt_str_op(s, OP_EQ, "the start of a string"); + + done: + buf_free(output); + buf_free(input); + tor_free(s); +} + +static void test_buffer_copy(void *arg) { buf_t *buf=NULL, *buf2=NULL; @@ -799,6 +862,7 @@ struct testcase_t buffer_tests[] = { { "basic", test_buffers_basic, TT_FORK, NULL, NULL }, { "copy", test_buffer_copy, TT_FORK, NULL, NULL }, { "pullup", test_buffer_pullup, TT_FORK, NULL, NULL }, + { "move_all", test_buffers_move_all, 0, NULL, NULL }, { "startswith", test_buffer_peek_startswith, 0, NULL, NULL }, { "allocation_tracking", test_buffer_allocation_tracking, TT_FORK, NULL, NULL }, |