]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add and use fr_pair_list_print()
authorAlan T. DeKok <aland@freeradius.org>
Mon, 7 Aug 2023 13:10:21 +0000 (09:10 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 7 Aug 2023 13:31:09 +0000 (09:31 -0400)
so that we can hoist the "nested or not" debug printing into
this function.  Which also lets this function peek ahead, and
print attributes as if they were nested when they really aren't

src/bin/unit_test_attribute.c
src/lib/util/pair.h
src/lib/util/pair_print.c

index c542d29585520f6d5dd35256735431727a35042b..58626b7df6fd144ea22d405233be1f2152ea22a8 100644 (file)
@@ -1180,8 +1180,6 @@ static size_t command_normalise_attribute(command_result_t *result, command_file
 {
        fr_pair_list_t  head;
        ssize_t         slen;
-       char            *p, *end;
-       fr_pair_t       *vp;
        fr_dict_t const *dict = cc->tmpl_rules.attr.dict_def ? cc->tmpl_rules.attr.dict_def : cc->config->dict;
 
        fr_pair_list_init(&head);
@@ -1190,40 +1188,18 @@ static size_t command_normalise_attribute(command_result_t *result, command_file
                RETURN_OK_WITH_ERROR();
        }
 
-       /*
-        *      Set p to be the output buffer
-        */
-       p = data;
-       end = p + COMMAND_OUTPUT_MAX;
-
        /*
         *      Output may be an error, and we ignore
         *      it if so.
         */
 
-       if (!fr_pair_list_empty(&head)) {
-               for (vp = fr_pair_list_head(&head);
-                    vp;
-                    vp = fr_pair_list_next(&head, vp)) {
-                       if ((slen = fr_pair_print(&FR_SBUFF_OUT(p, end), NULL, vp)) < 0) {
-                       oob:
-                               fr_strerror_const("Out of output buffer space for printed pairs");
-                               RETURN_COMMAND_ERROR();
-                       }
-                       p += slen;
-
-                       if (fr_pair_list_next(&head, vp)) {
-                               slen = strlcpy(p, ", ", end - p);
-                               if (is_truncated((size_t)slen, end - p)) goto oob;
-                               p += slen;
-                       }
-               }
-               fr_pair_list_free(&head);
-       } else { /* zero-length to_decibute */
-               *p = '\0';
+       slen = fr_pair_list_print(&FR_SBUFF_OUT(data, COMMAND_OUTPUT_MAX), &head);
+       if (slen <= 0) {
+               fr_assert(0);
+               RETURN_OK_WITH_ERROR();
        }
 
-       RETURN_OK(p - data);
+       RETURN_OK(slen);
 }
 
 static const fr_token_t token2op[UINT8_MAX + 1] = {
@@ -1542,11 +1518,10 @@ static size_t command_decode_pair(command_result_t *result, command_file_ctx_t *
 {
        fr_test_point_pair_decode_t     *tp = NULL;
        void            *decode_ctx = NULL;
-       char            *p, *end;
+       char            *p;
        uint8_t         *to_dec;
        uint8_t         *to_dec_end;
        fr_pair_list_t  head;
-       fr_pair_t       *vp;
        ssize_t         slen;
 
        fr_pair_list_init(&head);
@@ -1618,42 +1593,18 @@ static size_t command_decode_pair(command_result_t *result, command_file_ctx_t *
        fr_strerror_clear();
        ASAN_UNPOISON_MEMORY_REGION(to_dec_end, COMMAND_OUTPUT_MAX - slen);
 
-       /*
-        *      Set p to be the output buffer
-        */
-       p = data;
-       end = p + COMMAND_OUTPUT_MAX;
-
        /*
         *      Output may be an error, and we ignore
         *      it if so.
         */
-
-       if (!fr_pair_list_empty(&head)) {
-               for (vp = fr_pair_list_head(&head);
-                    vp;
-                    vp = fr_pair_list_next(&head, vp)) {
-                       if ((slen = fr_pair_print(&FR_SBUFF_OUT(p, end), NULL, vp)) < 0) {
-                       oob:
-                               fr_strerror_const("Out of output buffer space for printed pairs");
-                               CLEAR_TEST_POINT(cc);
-                               RETURN_COMMAND_ERROR();
-                       }
-                       p += slen;
-
-                       if (fr_pair_list_next(&head, vp)) {
-                               slen = strlcpy(p, ", ", end - p);
-                               if (is_truncated((size_t)slen, end - p)) goto oob;
-                               p += slen;
-                       }
-               }
-               fr_pair_list_free(&head);
-       } else { /* zero-length to_decibute */
-               *p = '\0';
+       slen = fr_pair_list_print(&FR_SBUFF_OUT(data, COMMAND_OUTPUT_MAX), &head);
+       if (slen <= 0) {
+               fr_assert(0);
+               RETURN_OK_WITH_ERROR();
        }
 
        CLEAR_TEST_POINT(cc);
-       RETURN_OK(p - data);
+       RETURN_OK(slen);
 }
 
 static size_t command_decode_proto(command_result_t *result, command_file_ctx_t *cc,
@@ -1665,9 +1616,7 @@ static size_t command_decode_proto(command_result_t *result, command_file_ctx_t
        uint8_t         *to_dec;
        uint8_t         *to_dec_end;
        fr_pair_list_t  head;
-       fr_pair_t       *vp;
        ssize_t         slen;
-       fr_sbuff_t      sbuff = FR_SBUFF_OUT(data, COMMAND_OUTPUT_MAX);
 
        p = in;
        fr_pair_list_init(&head);
@@ -1730,28 +1679,17 @@ static size_t command_decode_proto(command_result_t *result, command_file_ctx_t
         *      it if so.
         */
 
-       if (!fr_pair_list_empty(&head)) {
-               for (vp = fr_pair_list_head(&head);
-                    vp;
-                    vp = fr_pair_list_next(&head, vp)) {
-                       if ((slen = fr_pair_print(&sbuff, NULL, vp)) < 0) {
-                       oob:
-                               fr_strerror_printf("Out of output buffer space (%zd) for decoded data", slen);
-                               CLEAR_TEST_POINT(cc);
-                               RETURN_COMMAND_ERROR();
-                       }
-
-                       if (fr_pair_list_next(&head, vp)) {
-                               if (fr_sbuff_in_char(&sbuff, ',', ' ') <= 0) goto oob;
-                       }
-               }
-               fr_pair_list_free(&head);
-       } else { /* zero-length to_decibute */
-               *data = '\0';
+       /*
+        *      Print the pairs.
+        */
+       slen = fr_pair_list_print(&FR_SBUFF_OUT(data, COMMAND_OUTPUT_MAX), &head);
+       if (slen <= 0) {
+               fr_assert(0);
+               RETURN_OK_WITH_ERROR();
        }
 
        CLEAR_TEST_POINT(cc);
-       RETURN_OK(fr_sbuff_used(&sbuff));
+       RETURN_OK(slen);
 }
 
 /** Parse a dictionary attribute, writing "ok" to the data buffer is everything was ok
@@ -2061,9 +1999,8 @@ static size_t command_read_file(command_result_t *result, command_file_ctx_t *cc
 {
        ssize_t slen;
        fr_pair_list_t head;
-       fr_pair_t *vp;
        bool done = false;
-       char *filename, *p, *end;
+       char *filename;
        FILE *fp;
 
        filename = talloc_asprintf(cc->tmp_ctx, "%s/%s", cc->path, in);
@@ -2086,31 +2023,20 @@ static size_t command_read_file(command_result_t *result, command_file_ctx_t *cc
        /*
         *      Print the pairs.
         */
-       p = data;
-       end = data + COMMAND_OUTPUT_MAX;
-       for (vp = fr_pair_list_head(&head);
-            vp != NULL;
-            vp = fr_pair_list_next(&head, vp)) {
-               if ((slen = fr_pair_print(&FR_SBUFF_OUT(p, end), NULL, vp)) <= 0) RETURN_OK_WITH_ERROR();
-               p += (size_t)slen;
-
-               if (p >= end) break;
-
-               *(p++) = ',';
-               *(p++) = ' ';
+       slen = fr_pair_list_print(&FR_SBUFF_OUT(data, COMMAND_OUTPUT_MAX), &head);
+       if (slen <= 0) {
+               fr_assert(0);
+               RETURN_OK_WITH_ERROR();
        }
 
-       /*
-        *      Delete the trailing ", ".
-        */
-       if (p > data) p -= 2;
-       *p = 0;
-
-       if (!done) strlcpy(p, "!DONE", (end - p));
+       if (!done) {
+               strlcpy(data + slen, "!DONE", COMMAND_OUTPUT_MAX - slen);
+               slen += 5;
+       }
 
        fr_pair_list_free(&head);
 
-       RETURN_OK(p - data);
+       RETURN_OK(slen);
 }
 
 
@@ -2583,7 +2509,6 @@ static size_t command_pair(command_result_t *result, command_file_ctx_t *cc,
 {
        ssize_t slen;
        fr_pair_ctx_t ctx;
-       fr_pair_t *vp;
        fr_pair_list_t head;
        char *p, *end;
 
@@ -2610,29 +2535,15 @@ static size_t command_pair(command_result_t *result, command_file_ctx_t *cc,
 
        PAIR_LIST_VERIFY(&head);
 
-       p = data;
-       end = data + COMMAND_OUTPUT_MAX;
-       for (vp = fr_pair_list_head(&head);
-            vp != NULL;
-            vp = fr_pair_list_next(&head, vp)) {
-               if ((slen = fr_pair_print(&FR_SBUFF_OUT(p, end), NULL, vp)) <= 0) RETURN_OK_WITH_ERROR();
-               p += (size_t)slen;
-
-               if (p >= end) break;
-
-               *(p++) = ',';
-               *(p++) = ' ';
+       slen = fr_pair_list_print(&FR_SBUFF_OUT(data, COMMAND_OUTPUT_MAX), &head);
+       if (slen <= 0) {
+               fr_assert(0);
+               RETURN_OK_WITH_ERROR();
        }
 
-       /*
-        *      Delete the trailing ", ".
-        */
-       if (p > data) p -= 2;
-       *p = 0;
-
        fr_pair_list_free(&head);
 
-       RETURN_OK(p - data);
+       RETURN_OK(slen);
 }
 
 
index 82cb64c5c233e5743ba2f40e472028ce76536a74..18e886ebc5544bf3acc999757c9861e0359f84e0 100644 (file)
@@ -775,6 +775,8 @@ ssize_t             fr_pair_print(fr_sbuff_t *out, fr_pair_t const *parent,
 ssize_t                fr_pair_print_secure(fr_sbuff_t *out, fr_pair_t const *parent,
                                     fr_pair_t const *vp) CC_HINT(nonnull(1,3));
 
+ssize_t                fr_pair_list_print(fr_sbuff_t *out, fr_pair_list_t const *list);
+
 static inline fr_slen_t CC_HINT(nonnull(2,4))
                fr_pair_aprint(TALLOC_CTX *ctx, char **out, fr_pair_t const *parent, fr_pair_t const *vp)
                SBUFF_OUT_TALLOC_FUNC_NO_LEN_DEF(fr_pair_print, parent, vp)
index 22bcd8d49880ed9d8f28371c995bedae913889e3..61e13f58866d2436ff5b39941922054b824f8aed 100644 (file)
@@ -199,6 +199,43 @@ ssize_t fr_pair_print_secure(fr_sbuff_t *out, fr_pair_t const *parent, fr_pair_t
        FR_SBUFF_SET_RETURN(out, &our_out);
 }
 
+/** Print a pair list
+ *
+ * @param[in] out      Where to write the string.
+ * @param[in] list     pair list
+ * @return
+ *     - Length of data written to out.
+ *     - value >= outlen on truncation.
+ */
+ssize_t fr_pair_list_print(fr_sbuff_t *out, fr_pair_list_t const *list)
+{
+       fr_pair_t *vp;
+       fr_sbuff_t our_out = FR_SBUFF(out);
+
+       vp = fr_pair_list_head(list);
+       if (!vp) {
+               FR_SBUFF_IN_CHAR_RETURN(out, '\0');
+               return fr_sbuff_used(out);
+       }
+
+       while (true) {
+               ssize_t slen;
+
+               slen = fr_pair_print(&our_out, NULL, vp);
+               if (slen <= 0) {
+                       fr_assert(0);
+                       return slen;
+               }
+
+               vp = fr_pair_list_next(list, vp);
+               if (!vp) break;
+
+               FR_SBUFF_IN_STRCPY_LITERAL_RETURN(&our_out, ", ");
+       }
+
+       FR_SBUFF_SET_RETURN(out, &our_out);
+}
+
 /** Print one attribute and value to FP
  *
  * Complete string with '\\t' and '\\n' is written to buffer before printing to