diff options
author | Alexander Færøy <ahf@torproject.org> | 2020-07-31 02:03:34 +0000 |
---|---|---|
committer | Alexander Færøy <ahf@torproject.org> | 2020-07-31 02:03:34 +0000 |
commit | 4e684c8695e4654d841644fe9c13e70eabd191b9 (patch) | |
tree | 0f9f9cd201c2d970170e98a5e94d713737a2e234 | |
parent | cdb0e6c2522aac372c9a816300dacfd62856dd48 (diff) | |
parent | c4742b89b23d58958ee0d5ca324dac5948c94bf6 (diff) | |
download | tor-4e684c8695e4654d841644fe9c13e70eabd191b9.tar.gz tor-4e684c8695e4654d841644fe9c13e70eabd191b9.zip |
Merge branch 'maint-0.3.5' into maint-0.4.2
-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 4d026bd37d..ace5bdc4a4 100644 --- a/src/lib/buf/buffers.c +++ b/src/lib/buf/buffers.c @@ -689,6 +689,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 97311c85cc..3084c19d74 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 }, |