From f69d625ac414dee195d14d6bb8e7fcfdf346181e Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Mon, 26 Apr 2021 19:16:19 +0100
Subject: [PATCH] auc: compare versions using dpkg/opkg's verrevcmp

Using strcmp() to compare a version string doesn't work well.
Use verrevcmp() function from opkg instead.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
(cherry picked from commit 794cf3ac59deb28b30f63aeb26f58726595cd885,
as it was previously skipped also switch PKG_REVISION back to manual
to keep it in sync with master branch)
---
 utils/auc/Makefile           |  2 +-
 utils/auc/src/CMakeLists.txt |  2 +-
 utils/auc/src/auc.c          | 55 +++++++++++++++++++++++++++++++++++-
 3 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/utils/auc/Makefile b/utils/auc/Makefile
index 58e026a8d8..17b401bf4b 100644
--- a/utils/auc/Makefile
+++ b/utils/auc/Makefile
@@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=auc
 PKG_VERSION:=0.1.7
-PKG_RELEASE:=$(AUTORELEASE)
+PKG_RELEASE:=1
 PKG_LICENSE:=GPL-3.0
 
 include $(INCLUDE_DIR)/package.mk
diff --git a/utils/auc/src/CMakeLists.txt b/utils/auc/src/CMakeLists.txt
index de6cee8334..14cc199ce2 100644
--- a/utils/auc/src/CMakeLists.txt
+++ b/utils/auc/src/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.6)
+cmake_minimum_required(VERSION 2.6...3.12)
 
 PROJECT(auc C)
 ADD_DEFINITIONS(-Os -ggdb -Wall --std=gnu99 -Wmissing-declarations)
diff --git a/utils/auc/src/auc.c b/utils/auc/src/auc.c
index f01efefaae..ebda3eed8c 100644
--- a/utils/auc/src/auc.c
+++ b/utils/auc/src/auc.c
@@ -17,6 +17,7 @@
 #define AUC_VERSION "unknown"
 #endif
 
+#include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <dlfcn.h>
@@ -361,6 +362,58 @@ static int load_config() {
 	return 0;
 }
 
+/*
+ * libdpkg - Debian packaging suite library routines
+ * vercmp.c - comparison of version numbers
+ *
+ * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
+ */
+
+/* assume ascii; warning: evaluates x multiple times! */
+#define order(x) ((x) == '~' ? -1 \
+		: isdigit((x)) ? 0 \
+		: !(x) ? 0 \
+		: isalpha((x)) ? (x) \
+		: (x) + 256)
+
+static int verrevcmp(const char *val, const char *ref)
+{
+	if (!val)
+		val = "";
+	if (!ref)
+		ref = "";
+
+	while (*val || *ref) {
+		int first_diff = 0;
+
+		while ((*val && !isdigit(*val)) || (*ref && !isdigit(*ref))) {
+			int vc = order(*val), rc = order(*ref);
+			if (vc != rc)
+				return vc - rc;
+			val++;
+			ref++;
+		}
+
+		while (*val == '0')
+			val++;
+		while (*ref == '0')
+			ref++;
+		while (isdigit(*val) && isdigit(*ref)) {
+			if (!first_diff)
+				first_diff = *val - *ref;
+			val++;
+			ref++;
+		}
+		if (isdigit(*val))
+			return 1;
+		if (isdigit(*ref))
+			return -1;
+		if (first_diff)
+			return first_diff;
+	}
+	return 0;
+}
+
 
 /**
  * UBUS response callbacks
@@ -414,7 +467,7 @@ static void pkglist_check_cb(struct ubus_request *req, int type, struct blob_att
 			continue;
 		}
 
-		cmpres = strcmp(blobmsg_get_string(cur), pkg->version);
+		cmpres = verrevcmp(blobmsg_get_string(cur), pkg->version);
 		if (cmpres < 0)
 			*status |= PKG_UPGRADE;
 
-- 
GitLab