diff mbox series

BUG: Parser: solve incompatibility between parsers

Message ID 20241002155743.242157-1-stefano.babic@swupdate.org
State Accepted
Headers show
Series BUG: Parser: solve incompatibility between parsers | expand

Commit Message

Stefano Babic Oct. 2, 2024, 3:57 p.m. UTC
It is possible to switch between json and libconfig, but JSON allows to
scale down an array to a scalra if it has just one element, and this
breaks the parser looking for array in case of libconfig that is strict
typed. Solve this allowing this singularity in case of libconfig.
Note that this issue causes SWUpdate to abort in json-c library
because a function operating on a JSON array is called - by
checking the type, this is solved, too.

Signed-off-by: Stefano Babic <stefano.babic@swupdate.org>
---
 core/parsing_library.c     | 35 ++++++++++++++++++++++++++++++++---
 include/parselib-private.h |  4 ++++
 2 files changed, 36 insertions(+), 3 deletions(-)

--
2.34.1
diff mbox series

Patch

diff --git a/core/parsing_library.c b/core/parsing_library.c
index 038c6851..1dc0c42a 100644
--- a/core/parsing_library.c
+++ b/core/parsing_library.c
@@ -38,11 +38,37 @@  void check_field_string(const char *src, char *dst, const size_t max_len)

 int get_array_length(parsertype p, void *root)
 {
+	int type;
 	switch (p) {
 	case LIBCFG_PARSER:
-		return config_setting_length(root);
+		type = config_setting_type((config_setting_t *)root);
+		switch (type) {
+		case CONFIG_TYPE_LIST:
+		case CONFIG_TYPE_ARRAY:
+			return config_setting_length((config_setting_t *)root);
+		/*
+		 * Group is considered as array of length=1, like object for JSON
+		 */
+		case CONFIG_TYPE_GROUP:
+			return 1;
+		default:
+			return 0;
+		}
+
 	case JSON_PARSER:
-		return json_object_array_length(root);
+		switch (json_object_get_type((json_object *)root)) {
+		case json_type_array:
+			return json_object_array_length(root);
+		/*
+		 * It is a single object. JSON allows to move to a object if
+		 * the array has just one element, so returns 1
+		 * as this is the only element
+		 */
+		case json_type_object:
+			return 1;
+		default:
+			return 0;
+		}
 	default:
 		(void)root;
 	}
@@ -87,7 +113,10 @@  void *get_elem_from_idx(parsertype p, void *node, int idx)
 	case LIBCFG_PARSER:
 		return config_setting_get_elem(node, idx);
 	case JSON_PARSER:
-		return json_object_array_get_idx(node, idx);
+		if (json_object_get_type((json_object *)node) == json_type_array) {
+			return json_object_array_get_idx(node, idx);
+		}
+		return node;
 	default:
 		(void)node;
 		(void)idx;
diff --git a/include/parselib-private.h b/include/parselib-private.h
index e3c34dc8..45d500e5 100644
--- a/include/parselib-private.h
+++ b/include/parselib-private.h
@@ -24,6 +24,7 @@  void *get_node_libconfig(config_t *cfg, const char **nodes);
 #define config_setting_get_elem(a,b)	(NULL)
 #define config_setting_length(a)	(0)
 #define config_setting_lookup_string(a, b, str) (0)
+#define config_setting_type(path) (0)
 #define find_node_libconfig(cfg, field, swcfg) (NULL)
 #define get_field_string_libconfig(e, path)	(NULL)
 #define get_child_libconfig(e, name)		(NULL)
@@ -32,6 +33,9 @@  void *get_node_libconfig(config_t *cfg, const char **nodes);
 #define find_root_libconfig(cfg, nodes, depth)		(NULL)
 #define get_node_libconfig(cfg, nodes)		(NULL)
 #define is_field_numeric_cfg(e, path)	(false)
+#define CONFIG_TYPE_GROUP   1
+#define CONFIG_TYPE_ARRAY   7
+#define CONFIG_TYPE_LIST    8
 #endif

 /*