mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-05-05 16:30:17 +10:00
FIX: Substrings had corner-cases with incorrect results, read more
I found this while writing unit tests for Toy_Function, where one (native) function was named 'identity' and another (custom) was named 'ident' to avoid a naming clash. The rename didn't resolve the clash, so after some digging, I found that strings compared to substrings would return a match, despite being different. This took some awkward corner-case handling, as it turns out 'deepCompareUtil' only returns zero when no differences have been found, not when a match has been found. I also added checks for this to Toy_String's unit test, with the parameters checked in both orders i.e. (a,b) and (b,a), because paranoia is your friend. The rope pattern is powerful, but also gives you enough rope to hang yourself.
This commit is contained in:
+18
-4
@@ -193,13 +193,13 @@ static int deepCompareUtil(Toy_String* left, Toy_String* right, const char** lef
|
||||
(*rightHead)++;
|
||||
}
|
||||
|
||||
//if both are not null, then it's a real result
|
||||
if ( (**leftHead == '\0' || **rightHead == '\0') == false) {
|
||||
//if there's a difference, and neither is null, than a result has (probably) been found
|
||||
if ((**leftHead != '\0' && **rightHead != '\0' && (**leftHead != **rightHead))) {
|
||||
result = *(const unsigned char*)(*leftHead) - *(const unsigned char*)(*rightHead);
|
||||
}
|
||||
}
|
||||
|
||||
//if either are a null character, return 0 to check the next node
|
||||
//returning 0 means no difference found yet
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -209,11 +209,25 @@ int Toy_compareStrings(Toy_String* left, Toy_String* right) {
|
||||
return left->info.length - right->info.length;
|
||||
}
|
||||
|
||||
//BUGFIX: If both args are leaves, and one is a substring of the other, then deepCompareUtil() will return a wrong result
|
||||
if (left->info.type == TOY_STRING_LEAF && right->info.type == TOY_STRING_LEAF) {
|
||||
unsigned int maxLength = left->info.length > right->info.length ? left->info.length : right->info.length;
|
||||
return strncmp(left->leaf.data, right->leaf.data, maxLength);
|
||||
}
|
||||
|
||||
//util pointers
|
||||
const char* leftHead = NULL;
|
||||
const char* rightHead = NULL;
|
||||
|
||||
return deepCompareUtil(left, right, &leftHead, &rightHead);
|
||||
int result = deepCompareUtil(left, right, &leftHead, &rightHead);
|
||||
|
||||
//BUGFIX: deepCompareUtil() doesn't handle substrings correctly
|
||||
if (result == 0 && leftHead != NULL && rightHead != NULL) {
|
||||
return (int)(*leftHead - *rightHead);
|
||||
}
|
||||
else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int hashCString(const char* string) {
|
||||
|
||||
Reference in New Issue
Block a user