]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add eofish support to terminal checks
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 17 Dec 2020 15:49:55 +0000 (09:49 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 17 Dec 2020 15:50:07 +0000 (09:50 -0600)
src/lib/util/sbuff.c
src/lib/util/sbuff.h
src/lib/util/sbuff_tests.c

index dfac44dc6a45f94b679e567cc0109e11c47769a1..8b557765fa9483fe5f546ea0618397419c1a2336 100644 (file)
@@ -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);
 }
index e18a2443c97848d04564256c6e48bee109eb5763..9748fa443b2e413e358c2350e43fad8331f31ccb 100644 (file)
@@ -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)
index 5b2ccf8f53d56957f211ea96394d2c2120994aed..256dc72e051ecbbc063248653cb1b1d14b216c59 100644 (file)
@@ -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