From becbfdc4033d15ec0661c9f41adb0004c7af7c63 Mon Sep 17 00:00:00 2001
From: Olivier Matz <zer0@droids-corp.org>
Date: Thu, 9 Aug 2018 15:55:42 +0200
Subject: [PATCH] do not use reserved names.

---
 lib/ecoli_config.c | 31 +++++++++++++++++++++++++++++++
 lib/ecoli_config.h | 17 +++++++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/lib/ecoli_config.c b/lib/ecoli_config.c
index 838438e..ff4b27d 100644
--- a/lib/ecoli_config.c
+++ b/lib/ecoli_config.c
@@ -18,6 +18,13 @@
 
 EC_LOG_TYPE_REGISTER(config);
 
+const char *ec_config_reserved_keys[] = {
+	"id",
+	"attrs",
+	"help",
+	"type",
+};
+
 static int
 __ec_config_dump(FILE *out, const char *key, const struct ec_config *config,
 	size_t indent);
@@ -25,6 +32,18 @@ static int
 ec_config_dict_validate(const struct ec_keyval *dict,
 			const struct ec_config_schema *schema);
 
+bool
+ec_config_key_is_reserved(const char *name)
+{
+	size_t i;
+
+	for (i = 0; i < EC_COUNT_OF(ec_config_reserved_keys); i++) {
+		if (!strcmp(name, ec_config_reserved_keys[i]))
+			return true;
+	}
+	return false;
+}
+
 /* return ec_value type as a string */
 static const char *
 ec_config_type_str(enum ec_config_type type)
@@ -82,6 +101,13 @@ __ec_config_schema_validate(const struct ec_config_schema *schema,
 	}
 
 	for (i = 0; schema[i].type != EC_CONFIG_TYPE_NONE; i++) {
+		if (schema[i].key != NULL &&
+				ec_config_key_is_reserved(schema[i].key)) {
+			errno = EINVAL;
+			EC_LOG(EC_LOG_ERR,
+				"key name <%s> is reserved\n", schema[i].key);
+			return -1;
+		}
 		/* check for duplicate name if more than one element */
 		for (j = i + 1; schema[j].type != EC_CONFIG_TYPE_NONE; j++) {
 			if (!strcmp(schema[i].key, schema[j].key)) {
@@ -935,6 +961,11 @@ static int ec_config_testcase(void)
 	int testres = 0;
 	int ret;
 
+	testres |= EC_TEST_CHECK(ec_config_key_is_reserved("id"),
+		"'id' should be reserved");
+	testres |= EC_TEST_CHECK(!ec_config_key_is_reserved("foo"),
+		"'foo' should not be reserved");
+
 	node = ec_node("empty", EC_NO_ID);
 	if (node == NULL)
 		goto fail;
diff --git a/lib/ecoli_config.h b/lib/ecoli_config.h
index 866a67a..8ceddf5 100644
--- a/lib/ecoli_config.h
+++ b/lib/ecoli_config.h
@@ -98,6 +98,23 @@ int ec_config_schema_validate(const struct ec_config_schema *schema);
  */
 void ec_config_schema_dump(FILE *out, const struct ec_config_schema *schema);
 
+/**
+ * Check if a key name is reserved in a config dict.
+ *
+ * Some key names are reserved and should not be used in configs.
+ *
+ * @param name
+ *   The name of the key to test.
+ * @return
+ *   True if the key name is reserved and must not be used, else false.
+ */
+bool ec_config_key_is_reserved(const char *name);
+
+/**
+ * Array of reserved key names.
+ */
+extern const char *ec_config_reserved_keys[];
+
 
 /* config */
 
-- 
2.39.5