Fixed bug in multiCompare, which fixes ticket #66 ([False positive] "Buffer overrun" with "--all")

This commit is contained in:
Reijo Tomperi 2009-01-27 19:30:01 +00:00
parent 8cd2979468
commit 64e3250f00
3 changed files with 47 additions and 27 deletions

View File

@ -111,50 +111,68 @@ const char *Token::strAt(int index) const
return tok ? tok->_cstr : ""; return tok ? tok->_cstr : "";
} }
int Token::multiCompare(const char *needle, const char *haystack) int Token::multiCompare(const char *haystack, const char *needle)
{ {
bool emptyStringFound = false; bool emptyStringFound = false;
bool findNextOr = false; bool noMatch = false;
const char *haystackPointer = haystack; const char *needlePointer = needle;
for (; *needle; ++needle) for (; *haystack; ++haystack)
{ {
if (*needle == '|') if (*haystack == '|')
{
if (noMatch)
{
// We didn't have a match at this round
noMatch = false;
}
else if (*needlePointer == 0)
{ {
// If needle and haystack are both at the end, we have a match. // If needle and haystack are both at the end, we have a match.
if (*haystackPointer == 0)
return 1; return 1;
}
haystackPointer = haystack; else if (needlePointer == needle)
if (findNextOr) {
findNextOr = false; // If needlePointer was not increased at all, we had a empty
else // string in the haystack
emptyStringFound = true; emptyStringFound = true;
}
needlePointer = needle;
continue; continue;
} }
if (findNextOr) if (noMatch)
continue; continue;
// If haystack and needle don't share the same character, reset // If haystack and needle don't share the same character,
// haystackpointer and find next '|' character. // find next '|' character.
if (*haystackPointer != *needle) if (*needlePointer != *haystack)
{ {
haystackPointer = haystack; noMatch = true;
findNextOr = true;
continue; continue;
} }
// All characters in haystack and needle have matched this far // All characters in haystack and needle have matched this far
++haystackPointer; ++needlePointer;
} }
// If both needle and haystack are at the end, then we have a match.
if (*haystackPointer == 0)
return 1;
// If empty string was found or if last character in needle was '|' if (!noMatch)
if (emptyStringFound || findNextOr == false) {
if (*needlePointer == 0)
{
// If both needle and haystack are at the end, then we have a match.
return 1;
}
else if (needlePointer == needle)
{
// Last string in haystack was empty string e.g. "one|two|"
return 0;
}
}
// If empty string was found earlier from the haystack
if (emptyStringFound)
return 0; return 0;
return -1; return -1;

View File

@ -128,13 +128,13 @@ public:
* string, return value is 0. If needle was not found, return * string, return value is 0. If needle was not found, return
* value is -1. * value is -1.
* *
* @param needle e.g. "one|two" or "|one|two" * @param haystack e.g. "one|two" or "|one|two"
* @param haystack e.g. "one", "two" or "invalid" * @param needle e.g. "one", "two" or "invalid"
* @return 1 if needle is found from the haystack * @return 1 if needle is found from the haystack
* 0 if needle was empty string * 0 if needle was empty string
* -1 if needle was not found * -1 if needle was not found
*/ */
static int multiCompare(const char *needle, const char *haystack); static int multiCompare(const char *haystack, const char *needle);
unsigned int linenr() const; unsigned int linenr() const;

View File

@ -464,6 +464,8 @@ private:
ASSERT_EQUALS(-1, Token::multiCompare("verybig|two", "s")); ASSERT_EQUALS(-1, Token::multiCompare("verybig|two", "s"));
ASSERT_EQUALS(-1, Token::multiCompare("one|two", "ne")); ASSERT_EQUALS(-1, Token::multiCompare("one|two", "ne"));
ASSERT_EQUALS(-1, Token::multiCompare("abc|def", "a")); ASSERT_EQUALS(-1, Token::multiCompare("abc|def", "a"));
ASSERT_EQUALS(-1, Token::multiCompare("abc|def", "abcd"));
ASSERT_EQUALS(-1, Token::multiCompare("abc|def", "default"));
} }
void match1() void match1()