This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch feature/type_support_for_properties
in repository https://gitbox.apache.org/repos/asf/celix.git

commit fe434a03fe99bab2228df8dd2292aa3ddf0d13e1
Author: Pepijn Noltes <[email protected]>
AuthorDate: Sun Jan 8 22:48:12 2023 +0100

    Fix issue with setting properties with NULL values
---
 libs/utils/gtest/src/PropertiesTestSuite.cc |  5 ++--
 libs/utils/src/properties.c                 | 40 +++++++++++++++++------------
 2 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/libs/utils/gtest/src/PropertiesTestSuite.cc 
b/libs/utils/gtest/src/PropertiesTestSuite.cc
index 6904652e..bfc3efbf 100644
--- a/libs/utils/gtest/src/PropertiesTestSuite.cc
+++ b/libs/utils/gtest/src/PropertiesTestSuite.cc
@@ -141,8 +141,9 @@ TEST_F(PropertiesTestSuite, GetSetWithNullTest) {
     celix_properties_set(properties, nullptr, nullptr);
     EXPECT_EQ(celix_properties_size(properties), 0); //NULL key will be ignored
 
-    celix_properties_set(properties, "key", nullptr);
-    EXPECT_EQ(celix_properties_size(properties), 0); //NULL value will be 
ignored
+    celix_properties_set(properties, "key", nullptr); //NULL value will result 
in empty string value
+    EXPECT_STREQ("", celix_properties_get(properties, "key", "not found"));
+    EXPECT_EQ(celix_properties_size(properties), 1);
 
     celix_properties_destroy(properties);
 }
diff --git a/libs/utils/src/properties.c b/libs/utils/src/properties.c
index 778e00da..0ef19cc2 100644
--- a/libs/utils/src/properties.c
+++ b/libs/utils/src/properties.c
@@ -38,6 +38,7 @@
 
 static const char* const CELIX_PROPERTIES_BOOL_TRUE_STRVAL = "true";
 static const char* const CELIX_PROPERTIES_BOOL_FALSE_STRVAL = "false";
+static const char* const CELIX_PROPERTIES_EMPTY_STRVAL = "";
 
 struct celix_properties {
     celix_string_hash_map_t* map;
@@ -148,7 +149,7 @@ static void updateBuffers(char **key, char ** value, char 
**output, int outputPo
  */
 static char* celix_properties_createString(celix_properties_t* properties, 
const char* str) {
     if (str == NULL) {
-        return NULL;
+        return (char*)CELIX_PROPERTIES_EMPTY_STRVAL;
     }
     size_t len = strnlen(str, CELIX_UTILS_MAX_STRLEN) + 1;
     size_t left = CELIX_SHORT_PROPERTIES_OPTIMIZATION_STRING_BUFFER_SIZE - 
properties->currentStringBufferIndex;
@@ -162,6 +163,22 @@ static char* 
celix_properties_createString(celix_properties_t* properties, const
     }
     return result;
 }
+/**
+ * Free string, but first check if it a static const char* const string or 
part of the short properties
+ * optimization.
+ */
+static void celix_properties_freeString(celix_properties_t* properties, char* 
str) {
+    if (str == CELIX_PROPERTIES_BOOL_TRUE_STRVAL ||
+            str == CELIX_PROPERTIES_BOOL_FALSE_STRVAL ||
+            str == CELIX_PROPERTIES_EMPTY_STRVAL) {
+        //str is static const char* const -> nop
+    } else if (str >= properties->stringBuffer &&
+               str < (properties->stringBuffer + 
CELIX_SHORT_PROPERTIES_OPTIMIZATION_STRING_BUFFER_SIZE))   {
+        //str is part of the properties string buffer -> nop
+    } else {
+        free(str);
+    }
+}
 
 /**
  * Fill entry and optional use the short properties optimization string buffer.
@@ -272,7 +289,12 @@ static celix_properties_entry_t* 
celix_properties_createEntry(
     celix_status_t status = celix_properties_fillEntry(properties, entry, 
strValue, longValue, doubleValue,
                                                        boolValue, 
versionValue);
     if (status != CELIX_SUCCESS) {
-        free(entry);
+        if (entry >= properties->entriesBuffer &&
+            entry <= (properties->entriesBuffer + 
CELIX_SHORT_PROPERTIES_OPTIMIZATION_ENTRIES_SIZE)) {
+            //entry is part of the properties entries buffer -> nop.
+        } else {
+            free(entry);
+        }
         entry = NULL;
     }
     return entry;
@@ -305,19 +327,6 @@ static void celix_properties_createAndSetEntry(
     }
 }
 
-
-
-static void celix_properties_freeString(celix_properties_t* properties, char* 
str) {
-    if (str == CELIX_PROPERTIES_BOOL_TRUE_STRVAL || str == 
CELIX_PROPERTIES_BOOL_FALSE_STRVAL) {
-        //str is static const char* const -> nop
-    } else if (str >= properties->stringBuffer &&
-               str < (properties->stringBuffer + 
CELIX_SHORT_PROPERTIES_OPTIMIZATION_STRING_BUFFER_SIZE))   {
-        //str is part of the properties string buffer -> nop
-    } else {
-        free(str);
-    }
-}
-
 static void celix_properties_removeKeyCallback(void* handle, char* key) {
     celix_properties_t* properties = handle;
     celix_properties_freeString(properties, key);
@@ -861,4 +870,3 @@ bool celix_propertiesIterator_equals(const 
celix_properties_iterator_t* a, const
     memcpy(&internalIterB, b->_data, sizeof(internalIterB));
     return celix_stringHashMapIterator_equals(&internalIterA.mapIter, 
&internalIterB.mapIter);
 }
-

Reply via email to