aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Færøy <ahf@torproject.org>2020-07-31 02:03:34 +0000
committerAlexander Færøy <ahf@torproject.org>2020-07-31 02:03:34 +0000
commit529b98967538b0a942ded2e4739591c9fe01d8e1 (patch)
treeae3927844e327c36c606ee6a03e809f71aad2639
parent5f4601f5aa388f25c63faf9822f7dfcfab09f34c (diff)
parent4e684c8695e4654d841644fe9c13e70eabd191b9 (diff)
downloadtor-529b98967538b0a942ded2e4739591c9fe01d8e1.tar.gz
tor-529b98967538b0a942ded2e4739591c9fe01d8e1.zip
Merge branch 'maint-0.4.2' into release-0.4.2
-rw-r--r--changes/bug400765
-rw-r--r--src/lib/buf/buffers.c2
-rw-r--r--src/test/test_buffers.c64
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 },