From: Max Khon Date: Wed, 22 Jun 2022 21:02:06 +0000 (+0300) Subject: fr_sbuff_extend_file(): update "end" of parent sbuffs (#4576) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4ac945626a0b3dddd65b609c8b5049ffffe77e7c;p=thirdparty%2Ffreeradius-server.git fr_sbuff_extend_file(): update "end" of parent sbuffs (#4576) This fixes parsing when streaming from file and parsed object (string) spans fhe I/O buffer boundary. --- diff --git a/src/lib/util/sbuff.c b/src/lib/util/sbuff.c index 419b5dd4726..5ca3a8bc936 100644 --- a/src/lib/util/sbuff.c +++ b/src/lib/util/sbuff.c @@ -256,6 +256,7 @@ size_t fr_sbuff_shift(fr_sbuff_t *sbuff, size_t shift) */ size_t fr_sbuff_extend_file(fr_sbuff_t *sbuff, size_t extension) { + fr_sbuff_t *sbuff_i; size_t read, available, total_read; fr_sbuff_uctx_file_t *fctx; @@ -290,7 +291,9 @@ size_t fr_sbuff_extend_file(fr_sbuff_t *sbuff, size_t extension) } read = fread(sbuff->end, 1, available, fctx->file); - sbuff->end += read; /* Advance end, which increases fr_sbuff_remaining() */ + for (sbuff_i = sbuff; sbuff_i; sbuff_i = sbuff_i->parent) { + sbuff_i->end += read; /* Advance end, which increases fr_sbuff_remaining() */ + } /** Check for errors */ diff --git a/src/lib/util/sbuff_tests.c b/src/lib/util/sbuff_tests.c index 754bda62a1d..b188c3129b0 100644 --- a/src/lib/util/sbuff_tests.c +++ b/src/lib/util/sbuff_tests.c @@ -1007,23 +1007,40 @@ static void test_talloc_extend_with_marker(void) static void test_file_extend(void) { fr_sbuff_t sbuff; + fr_sbuff_t our_sbuff; fr_sbuff_uctx_file_t fctx; FILE *fp; char buff[16]; + char out[16 + 1]; char fbuff[] = " xyzzy"; char *post_ws; + ssize_t slen; TEST_CASE("Initialization"); fp = fmemopen(fbuff, sizeof(fbuff) - 1, "r"); TEST_CHECK(fp != NULL); TEST_CHECK(fr_sbuff_init_file(&sbuff, &fctx, buff, sizeof(buff), fp, 128) == &sbuff); + our_sbuff = FR_SBUFF_BIND_CURRENT(&sbuff); TEST_CASE("Advance past whitespace, which will require shift/extend"); - TEST_CHECK_LEN(sizeof(fbuff) - 6, fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX, NULL)); + TEST_CHECK_LEN(fr_sbuff_adv_past_whitespace(&our_sbuff, SIZE_MAX, NULL), sizeof(fbuff) - 6); TEST_CASE("Verify that we passed all and only whitespace"); - (void) fr_sbuff_out_abstrncpy(NULL, &post_ws, &sbuff, 24); + (void) fr_sbuff_out_abstrncpy(NULL, &post_ws, &our_sbuff, 24); TEST_CHECK_STRCMP(post_ws, "xyzzy"); talloc_free(post_ws); + TEST_CASE("Verify parent buffer end"); + TEST_CHECK(sbuff.end == our_sbuff.end); + + TEST_CASE("Verify that we do not read shifted buffer past eof"); + slen = fr_sbuff_out_bstrncpy(&FR_SBUFF_OUT(out, sizeof(out)), &our_sbuff, SIZE_MAX); + TEST_CHECK_SLEN(slen, 0); + slen = fr_sbuff_out_bstrncpy_exact(&FR_SBUFF_OUT(out, sizeof(out)), &our_sbuff, SIZE_MAX); + TEST_CHECK_SLEN(slen, 0); + slen = fr_sbuff_out_bstrncpy_until(&FR_SBUFF_OUT(out, sizeof(out)), &our_sbuff, SIZE_MAX, NULL, NULL); + TEST_CHECK_SLEN(slen, 0); + slen = fr_sbuff_out_bstrncpy_allowed(&FR_SBUFF_OUT(out, sizeof(out)), &our_sbuff, SIZE_MAX, allow_lowercase_and_space); + TEST_CHECK_SLEN(slen, 0); + fclose(fp); }