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); } -
