From: Arran Cudbard-Bell Date: Thu, 17 Dec 2020 15:49:55 +0000 (-0600) Subject: Add eofish support to terminal checks X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4d8c7b588358ac03084fe98762e979fe2ec6da81;p=thirdparty%2Ffreeradius-server.git Add eofish support to terminal checks --- diff --git a/src/lib/util/sbuff.c b/src/lib/util/sbuff.c index dfac44dc6a4..8b557765fa9 100644 --- a/src/lib/util/sbuff.c +++ b/src/lib/util/sbuff.c @@ -446,6 +446,7 @@ static inline bool fr_sbuff_terminal_search(fr_sbuff_t *in, char const *p, ssize_t mid; size_t remaining; + fr_sbuff_extend_status_t status = FR_SBUFF_EXTENDABLE; if (!term) return false; /* If there's no terminals, we don't need to search */ @@ -453,7 +454,15 @@ static inline bool fr_sbuff_terminal_search(fr_sbuff_t *in, char const *p, term_idx = idx[(uint8_t)*p]; /* Fast path */ if (!term_idx) return false; - remaining = fr_sbuff_remaining(in); + /* + * Special case for EOFlike states + */ + remaining = fr_sbuff_extend_lowat(&status, in, 1); + if (remaining == 0) { + if (status & FR_SBUFF_EXTEND_ERROR) return false; + return (idx['\0'] != 0); + } + mid = term_idx - 1; /* Inform the mid point from the index */ while (start <= end) { @@ -1955,7 +1964,5 @@ bool fr_sbuff_is_terminal(fr_sbuff_t *in, fr_sbuff_term_t const *tt) */ fr_sbuff_terminal_idx_init(&needle_len, idx, tt); - if (!fr_sbuff_extend_lowat(NULL, in, needle_len)) return false; - return fr_sbuff_terminal_search(in, in->p, idx, tt); } diff --git a/src/lib/util/sbuff.h b/src/lib/util/sbuff.h index e18a2443c97..9748fa443b2 100644 --- a/src/lib/util/sbuff.h +++ b/src/lib/util/sbuff.h @@ -217,6 +217,7 @@ typedef enum { #define FR_SBUFF_FLAG_EXTENDABLE 0x01 #define FR_SBUFF_FLAG_EXTENDED 0x02 +#define FR_SBUFF_FLAG_EXTEND_ERROR 0x04 /** Whether the buffer is currently extendable and whether it was extended * @@ -225,7 +226,8 @@ typedef enum { FR_SBUFF_NOT_EXTENDABLE = 0x00, FR_SBUFF_EXTENDABLE = FR_SBUFF_FLAG_EXTENDABLE, FR_SBUFF_EXTENDABLE_EXTENDED = FR_SBUFF_FLAG_EXTENDABLE | FR_SBUFF_FLAG_EXTENDED, - FR_SBUFF_EXTENDED = FR_SBUFF_FLAG_EXTENDED + FR_SBUFF_EXTENDED = FR_SBUFF_FLAG_EXTENDED, + FR_SBUFF_EXTEND_ERROR = FR_SBUFF_FLAG_EXTEND_ERROR } fr_sbuff_extend_status_t; #define fr_sbuff_is_extendable(_status) ((_status) & FR_SBUFF_FLAG_EXTENDABLE) diff --git a/src/lib/util/sbuff_tests.c b/src/lib/util/sbuff_tests.c index 5b2ccf8f53d..256dc72e051 100644 --- a/src/lib/util/sbuff_tests.c +++ b/src/lib/util/sbuff_tests.c @@ -700,6 +700,36 @@ static void test_unescape_multi_char_terminals(void) TEST_CHECK_STRCMP(out, " baz"); } +static void test_unescape_eof_terminal(void) +{ + char const in[] = "foo, bar"; + fr_sbuff_t sbuff; + ssize_t slen; + fr_sbuff_term_t tt_eof = FR_SBUFF_TERMS( + L(""), + L(","), + ); + fr_sbuff_term_t tt = FR_SBUFF_TERMS( + L(",") + ); + char out[100]; + + fr_sbuff_init(&sbuff, in, sizeof(in)); + + slen = fr_sbuff_out_bstrncpy_until(&FR_SBUFF_OUT(out, sizeof(out)), &sbuff, SIZE_MAX, &tt_eof, NULL); + TEST_CHECK(slen == 3); + TEST_CHECK_STRCMP(out, "foo"); + + fr_sbuff_advance(&sbuff, 1); /* Advance past comma */ + + slen = fr_sbuff_out_bstrncpy_until(&FR_SBUFF_OUT(out, sizeof(out)), &sbuff, SIZE_MAX, &tt_eof, NULL); + TEST_CHECK(slen == 4); + TEST_CHECK_STRCMP(out, " bar"); + + TEST_CHECK(fr_sbuff_is_terminal(&sbuff, &tt_eof) == true); + TEST_CHECK(fr_sbuff_is_terminal(&sbuff, &tt) == false); +} + static void test_no_advance(void) { char const *in = "i am a test string"; @@ -1381,6 +1411,7 @@ TEST_LIST = { { "fr_sbuff_out_bstrncpy_until", test_bstrncpy_until }, { "multi-char terminals", test_unescape_multi_char_terminals }, { "fr_sbuff_out_unescape_until", test_unescape_until }, + { "fr_sbuff_terminal_eof", test_unescape_eof_terminal }, /* * Extending buffer