aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <vyanitskiy@sysmocom.de>2023-12-11 13:34:02 +0700
committerfixeria <vyanitskiy@sysmocom.de>2023-12-30 16:14:38 +0000
commit9df820bf9b7d54b58b2462b1ee67c2e13eb749eb (patch)
treed9f8218060073973db2ae84e9deb18cb5a52af25
parentb8f3bba72174e057bf7504db6f6e0999b35633d7 (diff)
utils: fix OSMO_STRBUF_REMAIN to handle sb.pos == NULL correctly
Currently, OSMO_STRBUF_REMAIN would return a huge number if the given strbuf has its .pos pointer set to NULL. This macro is safe against the .buf pointer being NULL, but not against .pos being NULL. Fix this by adding a static inline function (for the sake of code readability) and handle .pos being NULL properly by returning length of the buffer. Add a unit test. Change-Id: I294a74a99c40995cf7fb5520d61f697d967be5a4
-rw-r--r--include/osmocom/core/utils.h15
-rw-r--r--tests/utils/utils_test.c18
-rw-r--r--tests/utils/utils_test.ok7
3 files changed, 39 insertions, 1 deletions
diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h
index b6e67e23..973a9d0c 100644
--- a/include/osmocom/core/utils.h
+++ b/include/osmocom/core/utils.h
@@ -281,8 +281,21 @@ struct osmo_strbuf {
#define OSMO_STRBUF_PRINTF(STRBUF, fmt, args...) \
OSMO_STRBUF_APPEND(STRBUF, snprintf, fmt, ##args)
+/*! Get remaining space for characters and terminating nul in the given struct osmo_strbuf.
+ * \param[in] sb the string buffer to get the remaining space for.
+ * \returns remaining space in the given struct osmo_strbuf. */
+static inline size_t _osmo_strbuf_remain(const struct osmo_strbuf *sb)
+{
+ if (OSMO_UNLIKELY(sb == NULL || sb->buf == NULL))
+ return 0;
+ if (sb->pos == NULL)
+ return sb->len;
+ return sb->len - (sb->pos - sb->buf);
+}
+
/*! Return remaining space for characters and terminating nul in the given struct osmo_strbuf. */
-#define OSMO_STRBUF_REMAIN(STRBUF) ((STRBUF).buf ? (STRBUF).len - ((STRBUF).pos - (STRBUF).buf) : 0)
+#define OSMO_STRBUF_REMAIN(STRBUF) \
+ _osmo_strbuf_remain(&(STRBUF))
/*! Return number of actual characters contained in struct osmo_strbuf (without terminating nul). */
#define OSMO_STRBUF_CHAR_COUNT(STRBUF) ((STRBUF).buf && ((STRBUF).pos > (STRBUF).buf) ? \
diff --git a/tests/utils/utils_test.c b/tests/utils/utils_test.c
index bdeedb58..26c94dce 100644
--- a/tests/utils/utils_test.c
+++ b/tests/utils/utils_test.c
@@ -1351,6 +1351,23 @@ void strbuf_test_tail(void)
strbuf_test_tail_for_buflen(1);
}
+void strbuf_test_remain_char_count(void)
+{
+ char buf[20];
+ struct osmo_strbuf sb = { .buf = buf, .len = sizeof(buf) };
+
+ printf("\n%s\n", __func__);
+
+ printf("remaining space: %zu\n", OSMO_STRBUF_REMAIN(sb));
+ printf("current char count: %zu\n", OSMO_STRBUF_CHAR_COUNT(sb));
+
+ printf("populating the buffer\n");
+ OSMO_STRBUF_PRINTF(sb, "osmocom");
+
+ printf("remaining space: %zu\n", OSMO_STRBUF_REMAIN(sb));
+ printf("current char count: %zu\n", OSMO_STRBUF_CHAR_COUNT(sb));
+}
+
static void startswith_test_str(const char *str, const char *startswith_str, bool expect_rc)
{
bool rc = osmo_str_startswith(str, startswith_str);
@@ -2198,6 +2215,7 @@ int main(int argc, char **argv)
strbuf_test();
strbuf_test_nolen();
strbuf_test_tail();
+ strbuf_test_remain_char_count();
startswith_test();
name_c_impl_test();
osmo_print_n_test();
diff --git a/tests/utils/utils_test.ok b/tests/utils/utils_test.ok
index 6f5d46bc..c0c95604 100644
--- a/tests/utils/utils_test.ok
+++ b/tests/utils/utils_test.ok
@@ -524,6 +524,13 @@ strbuf_test_tail_for_buflen(1)
6: "" sb.chars_needed=6 sb.pos=&sb.buf[1]
7: "" sb.chars_needed=12 sb.pos=&sb.buf[1]
+strbuf_test_remain_char_count
+remaining space: 20
+current char count: 0
+populating the buffer
+remaining space: 13
+current char count: 7
+
startswith_test()
osmo_str_startswith(NULL, NULL) == true
osmo_str_startswith("", NULL) == true