Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HPCC-32795 Additional optimizations to replaceString #19239

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
24 changes: 19 additions & 5 deletions system/jlib/jstring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1056,13 +1056,27 @@ StringBuffer &replaceStringNoCase(StringBuffer & result, size_t lenSource, const
// this method will replace all occurrences of "oldStr" with "newStr"
StringBuffer & StringBuffer::replaceString(const char* oldStr, const char* newStr)
{
if (curLen)
if (curLen && oldStr)
{
StringBuffer temp;
size_t oldlen = oldStr ? strlen(oldStr) : 0;
size_t oldlen = strlen(oldStr);
if (oldlen > curLen)
return *this;

size_t newlen = newStr ? strlen(newStr) : 0;
::replaceString(temp, curLen, buffer, oldlen, oldStr, newlen, newStr);
swapWith(temp);
if (oldlen == curLen)
{
if (memcmp(buffer, oldStr, oldlen) == 0)
{
memcpy(buffer, newStr, newlen);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I was reviewing this code (I am not because of general review comments) - this has a serious memory corruption if newlen > oldlen

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. I added ensureCapacity(newlen).

curLen = newlen;
}
}
else
{
StringBuffer temp;
::replaceString(temp, curLen, buffer, oldlen, oldStr, newlen, newStr);
swapWith(temp);
}
}
return *this;
}
Expand Down
10 changes: 10 additions & 0 deletions testing/unittests/jlibtests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -913,6 +913,16 @@ void testEncodeCSVColumn()
source.set("abbabab");
source.replaceString("ab", "xxx");
CPPUNIT_ASSERT_EQUAL_STR("xxxbxxxxxx", source.str());

// Search String has same length as source string and matches
source.set("ababab");
source.replaceString("ababab", "xxxxxx");
CPPUNIT_ASSERT_EQUAL_STR("xxxxxx", source.str());

// Search String has same length as source string and does not match
source.set("ababab");
source.replaceString("ababac", "xxxxxx");
CPPUNIT_ASSERT_EQUAL_STR("ababab", source.str());
}
};

Expand Down
Loading