diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/MemoryManagerSuite.cpp | 175 | ||||
-rw-r--r-- | test/test.cpp | 76 |
2 files changed, 194 insertions, 57 deletions
diff --git a/test/MemoryManagerSuite.cpp b/test/MemoryManagerSuite.cpp index a828d76..e4af977 100644 --- a/test/MemoryManagerSuite.cpp +++ b/test/MemoryManagerSuite.cpp @@ -36,76 +36,99 @@ extern "C" { namespace { -class CallCountLog { -public: - unsigned int callCountFree; - CallCountLog() : callCountFree(0) { - // no-op - } -}; +static void * failingMalloc(UriMemoryManager * memory, size_t size); +static void * failingCalloc(UriMemoryManager * memory, size_t nmemb, size_t size); +static void * failingRealloc(UriMemoryManager * memory, void * ptr, size_t size); +static void * failingReallocarray(UriMemoryManager * memory, void * ptr, size_t nmemb, size_t size); +static void countingFree(UriMemoryManager * memory, void * ptr); -static void * failingMalloc(UriMemoryManager * URI_UNUSED(memory), - size_t URI_UNUSED(size)) { - return NULL; -} +class FailingMemoryManager { +private: + UriMemoryManager memoryManager; + unsigned int callCountAlloc; + unsigned int callCountFree; + unsigned int failAllocAfterTimes; + friend void * failingMalloc(UriMemoryManager * memory, size_t size); + friend void * failingCalloc(UriMemoryManager * memory, size_t nmemb, size_t size); + friend void * failingRealloc(UriMemoryManager * memory, void * ptr, size_t size); + friend void * failingReallocarray(UriMemoryManager * memory, void * ptr, size_t nmemb, size_t size); + friend void countingFree(UriMemoryManager * memory, void * ptr); -static void * failingCalloc(UriMemoryManager * URI_UNUSED(memory), - size_t URI_UNUSED(nmemb), size_t URI_UNUSED(size)) { - return NULL; -} +public: + FailingMemoryManager(unsigned int failAllocAfterTimes = 0) + : callCountAlloc(0), callCountFree(0), + failAllocAfterTimes(failAllocAfterTimes) { + this->memoryManager.malloc = failingMalloc; + this->memoryManager.calloc = failingCalloc; + this->memoryManager.realloc = failingRealloc; + this->memoryManager.reallocarray = failingReallocarray; + this->memoryManager.free = countingFree; + this->memoryManager.userData = this; + } + UriMemoryManager * operator&() { + return &(this->memoryManager); + } + unsigned int getCallCountFree() const { + return this->callCountFree; + } +}; -static void * failingRealloc(UriMemoryManager * URI_UNUSED(memory), - void * URI_UNUSED(ptr), size_t URI_UNUSED(size)) { - return NULL; + + +static void * failingMalloc(UriMemoryManager * memory, size_t size) { + FailingMemoryManager * const fmm = static_cast<FailingMemoryManager *>(memory->userData); + fmm->callCountAlloc++; + if (fmm->callCountAlloc > fmm->failAllocAfterTimes) { + errno = ENOMEM; + return NULL; + } + return malloc(size); } -static void * failingReallocarray(UriMemoryManager * URI_UNUSED(memory), - void * URI_UNUSED(ptr), size_t URI_UNUSED(nmemb), - size_t URI_UNUSED(size)) { - return NULL; +static void * failingCalloc(UriMemoryManager * memory, size_t nmemb, size_t size) { + FailingMemoryManager * const fmm = static_cast<FailingMemoryManager *>(memory->userData); + fmm->callCountAlloc++; + if (fmm->callCountAlloc > fmm->failAllocAfterTimes) { + errno = ENOMEM; + return NULL; + } + return calloc(nmemb, size); } -static void countingFree(UriMemoryManager * memory, void * ptr) { - static_cast<CallCountLog *>(memory->userData)->callCountFree++; - free(ptr); +static void * failingRealloc(UriMemoryManager * memory, void * ptr, size_t size) { + FailingMemoryManager * const fmm = static_cast<FailingMemoryManager *>(memory->userData); + fmm->callCountAlloc++; + if (fmm->callCountAlloc > fmm->failAllocAfterTimes) { + errno = ENOMEM; + return NULL; + } + return realloc(ptr, size); } -class FailingMemoryManager { -private: - UriMemoryManager memoryManager; - CallCountLog callCountLog; +static void * failingReallocarray(UriMemoryManager * memory, void * ptr, size_t nmemb, size_t size) { + return uriEmulateReallocarray(memory, ptr, nmemb, size); +} -public: - FailingMemoryManager() { - this->memoryManager.malloc = failingMalloc; - this->memoryManager.calloc = failingCalloc; - this->memoryManager.realloc = failingRealloc; - this->memoryManager.reallocarray = failingReallocarray; - this->memoryManager.free = countingFree; - this->memoryManager.userData = &(this->callCountLog); - } - UriMemoryManager * operator&() { - return &(this->memoryManager); - } - unsigned int getCallCountFree() const { - return this->callCountLog.callCountFree; - } -}; +static void countingFree(UriMemoryManager * memory, void * ptr) { + FailingMemoryManager * const fmm = static_cast<FailingMemoryManager *>(memory->userData); + fmm->callCountFree++; + return free(ptr); +} @@ -318,11 +341,11 @@ TEST(FailingMemoryManagerSuite, DissectQueryMallocExMm) { TEST(FailingMemoryManagerSuite, FreeQueryListMm) { UriQueryListA * const queryList = parseQueryList("k1=v1"); FailingMemoryManager failingMemoryManager; - ASSERT_EQ(failingMemoryManager.getCallCountFree(), 0); + ASSERT_EQ(failingMemoryManager.getCallCountFree(), 0U); uriFreeQueryListMmA(queryList, &failingMemoryManager); - ASSERT_GE(failingMemoryManager.getCallCountFree(), 1); + ASSERT_GE(failingMemoryManager.getCallCountFree(), 1U); } @@ -330,25 +353,65 @@ TEST(FailingMemoryManagerSuite, FreeQueryListMm) { TEST(FailingMemoryManagerSuite, FreeUriMembersMm) { UriUriA uri = parse("http://example.org/"); FailingMemoryManager failingMemoryManager; - ASSERT_EQ(failingMemoryManager.getCallCountFree(), 0); + ASSERT_EQ(failingMemoryManager.getCallCountFree(), 0U); uriFreeUriMembersMmA(&uri, &failingMemoryManager); - ASSERT_GE(failingMemoryManager.getCallCountFree(), 1); + ASSERT_GE(failingMemoryManager.getCallCountFree(), 1U); uriFreeUriMembersA(&uri); } +namespace { + void testNormalizeSyntaxWithFailingMallocCallsFreeTimes(const char * uriString, + unsigned int mask, + unsigned int failAllocAfterTimes = 0, + unsigned int expectedCallCountFree = 0) { + UriUriA uri = parse(uriString); + FailingMemoryManager failingMemoryManager(failAllocAfterTimes); + ASSERT_EQ(uriNormalizeSyntaxExMmA(&uri, mask, &failingMemoryManager), + URI_ERROR_MALLOC); -TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMm) { - UriUriA uri = parse("hTTp://example.org/path"); - const unsigned int mask = URI_NORMALIZE_SCHEME; // anything but URI_NORMALIZED - FailingMemoryManager failingMemoryManager; + EXPECT_EQ(failingMemoryManager.getCallCountFree(), expectedCallCountFree); - ASSERT_EQ(uriNormalizeSyntaxExMmA(&uri, mask, &failingMemoryManager), - URI_ERROR_MALLOC); + uriFreeUriMembersA(&uri); + } +} // namespace - uriFreeUriMembersA(&uri); +TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmScheme) { + testNormalizeSyntaxWithFailingMallocCallsFreeTimes("hTTp://example.org/path", URI_NORMALIZE_SCHEME); +} + +TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmEmptyUserInfo) { + testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//@:123", URI_NORMALIZE_USER_INFO); +} + +TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmEmptyHostRegname) { + testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//:123", URI_NORMALIZE_HOST); +} + +TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmEmptyQuery) { + testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//:123?", URI_NORMALIZE_QUERY); +} + +TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmEmptyFragment) { + testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//:123#", URI_NORMALIZE_FRAGMENT); +} + +TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmHostTextIp4) { // issue #121 + testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//192.0.2.0:123" /* RFC 5737 */, URI_NORMALIZE_HOST, 1, 1); +} + +TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmHostTextIp6) { // issue #121 + testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//[2001:db8::]:123" /* RFC 3849 */, URI_NORMALIZE_HOST, 1, 1); +} + +TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmHostTextRegname) { // issue #121 + testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//host123.test:123" /* RFC 6761 */, URI_NORMALIZE_HOST, 1, 1); +} + +TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmHostTextFuture) { // issue #121 + testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//[v7.X]:123" /* arbitrary IPvFuture */, URI_NORMALIZE_HOST, 1, 1); } diff --git a/test/test.cpp b/test/test.cpp index 4b156a4..31e9866 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -267,7 +267,7 @@ TEST(UriSuite, TestIpSixOverread) { // NOTE: This string is designed to not have a terminator char uriText[2 + 3 + 2 + 1 + 1]; - strncpy(uriText, "//[::44.1", sizeof(uriText)); + memcpy(uriText, "//[::44.1", sizeof(uriText)); EXPECT_EQ(uriParseSingleUriExA(&uri, uriText, uriText + sizeof(uriText), &errorPos), URI_ERROR_SYNTAX); @@ -2216,6 +2216,45 @@ TEST(FreeUriMembersSuite, MultiFreeWorksFine) { uriFreeUriMembersA(&uri); // second time } +namespace { + void testFreeUriMembersFreesHostText(const char *const uriFirst) { // issue #121 + const char *const uriAfterLast = uriFirst + strlen(uriFirst); + UriUriA uri; + + EXPECT_EQ(uriParseSingleUriA(&uri, uriFirst, NULL), URI_SUCCESS); + EXPECT_EQ(uriMakeOwnerA(&uri), URI_SUCCESS); + + EXPECT_EQ(uri.owner, URI_TRUE); + EXPECT_TRUE(uri.hostText.first); + EXPECT_TRUE(uri.hostText.afterLast); + EXPECT_NE(uri.hostText.first, uri.hostText.afterLast); + URI_EXPECT_RANGE_OUTSIDE(uri.hostText, uriFirst, uriAfterLast); + + uriFreeUriMembersA(&uri); + + EXPECT_FALSE(uri.hostText.first); + EXPECT_FALSE(uri.hostText.afterLast); + + uriFreeUriMembersA(&uri); // second time + } +} // namespace + +TEST(FreeUriMembersSuite, FreeUriMembersFreesHostTextIp4) { // issue #121 + testFreeUriMembersFreesHostText("//192.0.2.0"); // RFC 5737 +} + +TEST(FreeUriMembersSuite, FreeUriMembersFreesHostTextIp6) { // issue #121 + testFreeUriMembersFreesHostText("//[2001:db8::]"); // RFC 3849 +} + +TEST(FreeUriMembersSuite, FreeUriMembersFreesHostTextRegname) { // issue #121 + testFreeUriMembersFreesHostText("//host123.test"); // RFC 6761 +} + +TEST(FreeUriMembersSuite, FreeUriMembersFreesHostTextFuture) { // issue #121 + testFreeUriMembersFreesHostText("//[v7.X]"); // arbitrary IPvFuture +} + TEST(MakeOwnerSuite, MakeOwner) { const char * const uriString = "scheme://user:pass@[v7.X]:55555/path/../path/?query#fragment"; UriUriA uri; @@ -2275,6 +2314,41 @@ TEST(MakeOwnerSuite, MakeOwner) { uriFreeUriMembersA(&uri); } +namespace { + void testMakeOwnerCopiesHostText(const char *const uriFirst) { // issue #121 + const char *const uriAfterLast = uriFirst + strlen(uriFirst); + UriUriA uri; + + EXPECT_EQ(uriParseSingleUriA(&uri, uriFirst, NULL), URI_SUCCESS); + EXPECT_EQ(uri.owner, URI_FALSE); + URI_EXPECT_RANGE_BETWEEN(uri.hostText, uriFirst, uriAfterLast); + + EXPECT_EQ(uriMakeOwnerA(&uri), URI_SUCCESS); + + EXPECT_EQ(uri.owner, URI_TRUE); + URI_EXPECT_RANGE_OUTSIDE(uri.hostText, uriFirst, uriAfterLast); + + uriFreeUriMembersA(&uri); + uriFreeUriMembersA(&uri); // tried freeing stack pointers before the fix + } +} // namespace + +TEST(MakeOwnerSuite, MakeOwnerCopiesHostTextIp4) { // issue #121 + testMakeOwnerCopiesHostText("//192.0.2.0"); // RFC 5737 +} + +TEST(MakeOwnerSuite, MakeOwnerCopiesHostTextIp6) { // issue #121 + testMakeOwnerCopiesHostText("//[2001:db8::]"); // RFC 3849 +} + +TEST(MakeOwnerSuite, MakeOwnerCopiesHostTextRegname) { // issue #121 + testMakeOwnerCopiesHostText("//host123.test"); // RFC 6761 +} + +TEST(MakeOwnerSuite, MakeOwnerCopiesHostTextFuture) { // issue #121 + testMakeOwnerCopiesHostText("//[v7.X]"); // arbitrary IPvFuture +} + TEST(ParseIpFourAddressSuite, FourSaneOctets) { unsigned char octetOutput[4]; const char * const ipAddressText = "111.22.3.40"; |