Change in libosmocore[master]: add identifier sanitation for setting FSM instance ids

Neels Hofmeyr gerrit-no-reply at
Fri Apr 12 04:45:38 UTC 2019

Neels Hofmeyr has submitted this change and it was merged. ( )

Change subject: add identifier sanitation for setting FSM instance ids

add identifier sanitation for setting FSM instance ids

We often compose FSM instance IDs from context information, for example placing
an MSISDN string or IP:port information in the FSM instance id, using
osmo_fsm_inst_update_id_f(). This fails if any characters are contained that
don't pass osmo_identifier_valid(). Hence it is the task of the caller to make
sure only characters allowed in an FSM id are applied.

Provide API to trivially allow this by replacing illegal chars:
- osmo_identifier_sanitize_buf(), with access to the same set of illegal
  characters defined in utils.c,
- osmo_fsm_inst_update_id_f_sanitize() implicitly replaces non-identifier

This makes it easy to add strings like '' or '+4987654321' to
an FSM instance id, without adding string mangling to each place that sets an
id; e.g. replacing with '-' to yield '192-168-0-1:2342' or '-4987654321'.

Change-Id: Ia40a6f3b2243c95fe428a080b938e11d8ab771a7
M include/osmocom/core/fsm.h
M include/osmocom/core/utils.h
M src/fsm.c
M src/utils.c
4 files changed, 53 insertions(+), 2 deletions(-)

  Jenkins Builder: Verified
  Harald Welte: Looks good to me, approved

diff --git a/include/osmocom/core/fsm.h b/include/osmocom/core/fsm.h
index c9e1e0c..41d01a5 100644
--- a/include/osmocom/core/fsm.h
+++ b/include/osmocom/core/fsm.h
@@ -220,6 +220,7 @@
 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 08735fd..f27359c 100644
--- a/include/osmocom/core/utils.h
+++ b/include/osmocom/core/utils.h
@@ -140,6 +140,7 @@
 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 b6912c6..c32767b 100644
--- a/src/fsm.c
+++ b/src/fsm.c
@@ -364,6 +364,35 @@
 	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 6116d3a..896e917 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -553,6 +553,8 @@
 	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_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 @@
 		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 @@
 	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.

To view, visit
To unsubscribe, or for help writing mail filters, visit

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: Ia40a6f3b2243c95fe428a080b938e11d8ab771a7
Gerrit-Change-Number: 13574
Gerrit-PatchSet: 4
Gerrit-Owner: Neels Hofmeyr <nhofmeyr at>
Gerrit-Reviewer: Harald Welte <laforge at>
Gerrit-Reviewer: Jenkins Builder (1000002)
Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr at>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the gerrit-log mailing list