From feb7568b7b45245bdf71bd97cf9ef7c585b28c42 Mon Sep 17 00:00:00 2001
From: Jan Luebbe <jlu@pengutronix.de>
Date: Mon, 3 Mar 2025 18:56:21 +0100
Subject: [PATCH 3/6] utils: add helper to get a string list from a GKeyFile

The helper also optionally checks the strings against an allow-list.

Signed-off-by: Jan Luebbe <jlu@pengutronix.de>
Upstream-Status: Backport
---
 include/utils.h | 21 +++++++++++++++++++++
 src/utils.c     | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/include/utils.h b/include/utils.h
index 0c009eab..ae0a7c2c 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -303,6 +303,27 @@ guint64 key_file_consume_binary_suffixed_string(GKeyFile *key_file,
 		GError **error)
 G_GNUC_WARN_UNUSED_RESULT;
 
+/**
+ * Get list of string arguments from key and remove key from key_file.
+ *
+ * Optionally filter
+ *
+ * @param key_file a GKeyFile
+ * @param group_name the group name
+ * @param key the key name
+ * @param allowed a list of allowed strings, or NULL
+ * @param error return location for a GError, or NULL
+ *
+ * @return a GStrv or NULL if the key was not found or an error occurred
+ */
+gchar **key_file_consume_string_list(
+		GKeyFile *key_file,
+		const gchar *group_name,
+		const gchar *key,
+		const gchar * const *allowed,
+		GError **error)
+G_GNUC_WARN_UNUSED_RESULT;
+
 gchar * r_realpath(const gchar *path)
 G_GNUC_WARN_UNUSED_RESULT;
 
diff --git a/src/utils.c b/src/utils.c
index 2bc3b9f2..8e097955 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -486,6 +486,45 @@ guint64 key_file_consume_binary_suffixed_string(GKeyFile *key_file,
 	return result << scale_shift;
 }
 
+gchar **key_file_consume_string_list(
+		GKeyFile *key_file,
+		const gchar *group_name,
+		const gchar *key,
+		const gchar * const *allowed,
+		GError **error)
+{
+	GError *ierror = NULL;
+	gsize length = 0;
+
+	g_auto(GStrv) result = g_key_file_get_string_list(key_file, group_name, key, &length, &ierror);
+	if (g_error_matches(ierror, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) {
+		/* handle missing key the same as an empty list */
+		g_clear_error(&ierror);
+		return NULL;
+	} else if (ierror) {
+		g_propagate_error(error, ierror);
+		return NULL;
+	}
+
+	g_key_file_remove_key(key_file, group_name, key, NULL);
+
+	if (length == 0)
+		return NULL;
+
+	/* check against allow-list */
+	if (allowed) {
+		for (gsize i = 0; i < length; i++) {
+			if (!g_strv_contains(allowed, result[i])) {
+				g_set_error(error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE,
+						"Unsupported list item '%s' for key '%s' in [%s]", result[i], key, group_name);
+				return NULL;
+			}
+		}
+	}
+
+	return g_steal_pointer(&result);
+}
+
 gchar * r_realpath(const gchar *path)
 {
 	gchar buf[PATH_MAX + 1];
-- 
2.47.3

