diff --git a/system/jlib/jstring.cpp b/system/jlib/jstring.cpp index 6e062d2938e..4048c887d4f 100644 --- a/system/jlib/jstring.cpp +++ b/system/jlib/jstring.cpp @@ -2869,36 +2869,24 @@ const char * stristr (const char *haystack, const char *needle) if (isEmptyString(haystack) || isEmptyString(needle)) return nullptr; - const char *pptr = needle; /* Pattern to search for */ - const char *start = haystack; /* Start with a bowl of hay */ - const char *sptr; /* Substring pointer */ - int slen = strlen(haystack); /* Total size of haystack */ - int plen = strlen(needle); /* Length of our needle */ - - /* while string length not shorter than pattern length */ - for (; slen >= plen; start++, slen--) + const char * start = haystack; + size_t slen = strlen(haystack); /* Total size of haystack */ + size_t nlen = strlen(needle); /* Length of our needle */ + char needle0 = tolower(*needle); + for (; slen >= nlen; start++, slen--) { - /* find start of pattern in string */ - while (tolower(*start) != tolower(*needle)) - { - start++; - slen--; - /* if pattern longer than string */ - if (slen < plen) - return nullptr; - } - - sptr = start; - pptr = (char *) needle; - while (tolower(*sptr) == tolower(*pptr)) + if (tolower(*start) == needle0) { - sptr++; - pptr++; - /* if end of pattern then pattern was found */ - if (!*pptr) - return start; + size_t i = 1; + for (;;) + { + if (i == nlen) + return start; + if (tolower(start[i]) != tolower(needle[i])) + break; + i++; + } } } - return nullptr; } diff --git a/testing/unittests/jlibtests.cpp b/testing/unittests/jlibtests.cpp index 9918b77c5ef..6aeb3e11f36 100644 --- a/testing/unittests/jlibtests.cpp +++ b/testing/unittests/jlibtests.cpp @@ -38,7 +38,7 @@ #include "unittests.hpp" -#define CPPUNIT_ASSERT_EQUAL_STR(x, y) CPPUNIT_ASSERT_EQUAL(std::string(x),std::string(y)) +#define CPPUNIT_ASSERT_EQUAL_STR(x, y) CPPUNIT_ASSERT_EQUAL(std::string(x ? x : ""),std::string(y ? y : "")) static const unsigned oneMinute = 60000; // msec @@ -3830,4 +3830,31 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( JLibSecretsTest, "JLibSecretsTest" ); +class JLibStringTest : public CppUnit::TestFixture +{ +public: + CPPUNIT_TEST_SUITE(JLibStringTest); + CPPUNIT_TEST(testStristr); + CPPUNIT_TEST_SUITE_END(); + + void testStristr() + { + CPPUNIT_ASSERT_EQUAL_STR(stristr("abc", "abc"), "abc"); + CPPUNIT_ASSERT_EQUAL_STR(stristr("abc", "ABC"), "abc"); + CPPUNIT_ASSERT_EQUAL_STR(stristr("x", "ABC"), ""); + CPPUNIT_ASSERT_EQUAL_STR(stristr("abcdefgh", "A"), "abcdefgh"); + CPPUNIT_ASSERT_EQUAL_STR(stristr("ABCDEFGH", "a"), "ABCDEFGH"); + CPPUNIT_ASSERT_EQUAL_STR(stristr("abcdefgh", "E"), "efgh"); + CPPUNIT_ASSERT_EQUAL_STR(stristr("ABCDEFGH", "e"), "EFGH"); + CPPUNIT_ASSERT_EQUAL_STR(stristr("abcdefgh", "FGH"), "fgh"); + CPPUNIT_ASSERT_EQUAL_STR(stristr("aabcdefgh", "ABC"), "abcdefgh"); + CPPUNIT_ASSERT_EQUAL_STR(stristr("ababacz", "ABAC"), "abacz"); + CPPUNIT_ASSERT_EQUAL_STR(stristr("", "ABC"), ""); + CPPUNIT_ASSERT_EQUAL_STR(stristr("ABC", ""), ""); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION( JLibStringTest ); +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( JLibStringTest, "JLibStringTest" ); + #endif // _USE_CPPUNIT