summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/core/fsm.h1
-rw-r--r--include/osmocom/core/utils.h1
-rw-r--r--src/fsm.c29
-rw-r--r--src/utils.c24
4 files changed, 53 insertions, 2 deletions
diff --git a/include/osmocom/core/fsm.h b/include/osmocom/core/fsm.h
index c9e1e0cf..41d01a58 100644
--- a/include/osmocom/core/fsm.h
+++ b/include/osmocom/core/fsm.h
@@ -220,6 +220,7 @@ void osmo_fsm_inst_free(struct osmo_fsm_inst *fi);
int osmo_fsm_inst_update_id(struct osmo_fsm_inst *fi, const char *id);
int osmo_fsm_inst_update_id_f(struct osmo_fsm_inst *fi, const char *fmt, ...);
+int osmo_fsm_inst_update_id_f_sanitize(struct osmo_fsm_inst *fi, char replace_with, const char *fmt, ...);
const char *osmo_fsm_event_name(struct osmo_fsm *fsm, uint32_t event);
const char *osmo_fsm_inst_name(struct osmo_fsm_inst *fi);
diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h
index 08735fdb..f27359cb 100644
--- a/include/osmocom/core/utils.h
+++ b/include/osmocom/core/utils.h
@@ -140,6 +140,7 @@ bool osmo_is_hexstr(const char *str, int min_digits, int max_digits,
bool osmo_identifier_valid(const char *str);
bool osmo_separated_identifiers_valid(const char *str, const char *sep_chars);
+void osmo_identifier_sanitize_buf(char *str, const char *sep_chars, char replace_with);
const char *osmo_escape_str(const char *str, int len);
char *osmo_escape_str_buf2(char *buf, size_t bufsize, const char *str, int in_len);
diff --git a/src/fsm.c b/src/fsm.c
index b6912c6b..c32767b2 100644
--- a/src/fsm.c
+++ b/src/fsm.c
@@ -364,6 +364,35 @@ int osmo_fsm_inst_update_id_f(struct osmo_fsm_inst *fi, const char *fmt, ...)
return 0;
}
+/*! Change id of the FSM instance using a string format, and ensuring a valid id.
+ * Replace any characters that are not permitted as FSM identifier with replace_with.
+ * \param[in] fi FSM instance.
+ * \param[in] replace_with Character to use instead of non-permitted FSM id characters.
+ * Make sure to choose a legal character, e.g. '-'.
+ * \param[in] fmt format string to compose new ID.
+ * \param[in] ... variable argument list for format string.
+ * \returns 0 if the ID was updated, otherwise -EINVAL.
+ */
+int osmo_fsm_inst_update_id_f_sanitize(struct osmo_fsm_inst *fi, char replace_with, const char *fmt, ...)
+{
+ char *id = NULL;
+ va_list ap;
+ int rc;
+
+ if (!fmt)
+ return osmo_fsm_inst_update_id(fi, NULL);
+
+ va_start(ap, fmt);
+ id = talloc_vasprintf(fi, fmt, ap);
+ va_end(ap);
+
+ osmo_identifier_sanitize_buf(id, NULL, replace_with);
+
+ rc = osmo_fsm_inst_update_id(fi, id);
+ talloc_free(id);
+ return rc;
+}
+
/*! allocate a new instance of a specified FSM
* \param[in] fsm Descriptor of the FSM
* \param[in] ctx talloc context from which to allocate memory
diff --git a/src/utils.c b/src/utils.c
index 6116d3ad..896e9177 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -553,6 +553,8 @@ bool osmo_is_hexstr(const char *str, int min_digits, int max_digits,
return true;
}
+static const char osmo_identifier_illegal_chars[] = "., {}[]()<>|~\\^`'\"?=;/+*&%$#!";
+
/*! Determine if a given identifier is valid, i.e. doesn't contain illegal chars
* \param[in] str String to validate
* \param[in] sep_chars Permitted separation characters between identifiers.
@@ -561,7 +563,6 @@ bool osmo_is_hexstr(const char *str, int min_digits, int max_digits,
bool osmo_separated_identifiers_valid(const char *str, const char *sep_chars)
{
/* characters that are illegal in names */
- static const char illegal_chars[] = "., {}[]()<>|~\\^`'\"?=;/+*&%$#!";
unsigned int i;
size_t len;
@@ -578,7 +579,7 @@ bool osmo_separated_identifiers_valid(const char *str, const char *sep_chars)
if (!isprint((int)str[i]))
return false;
/* check for some explicit reserved control characters */
- if (strchr(illegal_chars, str[i]))
+ if (strchr(osmo_identifier_illegal_chars, str[i]))
return false;
}
@@ -594,6 +595,25 @@ bool osmo_identifier_valid(const char *str)
return osmo_separated_identifiers_valid(str, NULL);
}
+/*! Replace characters in the given string buffer so that it is guaranteed to pass osmo_separated_identifiers_valid().
+ * To guarantee passing osmo_separated_identifiers_valid(), replace_with must not itself be an illegal character. If in
+ * doubt, use '-'.
+ * \param[inout] str Identifier to sanitize, must be nul terminated and in a writable buffer.
+ * \param[in] sep_chars Additional characters that are allowed besides osmo_identifier_illegal_chars.
+ * \param[in] replace_with Replace any illegal characters with this character.
+ */
+void osmo_identifier_sanitize_buf(char *str, const char *sep_chars, char replace_with)
+{
+ char *pos;
+ if (!str)
+ return;
+ for (pos = str; *pos; pos++) {
+ if (strchr(osmo_identifier_illegal_chars, *pos)
+ || (sep_chars && strchr(sep_chars, *pos)))
+ *pos = replace_with;
+ }
+}
+
/*! Like osmo_escape_str_buf2, but with unusual ordering of arguments, and may sometimes return string constants instead
* of writing to buf for error cases or empty input.
* Most *_buf() functions have the buffer and size as first arguments, here the arguments are last.