From 5d9a370c2e2e1ffc77c967d52f8e5b33a62631b5 Mon Sep 17 00:00:00 2001 From: Eugene Dorfman Date: Fri, 25 Oct 2024 18:31:57 +0200 Subject: [PATCH 1/6] FEAT: extend dynamically allocated evidence array by additionalCapacity in case derived evidence is to be added on the fly during device detection (f.e. derived from 51d_gethighentropyvalues) --- EvidenceBase.cpp | 7 ++++--- EvidenceBase.hpp | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/EvidenceBase.cpp b/EvidenceBase.cpp index f665c5c2..21bcf0c1 100644 --- a/EvidenceBase.cpp +++ b/EvidenceBase.cpp @@ -26,7 +26,7 @@ using namespace FiftyoneDegrees::Common; -EvidenceBase::EvidenceBase() { +EvidenceBase::EvidenceBase(size_t additionalCapacity): additionalCapacity(additionalCapacity) { evidence = NULL; } @@ -42,7 +42,8 @@ fiftyoneDegreesEvidenceKeyValuePairArray* EvidenceBase::get() { EvidenceFree(evidence); evidence = NULL; } - evidence = EvidenceCreate((uint32_t)size()); + // in case capacity has been provided as a hint + evidence = EvidenceCreate((uint32_t)(size() + additionalCapacity)); if (evidence != NULL) { for (map::const_iterator iterator = begin(); iterator != end(); @@ -88,4 +89,4 @@ void EvidenceBase::erase(iterator first, iterator last) { map::erase(first, last); EvidenceFree(evidence); evidence = NULL; -} \ No newline at end of file +} diff --git a/EvidenceBase.hpp b/EvidenceBase.hpp index c523ae62..c7a7f8f8 100644 --- a/EvidenceBase.hpp +++ b/EvidenceBase.hpp @@ -65,6 +65,7 @@ namespace FiftyoneDegrees { * ``` */ class EvidenceBase : public map { + size_t additionalCapacity; public: /** * @name Constructors and Destructors @@ -73,8 +74,18 @@ namespace FiftyoneDegrees { /** * Construct a new instance containing no evidence. + * @param additionalCapacity - hint the additional capacity for the + * dynamically allocated evidence array structure, to allow + * derived evidence be added on the fly, when process() function is + * called on the evidence. + * The total capacity is the number of existing kv pairs plus this + * additional capacity. + * f.e. it may be necessary to expand 51d_gethighentropyvalues + * into sec-ch-ua headers, thus the additional capacity must be 6. + * If additional capacity is 0 - then the native evidence array will + * have the capacity matching the number of key value pairs. */ - EvidenceBase(); + EvidenceBase(size_t additionalCapacity = 0); /** * Free all the underlying memory containing the evidence. @@ -138,4 +149,4 @@ namespace FiftyoneDegrees { } } -#endif \ No newline at end of file +#endif From cc9536e9cdcec8946a8d60c8af0dfbff02c6ecc4 Mon Sep 17 00:00:00 2001 From: James Rosewell Date: Tue, 29 Oct 2024 10:11:01 +0000 Subject: [PATCH 2/6] FEAT/REFACT: Modifed evidence so that if the capacity of the array is going to be exceeded when new evidence is added a new array is created and linked to the original one. This is needed to avoid situations where GHEV or other dynamic evidence is unpacked and there is insufficient capacity in the original evidence array. The developer would receive unpredicatable results and it would not be obvious where the problem is. The dynamic allocation of more memory for evidence can be avoided by specifying a sufficiently large evidence capacity when the initial evidence array is created. The void pointer used in pairs and evidence pairs has been removed and the KeyValuePair with character pointers used throughout. This reduces problems with casting void pointers for no reason. The evidence key value pair now uses the key value pair to reduce duplication and ensure that all strings have length fields to reduce calls to strlen and to handle GHEV evidence where the string may not be null terminated. Code that expects the keys, values, or parsed value to be null terminated now needs to use the length field to get the number of characters. If a null terminated version is needed then the caller will need to make a copy and add a null terminator. --- evidence.c | 208 ++++++++++++++++++++++++++++++++++------------------- evidence.h | 93 +++++++++++++----------- fiftyone.h | 2 + headers.c | 12 ++-- headers.h | 9 +-- pair.h | 8 +-- 6 files changed, 197 insertions(+), 135 deletions(-) diff --git a/evidence.c b/evidence.c index c53539b6..771e00c4 100644 --- a/evidence.c +++ b/evidence.c @@ -24,15 +24,22 @@ #include "fiftyone.h" typedef struct evidence_iterate_state_t { - fiftyoneDegreesEvidenceKeyValuePairArray *evidence; + EvidenceKeyValuePairArray *evidence; EvidencePrefix prefix; void *state; - fiftyoneDegreesEvidenceIterateMethod callback; + EvidenceIterateMethod callback; } evidenceIterateState; +typedef struct evidence_find_state_t { + Header* header; // Header to find + EvidenceKeyValuePair* pair; // Pair found that matches the header +} evidenceFindState; + static EvidencePrefixMap _map[] = { - { "server.", sizeof("server.") - 1, FIFTYONE_DEGREES_EVIDENCE_SERVER }, - { "header.", sizeof("header.") - 1, FIFTYONE_DEGREES_EVIDENCE_HTTP_HEADER_STRING }, + { "server.", sizeof("server.") - 1, + FIFTYONE_DEGREES_EVIDENCE_SERVER }, + { "header.", sizeof("header.") - 1, + FIFTYONE_DEGREES_EVIDENCE_HTTP_HEADER_STRING }, { "query.", sizeof("query.") - 1, FIFTYONE_DEGREES_EVIDENCE_QUERY }, { "cookie.", sizeof("cookie.") - 1, FIFTYONE_DEGREES_EVIDENCE_COOKIE } }; @@ -45,8 +52,9 @@ static void parsePair(EvidenceKeyValuePair *pair) { case FIFTYONE_DEGREES_EVIDENCE_QUERY: case FIFTYONE_DEGREES_EVIDENCE_COOKIE: default: - pair->parsedValue = pair->originalValue; - pair->parsedLength = strlen(pair->parsedValue); + // These are string prefixes so just copy over the original values. + pair->parsedValue = pair->item.value; + pair->parsedLength = pair->item.valueLength; break; } } @@ -54,15 +62,19 @@ static void parsePair(EvidenceKeyValuePair *pair) { // If a string comparison of the pair field and the header indicates a match // then set the header to avoid a string comparison in future iterations. static void setPairHeader(EvidenceKeyValuePair* pair, Header* header) { - if (pair->fieldLength == header->length && - StringCompareLength(pair->field, header->name, header->length) == 0) { + if (pair->item.keyLength == header->nameLength && + StringCompareLength( + pair->item.key, + header->name, + header->nameLength) == 0) { pair->header = header; } } /** * Iterate through an evidence collection and perform callback on the evidence - * whose prefix matches the input prefixes. + * whose prefix matches the input prefixes. Checks the linked list of evidence + * arrays to ensure these are also processed. * * @param evidence the evidence collection to process * @param prefixes the accepted evidence prefixes @@ -75,12 +87,14 @@ static uint32_t evidenceIterate( int prefixes, void* state, EvidenceIterateMethod callback) { - uint32_t i = 0, iterations = 0; - const uint32_t count = evidence->count; + uint32_t index = 0, iterations = 0; EvidenceKeyValuePair* pair; bool cont = true; - while (cont && i < count) { - pair = &evidence->items[i++]; + while (cont && evidence != NULL) { + + // Check the current evidence item and call back if the right prefix + // after parsing the pair if not done so already. + pair = &evidence->items[index++]; if ((pair->prefix & prefixes) == pair->prefix) { if (pair->parsedValue == NULL) { parsePair(pair); @@ -88,10 +102,36 @@ static uint32_t evidenceIterate( cont = callback(state, pair); iterations++; } + + // Check if the next evidence array needs to be moved to. + if (index >= evidence->count) { + evidence = evidence->next; + index = 0; + } } return iterations; } +/** + * If the header name and pair key match then stop iterating having set the + * found pair, otherwise return false. + */ +static bool findHeaderEvidenceCallback( + void* state, + EvidenceKeyValuePair* pair) { + evidenceFindState* findState = (evidenceFindState*)state; + if (findState->header == pair->header || ( + findState->header->nameLength == pair->item.keyLength && + StringCompareLength( + findState->header->name, + pair->item.key, + pair->item.keyLength) == 0)) { + findState->pair = pair; + return false; + } + return true; +} + /** * Finds the evidence pair that matches the header. Returns null if a pair does * not exist. @@ -100,39 +140,20 @@ static EvidenceKeyValuePair* findHeaderEvidence( EvidenceKeyValuePairArray* evidence, int prefixes, Header* header) { - EvidenceKeyValuePair* pair; - - // For each of the evidence pairs available. - for (uint32_t i = 0; i < evidence->count; i++) { - pair = &evidence->items[i]; - - // Check that the prefix is one that is being considered. - if ((pair->prefix & prefixes) == pair->prefix) { - - // If the header has been assigned to the pair check to see if this - // one is a match. - if (pair->header == NULL) { - setPairHeader(pair, header); - } - - // If the pair's header and the required header are the same. - if (pair->header == header) { - - // Ensure the parsed value is populated before returning. - if (pair->parsedValue == NULL) { - parsePair(pair); - } - return pair; - } - } - } - return NULL; + evidenceFindState state = { header, NULL }; + evidenceIterate(evidence, prefixes, &state, findHeaderEvidenceCallback); + return state.pair; } // Safe-copies the pair parsed value to the buffer checking that there are // sufficient bytes remaining in the buffer for the parsed value. -static void addPairValueToBuffer(StringBuilder* builder, EvidenceKeyValuePair* pair) { - StringBuilderAddChars(builder, (char*)pair->parsedValue, pair->parsedLength); +static void addPairValueToBuffer( + StringBuilder* builder, + EvidenceKeyValuePair* pair) { + StringBuilderAddChars( + builder, + (char*)pair->parsedValue, + pair->parsedLength); } // For the header finds the corresponding evidence in the array of evidence. If @@ -166,8 +187,8 @@ static bool addHeaderValueToBuilder( // current character in the buffer. addPairValueToBuffer(builder, pair); - // return false if we have overfilled the buffer - return !builder->full; + // Return false if we have overfilled the buffer. + return builder->full == false; } // Assembles a pseudo header in the buffer. If this can not be achieved returns @@ -180,11 +201,13 @@ static bool processPseudoHeader( Header* header, StringBuilder* builder, void* state, - fiftyoneDegreesEvidenceIterateForHeadersMethod callback) { + fiftyoneDegreesEvidenceIterateMethod callback) { + EvidenceKeyValuePair pair; // For each of the headers that form the pseudo header. for (uint32_t i = 0; i < header->segmentHeaders->count; i++) { - //if this is a subsequent segment - we prepend the separator + + // if this is a subsequent segment - we prepend the separator bool prependSeparator = i > 0; // Add the header evidence that forms the segment if available updating @@ -207,9 +230,17 @@ static bool processPseudoHeader( // character. StringBuilderComplete(builder); - // A full header has been formed so call the callback with the buffer and - // the number of characters populated. - return callback(state, header, builder->ptr, builder->added); + // A full header has been formed so call the callback with an evidence pair + // containing the parsed value. + pair.item.key = NULL; + pair.item.keyLength = 0; + pair.header = header; + pair.item.value = builder->ptr; + pair.item.valueLength = builder->added; + pair.parsedValue = builder->ptr; + pair.parsedLength = builder->added; + pair.prefix = 0; + return callback(state, &pair); } // Finds the header in the evidence, and if available calls the callback. @@ -220,7 +251,7 @@ static bool processHeader( int prefixes, Header* header, void* state, - fiftyoneDegreesEvidenceIterateForHeadersMethod callback) { + fiftyoneDegreesEvidenceIterateMethod callback) { // Get the evidence that corresponds to the header. If it doesn't exist // then there is no evidence for the header and a call back will not be @@ -233,27 +264,26 @@ static bool processHeader( return true; } - // A full header has been formed so call the callback with the buffer and - // the number of characters populated. - return callback( - state, - header, - (const char*)pair->parsedValue, - pair->parsedLength); + // A full header has been formed so call the callback with the pair. + return callback(state, pair); } fiftyoneDegreesEvidenceKeyValuePairArray* fiftyoneDegreesEvidenceCreate(uint32_t capacity) { - EvidenceKeyValuePairArray *evidence; + fiftyoneDegreesEvidenceKeyValuePairArray *evidence; uint32_t i; FIFTYONE_DEGREES_ARRAY_CREATE(EvidenceKeyValuePair, evidence, capacity); if (evidence != NULL) { + evidence->next = NULL; + evidence->prev = NULL; for (i = 0; i < evidence->capacity; i++) { - evidence->items[i].field = NULL; - evidence->items[i].fieldLength = 0; + evidence->items[i].item.key = NULL; + evidence->items[i].item.keyLength = 0; + evidence->items[i].item.value = NULL; + evidence->items[i].item.valueLength = 0; evidence->items[i].header = NULL; - evidence->items[i].originalValue = NULL; evidence->items[i].parsedValue = NULL; + evidence->items[i].parsedLength = 0; evidence->items[i].prefix = FIFTYONE_DEGREES_EVIDENCE_IGNORE; } } @@ -262,27 +292,55 @@ fiftyoneDegreesEvidenceCreate(uint32_t capacity) { void fiftyoneDegreesEvidenceFree( fiftyoneDegreesEvidenceKeyValuePairArray *evidence) { - Free(evidence); + EvidenceKeyValuePairArray* current = evidence; + while (current->next != NULL) { + current = current->next; + } + while (current != NULL) { + evidence = current->prev; + Free(current); + current = evidence; + } } -fiftyoneDegreesEvidenceKeyValuePair* fiftyoneDegreesEvidenceAddString( +fiftyoneDegreesEvidenceKeyValuePair* fiftyoneDegreesEvidenceAddPair( fiftyoneDegreesEvidenceKeyValuePairArray *evidence, fiftyoneDegreesEvidencePrefix prefix, - const char *field, - const char *originalValue) { + fiftyoneDegreesKeyValuePair value) { EvidenceKeyValuePair *pair = NULL; - if (evidence->count < evidence->capacity) { - pair = &evidence->items[evidence->count++]; - pair->prefix = prefix; - pair->field = field; - pair->fieldLength = strlen(field); - pair->originalValue = (void*)originalValue; - pair->parsedValue = NULL; - pair->header = NULL; + while (pair == NULL) { + if (evidence->count < evidence->capacity) { + // Use the next item in the allocated array. + pair = &evidence->items[evidence->count++]; + pair->prefix = prefix; + pair->item = value; + pair->parsedValue = NULL; + pair->header = NULL; + } + else { + // If there is insufficient capacity in the evidence array then add + // a new array. + if (evidence->next == NULL) { + evidence->next = EvidenceCreate( + evidence->capacity == 0 ? 1 : evidence->capacity); + evidence->next->prev = evidence; + } + // Move to the next evidence array. + evidence = evidence->next; + } } return pair; } +fiftyoneDegreesEvidenceKeyValuePair* fiftyoneDegreesEvidenceAddString( + fiftyoneDegreesEvidenceKeyValuePairArray* evidence, + fiftyoneDegreesEvidencePrefix prefix, + const char* key, + const char* value) { + KeyValuePair pair = { key, strlen(key), value, strlen(value) }; + return EvidenceAddPair(evidence, prefix, pair); +} + uint32_t fiftyoneDegreesEvidenceIterate( fiftyoneDegreesEvidenceKeyValuePairArray *evidence, int prefixes, @@ -312,7 +370,7 @@ fiftyoneDegreesEvidencePrefixMap* fiftyoneDegreesEvidenceMapPrefix( return result; } -EXTERNAL const char* fiftyoneDegreesEvidencePrefixString( +const char* fiftyoneDegreesEvidencePrefixString( fiftyoneDegreesEvidencePrefix prefix) { uint32_t i; EvidencePrefixMap* map; @@ -334,7 +392,7 @@ bool fiftyoneDegreesEvidenceIterateForHeaders( char* const buffer, size_t const length, void* state, - fiftyoneDegreesEvidenceIterateForHeadersMethod callback) { + fiftyoneDegreesEvidenceIterateMethod callback) { Header* header; StringBuilder builder = { buffer, length }; diff --git a/evidence.h b/evidence.h index 70eda75d..eecdd772 100644 --- a/evidence.h +++ b/evidence.h @@ -124,6 +124,7 @@ #include "string.h" #include "array.h" #include "common.h" +#include "pair.h" #include "headers.h" /** @@ -159,18 +160,35 @@ typedef struct fiftyone_degrees_evidence_prefix_map_t { */ typedef struct fiftyone_degrees_evidence_key_value_pair_t { fiftyoneDegreesEvidencePrefix prefix; /**< e.g. #FIFTYONE_DEGREES_EVIDENCE_HTTP_HEADER_STRING */ - const char *field; /**< e.g. User-Agent or ScreenPixelsWidth */ - size_t fieldLength; /**< length of field */ - const void *originalValue; /**< original unparsed value */ + fiftyoneDegreesKeyValuePair item; /**< the field key and original value */ const void *parsedValue; /**< parsed value which may not be a string */ size_t parsedLength; /**< length of parsedValue string */ fiftyoneDegreesHeader* header; /**< Unique header in the data set, or null if not related to a header */ } fiftyoneDegreesEvidenceKeyValuePair; +/** + * Forward declaration of the array so that it can point to an instance of the + * same type. + */ +typedef struct fiftyone_degrees_array_fiftyoneDegreesEvidenceKeyValuePair_t + fiftyoneDegreesEvidenceKeyValuePairArray; + +/** + * Pointers to the next and previous array of evidence key value pairs or + * NULL if not present. + */ +#define FIFTYONE_DEGREES_ARRAY_EVIDENCE_MEMBER \ + fiftyoneDegreesEvidenceKeyValuePairArray *next; \ + fiftyoneDegreesEvidenceKeyValuePairArray *prev; + +/** + * Array of evidence key value pairs and a pointer to the next array if present + * or NULL of not present. + */ FIFTYONE_DEGREES_ARRAY_TYPE( fiftyoneDegreesEvidenceKeyValuePair, - ) + FIFTYONE_DEGREES_ARRAY_EVIDENCE_MEMBER) /** * Callback method used to iterate evidence key value pairs. @@ -182,31 +200,17 @@ typedef bool(*fiftyoneDegreesEvidenceIterateMethod)( void *state, fiftyoneDegreesEvidenceKeyValuePair *pair); -/** - * Callback method used to iterate evidence key value pairs for an array of - * headers. - * @param state pointer provided to the iterator - * @param header that the value is related to - * @param value from the evidence for the header - * @param length of the value - * @return true if the iteration should continue otherwise false - */ -typedef bool(*fiftyoneDegreesEvidenceIterateForHeadersMethod)( - void* state, - fiftyoneDegreesHeader* header, - const char* value, - size_t length); - /** * Creates a new evidence array with the capacity requested. * @param capacity maximum number of evidence items * @return pointer to the newly created array */ EXTERNAL fiftyoneDegreesEvidenceKeyValuePairArray* -fiftyoneDegreesEvidenceCreate(uint32_t capacity); + fiftyoneDegreesEvidenceCreate(uint32_t capacity); /** - * Frees the memory used by an evidence array. + * Frees the memory used by an evidence array and any other arrays pointed to + * by the instance passed via the next member. * @param evidence pointer to the array to be freed */ EXTERNAL void fiftyoneDegreesEvidenceFree( @@ -216,16 +220,37 @@ EXTERNAL void fiftyoneDegreesEvidenceFree( * Adds a new entry to the evidence. The memory associated with the * field and original value parameters must not be freed until after the * evidence collection has been freed. This method will NOT copy the values. + * If there is insufficient capacity in the evidence array then another array + * will be created and will be pointed to by the next member of the evidence + * array passed. * @param evidence pointer to the evidence array to add the entry to * @param prefix enum indicating the category the entry belongs to - * @param field used as the key for the entry within its prefix - * @param originalValue the value to be parsed + * @param key string with null terminator + * @param value string with null terminator + * @returns the new evidence key value pair instance */ EXTERNAL fiftyoneDegreesEvidenceKeyValuePair* fiftyoneDegreesEvidenceAddString( fiftyoneDegreesEvidenceKeyValuePairArray *evidence, fiftyoneDegreesEvidencePrefix prefix, - const char *field, - const char *originalValue); + const char *key, + const char *value); + +/** + * Adds a new entry to the evidence. The memory associated with the + * field and original value parameters must not be freed until after the + * evidence collection has been freed. This method will NOT copy the values. + * If there is insufficient capacity in the evidence array then another array + * will be created and will be pointed to by the next member of the evidence + * array passed. + * @param evidence pointer to the evidence array to add the entry to + * @param prefix enum indicating the category the entry belongs to + * @param pair used as the key and value for the new entry + * @returns the new evidence key value pair instance + */ +EXTERNAL fiftyoneDegreesEvidenceKeyValuePair* fiftyoneDegreesEvidenceAddPair( + fiftyoneDegreesEvidenceKeyValuePairArray* evidence, + fiftyoneDegreesEvidencePrefix prefix, + fiftyoneDegreesKeyValuePair pair); /** * Determines the evidence map prefix from the key. @@ -260,22 +285,6 @@ EXTERNAL uint32_t fiftyoneDegreesEvidenceIterate( void *state, fiftyoneDegreesEvidenceIterateMethod callback); - -/** - * First checks if provided prefix+field are not already part of the - * evidence array with the same parameters. - * If not calls fiftyoneDegreesEvidenceAddString. - * @param evidence pointer to the evidence array to add the entry to - * @param prefix enum indicating the category the entry belongs to - * @param field used as the key for the entry within its prefix - * @param originalValue the value to be parsed - */ -EXTERNAL fiftyoneDegreesEvidenceKeyValuePair* fiftyoneDegreesEvidenceAddStringUnique( - fiftyoneDegreesEvidenceKeyValuePairArray *evidence, - fiftyoneDegreesEvidencePrefix prefix, - const char *field, - const char *originalValue); - /** * Iterates over the headers assembling the evidence values, considering the * prefixes, in the buffer if available. The call back method is called for @@ -300,7 +309,7 @@ EXTERNAL bool fiftyoneDegreesEvidenceIterateForHeaders( char* const buffer, size_t const length, void* state, - fiftyoneDegreesEvidenceIterateForHeadersMethod callback); + fiftyoneDegreesEvidenceIterateMethod callback); /** * @} diff --git a/fiftyone.h b/fiftyone.h index 92ec4a16..cf120ce5 100644 --- a/fiftyone.h +++ b/fiftyone.h @@ -287,6 +287,7 @@ MAP_TYPE(KeyValuePairArray) #define EvidenceCreate fiftyoneDegreesEvidenceCreate /**< Synonym for #fiftyoneDegreesEvidenceCreate function. */ #define EvidenceMapPrefix fiftyoneDegreesEvidenceMapPrefix /**< Synonym for #fiftyoneDegreesEvidenceMapPrefix function. */ #define EvidencePrefixString fiftyoneDegreesEvidencePrefixString /**< Synonym for #fiftyoneDegreesEvidencePrefixString function. */ +#define EvidenceAddPair fiftyoneDegreesEvidenceAddPair /**< Synonym for #fiftyoneDegreesEvidenceAddPair function. */ #define EvidenceAddString fiftyoneDegreesEvidenceAddString /**< Synonym for #fiftyoneDegreesEvidenceAddString function. */ #define PropertiesGetRequiredPropertyIndexFromName fiftyoneDegreesPropertiesGetRequiredPropertyIndexFromName /**< Synonym for #fiftyoneDegreesPropertiesGetRequiredPropertyIndexFromName function. */ #define PropertiesGetNameFromRequiredIndex fiftyoneDegreesPropertiesGetNameFromRequiredIndex /**< Synonym for #fiftyoneDegreesPropertiesGetNameFromRequiredIndex function. */ @@ -358,6 +359,7 @@ MAP_TYPE(KeyValuePairArray) #define StringBuilderAddChars fiftyoneDegreesStringBuilderAddChars /**< Synonym for fiftyoneDegreesStringBuilderAddChars */ #define StringBuilderComplete fiftyoneDegreesStringBuilderComplete /**< Synonym for fiftyoneDegreesStringBuilderComplete */ #define EvidenceIterateMethod fiftyoneDegreesEvidenceIterateMethod /**< Synonym for fiftyoneDegreesEvidenceIterateMethod */ +#define OverrideHasValueForRequiredPropertyIndex fiftyoneDegreesOverrideHasValueForRequiredPropertyIndex /**< Synonym for fiftyoneDegreesOverrideHasValueForRequiredPropertyIndex */ /* <-- only one asterisk to avoid inclusion in documentation * Shortened macros. diff --git a/headers.c b/headers.c index a02bfe70..dbaafc80 100644 --- a/headers.c +++ b/headers.c @@ -77,7 +77,7 @@ static void initHeaders(Headers* headers) { h->index = i; h->headerId = 0; h->isDataSet = false; - h->length = 0; + h->nameLength = 0; h->name = NULL; h->pseudoHeaders = NULL; h->segmentHeaders = NULL; @@ -181,7 +181,7 @@ static bool setHeaderName( return false; } name[length] = '\0'; - header->length = length; + header->nameLength = length; return true; } @@ -246,7 +246,7 @@ static Header* getHeader(Headers* headers, const char* name, size_t length) { Header* item; for (uint32_t i = 0; i < headers->count; i++) { item = &headers->items[i]; - if (item->length == length && + if (item->nameLength == length && StringCompareLength(name, item->name, length) == 0) { return item; } @@ -337,7 +337,7 @@ static Header* copyHeader( if (setHeaderName( copied, source->name, - source->length, + source->nameLength, exception) == false) { return NULL; } @@ -401,7 +401,7 @@ static bool addHeadersFromHeader( uint32_t start = 0; uint32_t end = 0; bool separatorEncountered = false; - for (;end < pseudoHeader->length; end++) { + for (;end < pseudoHeader->nameLength; end++) { // If a header has been found then either get the existing header with // this name, or add a new header. @@ -583,7 +583,7 @@ int fiftyoneDegreesHeaderGetIndex( // Perform a case insensitive compare of the remaining characters. for (i = 0; i < headers->count; i++) { header = &headers->items[i]; - if (header->length == length && + if (header->nameLength == length && StringCompareLength( httpHeaderName, header->name, diff --git a/headers.h b/headers.h index fe8bacd3..c3e22220 100644 --- a/headers.h +++ b/headers.h @@ -138,7 +138,7 @@ struct fiftyone_degrees_header_t { uint32_t index; /**< Index of the header in the array of all headers */ const char* name; /**< Name of the header or pseudo header field as a null terminated string */ - size_t length; /**< Length of the name string excluding the terminating + size_t nameLength; /**< Length of the name string excluding the terminating null */ fiftyoneDegreesHeaderID headerId; /**< Unique id in the data set for this full header */ @@ -183,13 +183,6 @@ typedef long(*fiftyoneDegreesHeadersGetMethod)( uint32_t index, fiftyoneDegreesCollectionItem *nameItem); -/** - * Check if a header is a pseudo header. - * @param headerName name of the header - * @return whether a header is a pseudo header. - */ -EXTERNAL bool fiftyoneDegreesHeadersIsPseudo(const char *headerName); - /** * Creates a new headers instance configured with the unique HTTP names needed * from evidence. If the useUpperPrefixedHeaders flag is true then checks for diff --git a/pair.h b/pair.h index bb6a4c55..c66c4baa 100644 --- a/pair.h +++ b/pair.h @@ -27,10 +27,10 @@ #include typedef struct fiftyone_degrees_key_value_pair_t { - char* key; - size_t keyLength; - char* value; - size_t valueLength; + const char* key; /**< pointer to the key string */ + size_t keyLength; /**< number of characters in key */ + const char* value; /**< pointer to the value string */ + size_t valueLength; /**< number of characters in value */ } fiftyoneDegreesKeyValuePair; FIFTYONE_DEGREES_ARRAY_TYPE(fiftyoneDegreesKeyValuePair, ) From 5a151ba89c81f2e7fae9e5cc46f0650053b8fd05 Mon Sep 17 00:00:00 2001 From: James Rosewell Date: Tue, 29 Oct 2024 10:12:08 +0000 Subject: [PATCH 3/6] REFACT: Removed the additional capacity feature. There is no need for this now that evidence can be expanded dynamically. --- EvidenceBase.cpp | 9 ++++----- EvidenceBase.hpp | 43 ++++++++++++++++--------------------------- 2 files changed, 20 insertions(+), 32 deletions(-) diff --git a/EvidenceBase.cpp b/EvidenceBase.cpp index 21bcf0c1..902b6539 100644 --- a/EvidenceBase.cpp +++ b/EvidenceBase.cpp @@ -26,7 +26,7 @@ using namespace FiftyoneDegrees::Common; -EvidenceBase::EvidenceBase(size_t additionalCapacity): additionalCapacity(additionalCapacity) { +EvidenceBase::EvidenceBase() { evidence = NULL; } @@ -42,13 +42,12 @@ fiftyoneDegreesEvidenceKeyValuePairArray* EvidenceBase::get() { EvidenceFree(evidence); evidence = NULL; } - // in case capacity has been provided as a hint - evidence = EvidenceCreate((uint32_t)(size() + additionalCapacity)); + evidence = EvidenceCreate((uint32_t)size()); if (evidence != NULL) { for (map::const_iterator iterator = begin(); iterator != end(); iterator++) { - EvidencePrefixMap *map = + EvidencePrefixMap* map = EvidenceMapPrefix(iterator->first.c_str()); if (map != NULL && isRelevant(map->prefixEnum)) { EvidenceAddString( @@ -89,4 +88,4 @@ void EvidenceBase::erase(iterator first, iterator last) { map::erase(first, last); EvidenceFree(evidence); evidence = NULL; -} +} \ No newline at end of file diff --git a/EvidenceBase.hpp b/EvidenceBase.hpp index c7a7f8f8..dad5cea6 100644 --- a/EvidenceBase.hpp +++ b/EvidenceBase.hpp @@ -65,27 +65,16 @@ namespace FiftyoneDegrees { * ``` */ class EvidenceBase : public map { - size_t additionalCapacity; public: /** * @name Constructors and Destructors * @{ */ - /** - * Construct a new instance containing no evidence. - * @param additionalCapacity - hint the additional capacity for the - * dynamically allocated evidence array structure, to allow - * derived evidence be added on the fly, when process() function is - * called on the evidence. - * The total capacity is the number of existing kv pairs plus this - * additional capacity. - * f.e. it may be necessary to expand 51d_gethighentropyvalues - * into sec-ch-ua headers, thus the additional capacity must be 6. - * If additional capacity is 0 - then the native evidence array will - * have the capacity matching the number of key value pairs. - */ - EvidenceBase(size_t additionalCapacity = 0); + /** + * Construct a new instance containing no evidence. + */ + EvidenceBase(); /** * Free all the underlying memory containing the evidence. @@ -98,12 +87,12 @@ namespace FiftyoneDegrees { * @{ */ - /** - * Get the underlying C structure containing the evidence. This - * only includes evidence which is relevant to the engine. Any - * evidence which is irrelevant will not be included in the result. - * @return pointer to a populated C evidence structure - */ + /** + * Get the underlying C structure containing the evidence. This + * only includes evidence which is relevant to the engine. Any + * evidence which is irrelevant will not be included in the result. + * @return pointer to a populated C evidence structure + */ fiftyoneDegreesEvidenceKeyValuePairArray* get(); /** @@ -112,9 +101,9 @@ namespace FiftyoneDegrees { * @{ */ - /** - * Clear all evidence items from the instance. - */ + /** + * Clear all evidence items from the instance. + */ void clear(); /** @@ -129,7 +118,7 @@ namespace FiftyoneDegrees { * @param last item to remove */ void erase(iterator first, iterator last); - + /** * @} */ @@ -144,9 +133,9 @@ namespace FiftyoneDegrees { virtual bool isRelevant(fiftyoneDegreesEvidencePrefix prefix); private: /** The underlying evidence structure. */ - fiftyoneDegreesEvidenceKeyValuePairArray *evidence; + fiftyoneDegreesEvidenceKeyValuePairArray* evidence; }; } } -#endif +#endif \ No newline at end of file From a83fdd492b255e45be4a79a9175e0142497f4dfc Mon Sep 17 00:00:00 2001 From: James Rosewell Date: Tue, 29 Oct 2024 10:12:54 +0000 Subject: [PATCH 4/6] REFACT: Modified tests and dependent classes to work with the refactered headers and evidence. --- overrides.c | 5 ++-- tests/EvidenceTests.cpp | 24 ++++++++--------- ...idenceWithHeadersTests_MultipleHeaders.cpp | 16 ++++++------ tests/EvidenceWithHeadersTests_NoHeaders.cpp | 8 +++--- .../EvidenceWithHeadersTests_SingleHeader.cpp | 16 ++++++------ tests/HeadersTests.cpp | 26 +++++++++---------- yamlfile.c | 15 +++++------ 7 files changed, 55 insertions(+), 55 deletions(-) diff --git a/overrides.c b/overrides.c index 75559292..ccef8e51 100644 --- a/overrides.c +++ b/overrides.c @@ -57,7 +57,8 @@ static void collectionRelease(Item *item) { * characters. Take 1 from the t to compare length. */ #define IS_HEADER_MATCH(t,p) \ - (StringCompareLength(skipPrefix(true, (char*)pair->field), t, sizeof(t)) == 0) + (StringCompareLength(\ + skipPrefix(true, (char*)pair->item.key), t, sizeof(t)) == 0) static const Collection dummyCollection = { NULL, @@ -183,7 +184,7 @@ static bool addOverrideToResults(void *state, EvidenceKeyValuePair *pair) { // Find the required property index, if any for the field. int requiredPropertyIndex = getRequiredPropertyIndexFromName( add->properties, - pair->field); + pair->item.key); return fiftyoneDegreesOverridesAdd( add->values, diff --git a/tests/EvidenceTests.cpp b/tests/EvidenceTests.cpp index 18b89857..45f783b8 100644 --- a/tests/EvidenceTests.cpp +++ b/tests/EvidenceTests.cpp @@ -30,10 +30,10 @@ void assertStringHeaderAdded( const char *expectedValue) { EXPECT_EQ((int)pair->prefix, (int)FIFTYONE_DEGREES_EVIDENCE_HTTP_HEADER_STRING) << L"Expected 'header' prefix."; - EXPECT_STREQ(pair->field, expectedField) << - L"Expected name '" << expectedField << "' not '" << pair->field << "'"; - EXPECT_TRUE(strcmp((const char*)pair->originalValue, expectedValue) == 0) << - L"Expected value '" << expectedValue << "' not '" << pair->originalValue << "'"; + EXPECT_STREQ(pair->item.key, expectedField) << + L"Expected name '" << expectedField << "' not '" << pair->item.key << "'"; + EXPECT_TRUE(strcmp((const char*)pair->item.value, expectedValue) == 0) << + L"Expected value '" << expectedValue << "' not '" << pair->item.value << "'"; } TEST_F(Evidence, Get_PrefixString) { @@ -99,9 +99,9 @@ TEST_F(Evidence, Add_MultipleStrings) #endif bool onMatchIterateString(void *state, fiftyoneDegreesEvidenceKeyValuePair *pair) { - if (strcmp((const char*)pair->field, "some-header-name") == 0) { - EXPECT_TRUE(strcmp((const char*)pair->originalValue, (const char*)pair->parsedValue) == 0) << - L"Expected parsed value to be '" << (const char*)pair->originalValue << "' not '" << + if (strcmp((const char*)pair->item.key, "some-header-name") == 0) { + EXPECT_TRUE(strcmp((const char*)pair->item.value, (const char*)pair->parsedValue) == 0) << + L"Expected parsed value to be '" << (const char*)pair->item.value << "' not '" << (const char*)pair->parsedValue << "'"; } return true; @@ -203,9 +203,9 @@ TEST_F(Evidence, Iterate_String_without_pseudo_evidence) { "Number of evidence should be 1\n"; } -bool callback1(void* state, fiftyoneDegreesHeader*, const char* value, size_t) { +bool callback1(void* state, fiftyoneDegreesEvidenceKeyValuePair* pair) { std::vector *results = (std::vector *) state; - results->push_back(value); + results->push_back(pair->item.value); return true; } @@ -361,9 +361,9 @@ TEST_F(Evidence, IterateForHeaders_ConstructPseudoHeader_Missing_or_Empty) { EXPECT_EQ(results[1], "\x1FGreen\x1F""Apple"); } -bool callback2(void* state, fiftyoneDegreesHeader* , const char* value, size_t ) { +bool callback2(void* state, fiftyoneDegreesEvidenceKeyValuePair *pair) { std::vector *results = (std::vector *) state; - results->push_back(value); + results->push_back(pair->item.value); return results->size() <= 1; // on the second header we signal early exit by returning false } @@ -388,7 +388,7 @@ TEST_F(Evidence, IterateForHeaders_CallbackSignalsEarlyExit) { EXPECT_EQ(results[1], "Big\x1FGreen"); } -bool callback_false(void* , fiftyoneDegreesHeader* , const char* , size_t ) { +bool callback_false(void*, fiftyoneDegreesEvidenceKeyValuePair*) { return false; } diff --git a/tests/EvidenceWithHeadersTests_MultipleHeaders.cpp b/tests/EvidenceWithHeadersTests_MultipleHeaders.cpp index 77233a9b..97c220b2 100644 --- a/tests/EvidenceWithHeadersTests_MultipleHeaders.cpp +++ b/tests/EvidenceWithHeadersTests_MultipleHeaders.cpp @@ -114,8 +114,8 @@ TEST_F(EvidenceWithHeadersTest_MultipleHeaders, Intersection_mh_se_sm) { evidenceHeaderIntersection_mh_se_sm); ASSERT_EQ(1, result); - ASSERT_STREQ("Black", intersection_mh_se_sm[0].field); - ASSERT_STREQ("Value", (char*)intersection_mh_se_sm[0].originalValue); + ASSERT_STREQ("Black", intersection_mh_se_sm[0].item.key); + ASSERT_STREQ("Value", (char*)intersection_mh_se_sm[0].item.value); } @@ -160,10 +160,10 @@ TEST_F(EvidenceWithHeadersTest_MultipleHeaders, Intersection_mh_me_mm) { evidenceHeaderIntersection_mh_me_mm); ASSERT_EQ(2, result); - EXPECT_STREQ("Black", intersection_mh_me_mm[0].field); - EXPECT_STREQ("Value", (char*)intersection_mh_me_mm[0].originalValue); - EXPECT_STREQ("Red", intersection_mh_me_mm[1].field); - EXPECT_STREQ("Value2", (char*)intersection_mh_me_mm[1].originalValue); + EXPECT_STREQ("Black", intersection_mh_me_mm[0].item.key); + EXPECT_STREQ("Value", (char*)intersection_mh_me_mm[0].item.value); + EXPECT_STREQ("Red", intersection_mh_me_mm[1].item.key); + EXPECT_STREQ("Value2", (char*)intersection_mh_me_mm[1].item.value); } //------------------------------------------------------------------ @@ -177,8 +177,8 @@ bool evidenceHeaderIntersection_mh_me_nm(void *state, fiftyoneDegreesEvidenceKeyValuePair *pair) { if (fiftyoneDegreesHeaderGetIndex( (fiftyoneDegreesHeaders*)state, - pair->field, - strlen(pair->field)) >= 0) { + pair->item.key, + pair->item.keyLength) >= 0) { intersection_mh_me_nm[intersection_mh_me_nm_count] = *pair; intersection_mh_me_nm_count++; } diff --git a/tests/EvidenceWithHeadersTests_NoHeaders.cpp b/tests/EvidenceWithHeadersTests_NoHeaders.cpp index 3f8e16bc..44729763 100644 --- a/tests/EvidenceWithHeadersTests_NoHeaders.cpp +++ b/tests/EvidenceWithHeadersTests_NoHeaders.cpp @@ -81,8 +81,8 @@ bool evidenceHeaderIntersection_nh_se_nm(void *state, fiftyoneDegreesEvidenceKeyValuePair *pair) { if (fiftyoneDegreesHeaderGetIndex( (fiftyoneDegreesHeaders*)state, - pair->field, - strlen(pair->field)) >= 0) { + pair->item.key, + pair->item.keyLength) >= 0) { intersection_nh_se_nm[intersection_nh_se_nm_count] = *pair; intersection_nh_se_nm_count++; } @@ -118,8 +118,8 @@ bool evidenceHeaderIntersection_nh_me_mm(void *state, fiftyoneDegreesEvidenceKeyValuePair *pair) { if (fiftyoneDegreesHeaderGetIndex( (fiftyoneDegreesHeaders*)state, - pair->field, - strlen(pair->field)) >= 0) { + pair->item.key, + pair->item.keyLength) >= 0) { intersection_nh_me_nm[intersection_multiple_nh_me_mm_count] = *pair; intersection_multiple_nh_me_mm_count++; } diff --git a/tests/EvidenceWithHeadersTests_SingleHeader.cpp b/tests/EvidenceWithHeadersTests_SingleHeader.cpp index f34376ae..a706d02d 100644 --- a/tests/EvidenceWithHeadersTests_SingleHeader.cpp +++ b/tests/EvidenceWithHeadersTests_SingleHeader.cpp @@ -111,8 +111,8 @@ TEST_F(EvidenceWithHeadersTest_SingleHeader, Intersection_sh_se_sm) { evidenceHeaderIntersection_sh_se_sm); ASSERT_EQ(1, result); - ASSERT_STREQ("Red", intersection_sh_se_sm[0].field); - ASSERT_STREQ("Value", (char*)intersection_sh_se_sm[0].originalValue); + ASSERT_STREQ("Red", intersection_sh_se_sm[0].item.key); + ASSERT_STREQ("Value", (char*)intersection_sh_se_sm[0].item.value); } @@ -130,8 +130,8 @@ bool evidenceHeaderIntersection_sh_me_mm(void *state, fiftyoneDegreesEvidenceKeyValuePair *pair) { if (fiftyoneDegreesHeaderGetIndex( (fiftyoneDegreesHeaders*)state, - pair->field, - strlen(pair->field)) >= 0) { + pair->item.key, + pair->item.keyLength) >= 0) { intersection_sh_me_sm[intersection_multiple_sh_me_mm_count] = *pair; intersection_multiple_sh_me_mm_count++; } @@ -162,8 +162,8 @@ TEST_F(EvidenceWithHeadersTest_SingleHeader, Intersection_sh_me_sm) { ASSERT_EQ(2, result); ASSERT_EQ(1, intersection_multiple_sh_me_mm_count); - EXPECT_STREQ("Red", intersection_sh_me_sm[0].field); - EXPECT_STREQ("Value2", (char*)intersection_sh_me_sm[0].originalValue); + EXPECT_STREQ("Red", intersection_sh_me_sm[0].item.key); + EXPECT_STREQ("Value2", (char*)intersection_sh_me_sm[0].item.value); } //------------------------------------------------------------------ @@ -181,8 +181,8 @@ bool evidenceHeaderIntersection_sh_me_nm(void *state, fiftyoneDegreesEvidenceKeyValuePair *pair) { if (fiftyoneDegreesHeaderGetIndex( (fiftyoneDegreesHeaders*)state, - pair->field, - strlen(pair->field)) >= 0) { + pair->item.key, + pair->item.keyLength) >= 0) { intersection_sh_me_nm[intersection_sh_me_nm_count] = *pair; intersection_sh_me_nm_count++; } diff --git a/tests/HeadersTests.cpp b/tests/HeadersTests.cpp index 41644c85..7601bfba 100644 --- a/tests/HeadersTests.cpp +++ b/tests/HeadersTests.cpp @@ -371,8 +371,8 @@ TEST_F(HeadersTests, PseudoHeadersPositive) { EXPECT_STREQ("header1\x1Fheader2", headers->items[3].name); EXPECT_EQ(2, headers->items[3].segmentHeaders->count); - EXPECT_EQ(7, headers->items[3].segmentHeaders->items[0]->length); - EXPECT_EQ(7, headers->items[3].segmentHeaders->items[1]->length); + EXPECT_EQ(7, headers->items[3].segmentHeaders->items[0]->nameLength); + EXPECT_EQ(7, headers->items[3].segmentHeaders->items[1]->nameLength); EXPECT_EQ(0, StringCompareLength( "header1", headers->items[3].segmentHeaders->items[0]->name, @@ -387,8 +387,8 @@ TEST_F(HeadersTests, PseudoHeadersPositive) { EXPECT_STREQ("header2\x1Fheader3", headers->items[4].name); EXPECT_EQ(2, headers->items[4].segmentHeaders->count); - EXPECT_EQ(7, headers->items[4].segmentHeaders->items[0]->length); - EXPECT_EQ(7, headers->items[4].segmentHeaders->items[1]->length); + EXPECT_EQ(7, headers->items[4].segmentHeaders->items[0]->nameLength); + EXPECT_EQ(7, headers->items[4].segmentHeaders->items[1]->nameLength); EXPECT_EQ(0, StringCompareLength( "header2", headers->items[4].segmentHeaders->items[0]->name, @@ -403,9 +403,9 @@ TEST_F(HeadersTests, PseudoHeadersPositive) { EXPECT_STREQ("header1\x1Fheader2\x1Fheader3", headers->items[5].name); EXPECT_EQ(3, headers->items[5].segmentHeaders->count); - EXPECT_EQ(7, headers->items[5].segmentHeaders->items[0]->length); - EXPECT_EQ(7, headers->items[5].segmentHeaders->items[1]->length); - EXPECT_EQ(7, headers->items[5].segmentHeaders->items[2]->length); + EXPECT_EQ(7, headers->items[5].segmentHeaders->items[0]->nameLength); + EXPECT_EQ(7, headers->items[5].segmentHeaders->items[1]->nameLength); + EXPECT_EQ(7, headers->items[5].segmentHeaders->items[2]->nameLength); EXPECT_EQ(0, StringCompareLength( "header1", @@ -445,11 +445,11 @@ TEST_F(HeadersTests, PseudoHeadersMissing) { EXPECT_STREQ("header1\x1Fheader2", headers->items[0].name); EXPECT_EQ(true, headers->items[0].isDataSet); EXPECT_EQ(2, headers->items[0].segmentHeaders->count); - EXPECT_EQ(7, headers->items[0].segmentHeaders->items[0]->length); + EXPECT_EQ(7, headers->items[0].segmentHeaders->items[0]->nameLength); EXPECT_EQ(1, headers->items[0].segmentHeaders->items[0]->pseudoHeaders->count); EXPECT_EQ(&headers->items[0], headers->items[0].segmentHeaders->items[0]->pseudoHeaders->items[0]); - EXPECT_EQ(7, headers->items[0].segmentHeaders->items[1]->length); + EXPECT_EQ(7, headers->items[0].segmentHeaders->items[1]->nameLength); EXPECT_EQ(1, headers->items[0].segmentHeaders->items[1]->pseudoHeaders->count); EXPECT_EQ(&headers->items[0], headers->items[0].segmentHeaders->items[1]->pseudoHeaders->items[0]); @@ -510,7 +510,7 @@ TEST_F(HeadersTests, PseudoHeadersSpecialCases) { EXPECT_STREQ("\x1Fheader1", headers->items[2].name); EXPECT_EQ(1, headers->items[2].segmentHeaders->count); - EXPECT_EQ(7, headers->items[2].segmentHeaders->items[0]->length); + EXPECT_EQ(7, headers->items[2].segmentHeaders->items[0]->nameLength); EXPECT_EQ(0, StringCompareLength( "header1", headers->items[2].segmentHeaders->items[0]->name, @@ -522,7 +522,7 @@ TEST_F(HeadersTests, PseudoHeadersSpecialCases) { EXPECT_STREQ("header1\x1F", headers->items[3].name); EXPECT_EQ(1, headers->items[3].segmentHeaders->count); - EXPECT_EQ(7, headers->items[3].segmentHeaders->items[0]->length); + EXPECT_EQ(7, headers->items[3].segmentHeaders->items[0]->nameLength); EXPECT_EQ(0, StringCompareLength( "header1", headers->items[3].segmentHeaders->items[0]->name, @@ -534,8 +534,8 @@ TEST_F(HeadersTests, PseudoHeadersSpecialCases) { EXPECT_STREQ("header1\x1F\x1Fheader2", headers->items[4].name); EXPECT_EQ(2, headers->items[4].segmentHeaders->count); - EXPECT_EQ(7, headers->items[4].segmentHeaders->items[0]->length); - EXPECT_EQ(7, headers->items[4].segmentHeaders->items[1]->length); + EXPECT_EQ(7, headers->items[4].segmentHeaders->items[0]->nameLength); + EXPECT_EQ(7, headers->items[4].segmentHeaders->items[1]->nameLength); EXPECT_EQ(0, StringCompareLength( "header1", headers->items[4].segmentHeaders->items[0]->name, diff --git a/yamlfile.c b/yamlfile.c index 0fc5bae0..cfae8be9 100644 --- a/yamlfile.c +++ b/yamlfile.c @@ -85,15 +85,15 @@ static char* readNext(FileState* fileState) { // Sets the current and end pointers to the current key. static void setCurrentKey(PairState* state) { KeyValuePair* current = state->pairs + state->index; - state->current = current->key; - state->end = current->key + current->keyLength - 1; + state->current = (char*)current->key; + state->end = (char*)(current->key + current->keyLength - 1); } // Sets the current and end pointers to the current value. static void setCurrentValue(PairState* state) { KeyValuePair* current = state->pairs + state->index; - state->current = current->value; - state->end = current->value + current->valueLength - 1; + state->current = (char*)current->value; + state->end = (char*)current->value + current->valueLength - 1; } // Switches from writing to the current key to the current value. Ensures that @@ -185,8 +185,8 @@ StatusCode fiftyoneDegreesYamlFileIterateWithLimit( keyValuePairs, collectionSize, 0, - keyValuePairs[0].key, - keyValuePairs[0].key + keyValuePairs[0].keyLength - 1 }; + (char*)keyValuePairs[0].key, + (char*)(keyValuePairs[0].key + keyValuePairs[0].keyLength - 1) }; // If there is no limit then set the limit to the largest value to // avoid checking for negative values in the loop. @@ -301,6 +301,5 @@ StatusCode fiftyoneDegreesYamlFileIterate( collectionSize, -1, state, - callback - ); + callback); } \ No newline at end of file From 071b5a7e6fc5c181ebbd1a1e33ca0a00bdc944a2 Mon Sep 17 00:00:00 2001 From: Eugene Dorfman Date: Tue, 29 Oct 2024 12:17:48 +0100 Subject: [PATCH 5/6] FIX: handle freeing NULL evidence --- evidence.c | 3 +++ tests/EvidenceTests.cpp | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/evidence.c b/evidence.c index 771e00c4..ca415233 100644 --- a/evidence.c +++ b/evidence.c @@ -292,6 +292,9 @@ fiftyoneDegreesEvidenceCreate(uint32_t capacity) { void fiftyoneDegreesEvidenceFree( fiftyoneDegreesEvidenceKeyValuePairArray *evidence) { + if (evidence == NULL) { + return; + } EvidenceKeyValuePairArray* current = evidence; while (current->next != NULL) { current = current->next; diff --git a/tests/EvidenceTests.cpp b/tests/EvidenceTests.cpp index 45f783b8..4bc4c083 100644 --- a/tests/EvidenceTests.cpp +++ b/tests/EvidenceTests.cpp @@ -438,4 +438,7 @@ TEST_F(Evidence, IterateForHeaders_SmallBuffer) { fiftyoneDegreesFree(buf); } - +TEST_F(Evidence, freeNullEvidence) { + fiftyoneDegreesEvidenceKeyValuePairArray *evidence = NULL; + EvidenceFree(evidence); +} From 54d8c7f8ac87ddf32f88074e3ddbc1139738ec63 Mon Sep 17 00:00:00 2001 From: Eugene Dorfman Date: Wed, 30 Oct 2024 13:19:05 +0100 Subject: [PATCH 6/6] FIX: warning on windows --- tests/EvidenceTests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/EvidenceTests.cpp b/tests/EvidenceTests.cpp index 4bc4c083..f1fa9697 100644 --- a/tests/EvidenceTests.cpp +++ b/tests/EvidenceTests.cpp @@ -439,6 +439,6 @@ TEST_F(Evidence, IterateForHeaders_SmallBuffer) { } TEST_F(Evidence, freeNullEvidence) { - fiftyoneDegreesEvidenceKeyValuePairArray *evidence = NULL; - EvidenceFree(evidence); + fiftyoneDegreesEvidenceKeyValuePairArray *evidence2 = NULL; + EvidenceFree(evidence2); }