@@ -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:
@@ -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;
@@ -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);
@@ -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);
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(+)