From 98ed3393cdfdf35ad0bb79f454474f2b27bf3d56 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 28 Mar 2019 13:26:53 +0100 Subject: osmo_escape_str_buf: Always copy, don't return input string pointer osmo_escape_str_buf() used to have the somewhat odd semantics that if no escaping was needed, it would return the original pointer without making any copy to the output buffer. While this seems like an elegant optimization, it is a very strange behavior and it works differently than all of our other *_buf() functions. Let's unify the API and turn osmo_escape_str_buf() into a strlcpy() if no escaping is needed. Change-Id: I3a02bdb27008a73101c2db41ac04248960ed4064 --- include/osmocom/core/utils.h | 2 +- src/utils.c | 27 ++++++++------------------- tests/utils/utils_test.c | 10 +--------- tests/utils/utils_test.ok | 2 -- 4 files changed, 10 insertions(+), 31 deletions(-) diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h index 16159d3d..e3728cd0 100644 --- a/include/osmocom/core/utils.h +++ b/include/osmocom/core/utils.h @@ -137,7 +137,7 @@ bool osmo_identifier_valid(const char *str); bool osmo_separated_identifiers_valid(const char *str, const char *sep_chars); const char *osmo_escape_str(const char *str, int len); -const char *osmo_escape_str_buf(const char *str, int in_len, char *buf, size_t bufsize); +char *osmo_escape_str_buf(const char *str, int in_len, char *buf, size_t bufsize); const char *osmo_quote_str(const char *str, int in_len); const char *osmo_quote_str_buf(const char *str, int in_len, char *buf, size_t bufsize); diff --git a/src/utils.c b/src/utils.c index 2d5bcb0e..019e7338 100644 --- a/src/utils.c +++ b/src/utils.c @@ -538,14 +538,14 @@ bool osmo_identifier_valid(const char *str) return osmo_separated_identifiers_valid(str, NULL); } -/*! Return the string with all non-printable characters escaped. +/*! Return the string with all non-printable characters escapeda, in user-supplied buffer. * \param[in] str A string that may contain any characters. * \param[in] len Pass -1 to print until nul char, or >= 0 to force a length. * \param[inout] buf string buffer to write escaped characters to. * \param[in] bufsize size of \a buf. - * \returns buf containing an escaped representation, possibly truncated, or str itself. + * \returns buf containing an escaped representation, possibly truncated. */ -const char *osmo_escape_str_buf(const char *str, int in_len, char *buf, size_t bufsize) +char *osmo_escape_str_buf(const char *str, int in_len, char *buf, size_t bufsize) { int in_pos = 0; int next_unprintable = 0; @@ -567,9 +567,10 @@ const char *osmo_escape_str_buf(const char *str, int in_len, char *buf, size_t b && str[next_unprintable] != '\\'; next_unprintable++); - if (next_unprintable == in_len - && in_pos == 0) - return str; + if (next_unprintable == in_len && in_pos == 0) { + osmo_strlcpy(buf, str, bufsize); + return buf; + } while (in_pos < next_unprintable && out_pos < out_len) out[out_pos++] = str[in_pos++]; @@ -633,25 +634,13 @@ const char *osmo_escape_str(const char *str, int in_len) */ const char *osmo_quote_str_buf(const char *str, int in_len, char *buf, size_t bufsize) { - const char *res; int l; if (!str) return "NULL"; if (bufsize < 3) return ""; buf[0] = '"'; - res = osmo_escape_str_buf(str, in_len, buf + 1, bufsize - 2); - /* if osmo_escape_str_buf() returned the str itself, we need to copy it to buf to be able to - * quote it. */ - if (res == str) { - /* max_len = bufsize - two quotes - nul term */ - int max_len = bufsize - 2 - 1; - if (in_len >= 0) - max_len = OSMO_MIN(in_len, max_len); - /* It is not allowed to pass unterminated strings into osmo_strlcpy() :/ */ - strncpy(buf + 1, str, max_len); - buf[1 + max_len] = '\0'; - } + osmo_escape_str_buf(str, in_len, buf + 1, bufsize - 2); l = strlen(buf); buf[l] = '"'; buf[l+1] = '\0'; /* both osmo_escape_str_buf() and max_len above ensure room for '\0' */ diff --git a/tests/utils/utils_test.c b/tests/utils/utils_test.c index d592fe04..711d6e12 100644 --- a/tests/utils/utils_test.c +++ b/tests/utils/utils_test.c @@ -545,7 +545,7 @@ static void str_escape_test(void) printf("- passthru:\n"); res = osmo_escape_str(printable, -1); - if (res != printable) + if (strcmp(res, printable)) printf("NOT passed through! \"%s\"\n", res); else printf("passed through unchanged \"%s\"\n", res); @@ -560,14 +560,6 @@ static void str_escape_test(void) memset(out_buf, 0x7f, sizeof(out_buf)); printf("\"%s\"\n", osmo_escape_str_buf((const char *)in_buf, sizeof(in_buf), out_buf, 10)); OSMO_ASSERT(out_buf[10] == 0x7f); - - printf("- passthrough without truncation when no escaping needed:\n"); - memset(in_buf, 'x', sizeof(in_buf)); - in_buf[19] = 'E'; - in_buf[20] = '\0'; - memset(out_buf, 0x7f, sizeof(out_buf)); - printf("\"%s\"\n", osmo_escape_str_buf((const char *)in_buf, -1, out_buf, 10)); - OSMO_ASSERT(out_buf[0] == 0x7f); } static void str_quote_test(void) diff --git a/tests/utils/utils_test.ok b/tests/utils/utils_test.ok index 1215ddd1..8fce9f13 100644 --- a/tests/utils/utils_test.ok +++ b/tests/utils/utils_test.ok @@ -232,8 +232,6 @@ passed through unchanged "printable" "" - truncation when too long: "\axxxxxxE" -- passthrough without truncation when no escaping needed: -"xxxxxxxxxxxxxxxxxxxE" Testing string quoting - all chars from 0 to 255 in batches of 16: -- cgit v1.2.3