diff --git a/CHANGES b/CHANGES index afcce93836..8e6d993723 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +5072. [bug] Add unit tests for isc_buffer_copyregion() and fix its + behavior for auto-reallocated buffers. [GL #644] + 5071. [bug] Comparision of NXT records was broken. [GL #631] 5070. [bug] Record types which support a empty rdata field were diff --git a/lib/isc/buffer.c b/lib/isc/buffer.c index 5eb2620c70..987795be12 100644 --- a/lib/isc/buffer.c +++ b/lib/isc/buffer.c @@ -514,27 +514,24 @@ isc_buffer_dup(isc_mem_t *mctx, isc_buffer_t **dstp, const isc_buffer_t *src) { isc_result_t isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r) { - unsigned char *base; - unsigned int available; isc_result_t result; REQUIRE(ISC_BUFFER_VALID(b)); REQUIRE(r != NULL); - /* - * XXXDCL - */ - base = isc_buffer_used(b); - available = isc_buffer_availablelength(b); if (ISC_UNLIKELY(b->autore)) { result = isc_buffer_reserve(&b, r->length); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { return (result); + } } - if (r->length > available) + + if (r->length > isc_buffer_availablelength(b)) { return (ISC_R_NOSPACE); + } + if (r->length > 0U) { - memmove(base, r->base, r->length); + memmove(isc_buffer_used(b), r->base, r->length); b->used += r->length; } diff --git a/lib/isc/tests/buffer_test.c b/lib/isc/tests/buffer_test.c index 34145d7bcc..89009e0a9d 100644 --- a/lib/isc/tests/buffer_test.c +++ b/lib/isc/tests/buffer_test.c @@ -10,17 +10,20 @@ */ #include + +#include +#include #include -#include -#include +#include #include #include "isctest.h" #include -#include +#include #include +#include ATF_TC(isc_buffer_reserve); ATF_TC_HEAD(isc_buffer_reserve, tc) { @@ -158,6 +161,51 @@ ATF_TC_BODY(isc_buffer_dynamic, tc) { isc_test_end(); } +ATF_TC(isc_buffer_copyregion); +ATF_TC_HEAD(isc_buffer_copyregion, tc) { + atf_tc_set_md_var(tc, "descr", "copy a region into a buffer"); +} + +ATF_TC_BODY(isc_buffer_copyregion, tc) { + unsigned char data[] = { 0x11, 0x22, 0x33, 0x44 }; + isc_buffer_t *b = NULL; + isc_result_t result; + + isc_region_t r = { + .base = data, + .length = sizeof(data), + }; + + result = isc_test_begin(NULL, true, 0); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + result = isc_buffer_allocate(mctx, &b, sizeof(data)); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + /* + * Fill originally allocated buffer space. + */ + result = isc_buffer_copyregion(b, &r); + ATF_CHECK_EQ(result, ISC_R_SUCCESS); + + /* + * Appending more data to the buffer should fail. + */ + result = isc_buffer_copyregion(b, &r); + ATF_CHECK_EQ(result, ISC_R_NOSPACE); + + /* + * Enable auto reallocation and retry. Appending should now succeed. + */ + isc_buffer_setautorealloc(b, true); + result = isc_buffer_copyregion(b, &r); + ATF_CHECK_EQ(result, ISC_R_SUCCESS); + + isc_buffer_free(&b); + + isc_test_end(); +} + ATF_TC(isc_buffer_printf); ATF_TC_HEAD(isc_buffer_printf, tc) { atf_tc_set_md_var(tc, "descr", "printf() into a buffer"); @@ -278,6 +326,7 @@ ATF_TC_BODY(isc_buffer_printf, tc) { ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, isc_buffer_reserve); ATF_TP_ADD_TC(tp, isc_buffer_dynamic); + ATF_TP_ADD_TC(tp, isc_buffer_copyregion); ATF_TP_ADD_TC(tp, isc_buffer_printf); return (atf_no_error()); }