diff mbox series

[v2,4/6] Cleanup input string to be semantic-version compliant

Message ID 20200612100354.3591-5-sde@unmatched.eu
State Changes Requested
Headers show
Series [v2,1/6] Add semver library | expand

Commit Message

Stijn Devriendt June 12, 2020, 10:03 a.m. UTC
When the string is malformed, we'll treat it as 0.0.0 and emit a
warning. This matches the approach from the previous code, to
ignore incorrect version parts, ending up with a NUL-version.

Signed-off-by: Stijn Devriendt <sde@unmatched.eu>
---
 core/artifacts_versions.c | 46 +++++++++++++++++++++++++++++++++++++++
 core/swupdate.c           |  2 ++
 include/util.h            |  1 +
 parser/parser.c           |  3 +++
 4 files changed, 52 insertions(+)
diff mbox series

Patch

diff --git a/core/artifacts_versions.c b/core/artifacts_versions.c
index 6fe5d60..ccc283e 100644
--- a/core/artifacts_versions.c
+++ b/core/artifacts_versions.c
@@ -25,6 +25,7 @@ 
 #include "swupdate.h"
 #include "parselib.h"
 #include "swupdate_settings.h"
+#include "semver.h"
 
 /*
  * Read versions of components from a file, if provided
@@ -66,6 +67,9 @@  static int read_sw_version_file(struct swupdate_cfg *sw)
 			}
 			strlcpy(swcomp->name, name, sizeof(swcomp->name));
 			strlcpy(swcomp->version, version, sizeof(swcomp->version));
+
+			cleanup_version(swcomp->version);
+
 			LIST_INSERT_HEAD(&sw->installed_sw_list, swcomp, next);
 			TRACE("Installed %s: Version %s",
 					swcomp->name,
@@ -118,6 +122,8 @@  static int versions_settings(void *setting, void *data)
 		GET_FIELD_STRING(LIBCFG_PARSER, elem, "name", swcomp->name);
 		GET_FIELD_STRING(LIBCFG_PARSER, elem, "version", swcomp->version);
 
+		cleanup_version(swcomp->version);
+
 		LIST_INSERT_HEAD(&sw->installed_sw_list, swcomp, next);
 		TRACE("Installed %s: Version %s",
 			swcomp->name,
@@ -154,6 +160,46 @@  void get_sw_versions(char __attribute__ ((__unused__)) *cfgname,
 }
 #endif
 
+static const char ACCEPTED_CHARS[] = "0123456789.";
+
+static bool is_oldstyle_version(const char* version_string)
+{
+	while (*version_string)
+	{
+		if (strchr(ACCEPTED_CHARS, *version_string) == NULL)
+			return false;
+	}
+	return true;
+}
+
+void cleanup_version(char* str)
+{
+	semver_t version = {};
+	int res = semver_clean(str);
+
+	/* This is only expected for overly long version strings.
+	 * Is SWUPDATE_GENERAL_STRING_SIZE > semver.c:MAX_SIZE + 1???
+	 */
+	assert(res == 0);
+	if (res == -1) {
+		WARN("Version string too long. Using 0.0.0 instead!");
+		str[0] = '\0';
+		return;
+	}
+
+	if (is_oldstyle_version(str))
+		return;
+
+	if (semver_parse(str, &version) == 0) {
+		semver_render(&version, str);
+	} else {
+		WARN("Unparseable version string. Using 0.0.0 instead!");
+		str[0] = '\0';
+	}
+
+	semver_free(&version);
+}
+
 /*
  * convert a version string into a number
  * version string is in the format:
diff --git a/core/swupdate.c b/core/swupdate.c
index 74dfbbe..8e85127 100644
--- a/core/swupdate.c
+++ b/core/swupdate.c
@@ -792,11 +792,13 @@  int main(int argc, char **argv)
 			swcfg.globals.no_downgrading = 1;
 			strlcpy(swcfg.globals.minimum_version, optarg,
 				sizeof(swcfg.globals.minimum_version));
+			cleanup_version(swcfg.globals.minimum_version);
 			break;
 		case 'R':
 			swcfg.globals.no_reinstalling = 1;
 			strlcpy(swcfg.globals.current_version, optarg,
 				sizeof(swcfg.globals.current_version));
+			cleanup_version(swcfg.globals.current_version);
 			break;
 		case 'M':
 			swcfg.globals.no_transaction_marker = 1;
diff --git a/include/util.h b/include/util.h
index 55fe70f..6a027c6 100644
--- a/include/util.h
+++ b/include/util.h
@@ -216,6 +216,7 @@  size_t snescape(char *dst, size_t n, const char *src);
 void freeargs (char **argv);
 int get_hw_revision(struct hw_type *hw);
 void get_sw_versions(char *cfgfname, struct swupdate_cfg *sw);
+void cleanup_version(char* str);
 __u64 version_to_number(const char *version_string);
 int hwid_match(const char* rev, const char* hwrev);
 int check_hw_compatibility(struct swupdate_cfg *cfg);
diff --git a/parser/parser.c b/parser/parser.c
index 31efe46..981d40d 100644
--- a/parser/parser.c
+++ b/parser/parser.c
@@ -273,6 +273,9 @@  static int parse_common_attributes(parsertype p, void *elem, struct img_type *im
 
 	GET_FIELD_STRING(p, elem, "name", image->id.name);
 	GET_FIELD_STRING(p, elem, "version", image->id.version);
+
+	cleanup_version(image->id.version);
+
 	GET_FIELD_STRING(p, elem, "filename", image->fname);
 	GET_FIELD_STRING(p, elem, "path", image->path);
 	GET_FIELD_STRING(p, elem, "volume", image->volname);