"Fossies" - the Fresh Open Source Software Archive

Member "uriparser-0.9.7/test/MemoryManagerSuite.cpp" (5 Oct 2022, 13585 Bytes) of package /linux/www/uriparser-0.9.7.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "MemoryManagerSuite.cpp": 0.9.5_vs_0.9.6.

    1 /*
    2  * uriparser - RFC 3986 URI parsing library
    3  *
    4  * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>
    5  * Copyright (C) 2007, Sebastian Pipping <sebastian@pipping.org>
    6  *
    7  * This library is free software; you can redistribute it and/or
    8  * modify it under the terms of the GNU Lesser General Public
    9  * License as published by the Free Software Foundation; either
   10  * version 2.1 of the License, or (at your option) any later version.
   11  *
   12  * This library is distributed in the hope that it will be useful,
   13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15  * Lesser General Public License for more details.
   16  *
   17  * You should have received a copy of the GNU Lesser General Public
   18  * License along with this library; if not, write to the Free Software
   19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   20  */
   21 
   22 #undef NDEBUG  // because we rely on assert(3) further down
   23 
   24 #include <cassert>
   25 #include <cerrno>
   26 #include <cstring>  // memcpy
   27 #include <gtest/gtest.h>
   28 
   29 #include <uriparser/Uri.h>
   30 
   31 // For defaultMemoryManager
   32 extern "C" {
   33 #include "../src/UriMemory.h"
   34 }
   35 
   36 
   37 namespace {
   38 
   39 
   40 
   41 static void * failingMalloc(UriMemoryManager * memory, size_t size);
   42 static void * failingCalloc(UriMemoryManager * memory, size_t nmemb, size_t size);
   43 static void * failingRealloc(UriMemoryManager * memory, void * ptr, size_t size);
   44 static void * failingReallocarray(UriMemoryManager * memory, void * ptr, size_t nmemb, size_t size);
   45 static void countingFree(UriMemoryManager * memory, void * ptr);
   46 
   47 
   48 
   49 class FailingMemoryManager {
   50 private:
   51     UriMemoryManager memoryManager;
   52     unsigned int callCountAlloc;
   53     unsigned int callCountFree;
   54     unsigned int failAllocAfterTimes;
   55 
   56     friend void * failingMalloc(UriMemoryManager * memory, size_t size);
   57     friend void * failingCalloc(UriMemoryManager * memory, size_t nmemb, size_t size);
   58     friend void * failingRealloc(UriMemoryManager * memory, void * ptr, size_t size);
   59     friend void * failingReallocarray(UriMemoryManager * memory, void * ptr, size_t nmemb, size_t size);
   60     friend void countingFree(UriMemoryManager * memory, void * ptr);
   61 
   62 public:
   63     FailingMemoryManager(unsigned int failAllocAfterTimes = 0)
   64             : callCountAlloc(0), callCountFree(0),
   65             failAllocAfterTimes(failAllocAfterTimes) {
   66         this->memoryManager.malloc = failingMalloc;
   67         this->memoryManager.calloc = failingCalloc;
   68         this->memoryManager.realloc = failingRealloc;
   69         this->memoryManager.reallocarray = failingReallocarray;
   70         this->memoryManager.free = countingFree;
   71         this->memoryManager.userData = this;
   72     }
   73 
   74     UriMemoryManager * operator&() {
   75         return &(this->memoryManager);
   76     }
   77 
   78     unsigned int getCallCountFree() const {
   79         return this->callCountFree;
   80     }
   81 };
   82 
   83 
   84 
   85 static void * failingMalloc(UriMemoryManager * memory, size_t size) {
   86     FailingMemoryManager * const fmm = static_cast<FailingMemoryManager *>(memory->userData);
   87     fmm->callCountAlloc++;
   88     if (fmm->callCountAlloc > fmm->failAllocAfterTimes) {
   89         errno = ENOMEM;
   90         return NULL;
   91     }
   92     return malloc(size);
   93 }
   94 
   95 
   96 
   97 static void * failingCalloc(UriMemoryManager * memory, size_t nmemb, size_t size) {
   98     FailingMemoryManager * const fmm = static_cast<FailingMemoryManager *>(memory->userData);
   99     fmm->callCountAlloc++;
  100     if (fmm->callCountAlloc > fmm->failAllocAfterTimes) {
  101         errno = ENOMEM;
  102         return NULL;
  103     }
  104     return calloc(nmemb, size);
  105 }
  106 
  107 
  108 
  109 static void * failingRealloc(UriMemoryManager * memory, void * ptr, size_t size) {
  110     FailingMemoryManager * const fmm = static_cast<FailingMemoryManager *>(memory->userData);
  111     fmm->callCountAlloc++;
  112     if (fmm->callCountAlloc > fmm->failAllocAfterTimes) {
  113         errno = ENOMEM;
  114         return NULL;
  115     }
  116     return realloc(ptr, size);
  117 }
  118 
  119 
  120 
  121 static void * failingReallocarray(UriMemoryManager * memory, void * ptr, size_t nmemb, size_t size) {
  122     return uriEmulateReallocarray(memory, ptr, nmemb, size);
  123 }
  124 
  125 
  126 
  127 static void countingFree(UriMemoryManager * memory, void * ptr) {
  128     FailingMemoryManager * const fmm = static_cast<FailingMemoryManager *>(memory->userData);
  129     fmm->callCountFree++;
  130     return free(ptr);
  131 }
  132 
  133 
  134 
  135 static UriUriA parse(const char * sourceUriString) {
  136     UriParserStateA state;
  137     UriUriA uri;
  138     state.uri = &uri;
  139     assert(uriParseUriA(&state, sourceUriString) == URI_SUCCESS);
  140     return uri;
  141 }
  142 
  143 
  144 
  145 static UriQueryListA * parseQueryList(const char * queryString) {
  146     UriQueryListA * queryList;
  147     const char * const first = queryString;
  148     const char * const afterLast = first + strlen(first);
  149     assert(uriDissectQueryMallocA(&queryList, NULL, first, afterLast)
  150             == URI_SUCCESS);
  151     return queryList;
  152 }
  153 
  154 }  // namespace
  155 
  156 
  157 
  158 TEST(MemoryManagerCompletenessSuite, AllFunctionMembersRequired) {
  159     UriUriA uri = parse("whatever");
  160     UriMemoryManager memory;
  161 
  162     memcpy(&memory, &defaultMemoryManager, sizeof(UriMemoryManager));
  163     memory.malloc = NULL;
  164     ASSERT_EQ(uriFreeUriMembersMmA(&uri, &memory),
  165               URI_ERROR_MEMORY_MANAGER_INCOMPLETE);
  166 
  167     memcpy(&memory, &defaultMemoryManager, sizeof(UriMemoryManager));
  168     memory.calloc = NULL;
  169     ASSERT_EQ(uriFreeUriMembersMmA(&uri, &memory),
  170               URI_ERROR_MEMORY_MANAGER_INCOMPLETE);
  171 
  172     memcpy(&memory, &defaultMemoryManager, sizeof(UriMemoryManager));
  173     memory.realloc = NULL;
  174     ASSERT_EQ(uriFreeUriMembersMmA(&uri, &memory),
  175               URI_ERROR_MEMORY_MANAGER_INCOMPLETE);
  176 
  177     memcpy(&memory, &defaultMemoryManager, sizeof(UriMemoryManager));
  178     memory.reallocarray = NULL;
  179     ASSERT_EQ(uriFreeUriMembersMmA(&uri, &memory),
  180               URI_ERROR_MEMORY_MANAGER_INCOMPLETE);
  181 
  182     memcpy(&memory, &defaultMemoryManager, sizeof(UriMemoryManager));
  183     memory.free = NULL;
  184     ASSERT_EQ(uriFreeUriMembersMmA(&uri, &memory),
  185               URI_ERROR_MEMORY_MANAGER_INCOMPLETE);
  186 
  187     memcpy(&memory, &defaultMemoryManager, sizeof(UriMemoryManager));
  188     ASSERT_EQ(uriFreeUriMembersMmA(&uri, &memory), URI_SUCCESS);
  189 }
  190 
  191 
  192 
  193 TEST(MemoryManagerCompletenessSuite, MallocAndFreeRequiredOnly) {
  194     UriMemoryManager memory;
  195     UriMemoryManager backend;
  196 
  197     memcpy(&backend, &defaultMemoryManager, sizeof(UriMemoryManager));
  198     backend.malloc = NULL;
  199     ASSERT_EQ(uriCompleteMemoryManager(&memory, &backend),
  200               URI_ERROR_MEMORY_MANAGER_INCOMPLETE);
  201 
  202     memcpy(&backend, &defaultMemoryManager, sizeof(UriMemoryManager));
  203     backend.free = NULL;
  204     ASSERT_EQ(uriCompleteMemoryManager(&memory, &backend),
  205               URI_ERROR_MEMORY_MANAGER_INCOMPLETE);
  206 }
  207 
  208 
  209 
  210 TEST(MemoryManagerTestingSuite, DefaultMemoryManager) {
  211     ASSERT_EQ(uriTestMemoryManager(&defaultMemoryManager), URI_SUCCESS);
  212 }
  213 
  214 
  215 
  216 TEST(MemoryManagerTestingSuite, CompleteMemoryManager) {
  217     UriMemoryManager memory;
  218     UriMemoryManager backend;
  219 
  220     memset(&backend, 0, sizeof(UriMemoryManager));
  221     backend.malloc = defaultMemoryManager.malloc;
  222     backend.free = defaultMemoryManager.free;
  223 
  224     ASSERT_EQ(uriCompleteMemoryManager(&memory, &backend),
  225             URI_SUCCESS);
  226 
  227     ASSERT_EQ(uriTestMemoryManager(&memory), URI_SUCCESS);
  228 }
  229 
  230 
  231 
  232 TEST(MemoryManagerTestingSuite, EmulateCalloc) {
  233     UriMemoryManager partialEmulationMemoryManager;
  234     memcpy(&partialEmulationMemoryManager, &defaultMemoryManager,
  235             sizeof(UriMemoryManager));
  236     partialEmulationMemoryManager.calloc = uriEmulateCalloc;
  237 
  238     ASSERT_EQ(uriTestMemoryManager(&partialEmulationMemoryManager),
  239             URI_SUCCESS);
  240 }
  241 
  242 
  243 
  244 TEST(MemoryManagerTestingSuite, EmulateReallocarray) {
  245     UriMemoryManager partialEmulationMemoryManager;
  246     memcpy(&partialEmulationMemoryManager, &defaultMemoryManager,
  247             sizeof(UriMemoryManager));
  248     partialEmulationMemoryManager.reallocarray = uriEmulateReallocarray;
  249 
  250     ASSERT_EQ(uriTestMemoryManager(&partialEmulationMemoryManager),
  251             URI_SUCCESS);
  252 }
  253 
  254 
  255 
  256 TEST(MemoryManagerTestingOverflowDetectionSuite, EmulateCalloc) {
  257     EXPECT_GT(2 * sizeof(size_t), sizeof(void *));
  258 
  259     errno = 0;
  260     ASSERT_EQ(NULL, uriEmulateCalloc(
  261             &defaultMemoryManager, (size_t)-1, (size_t)-1));
  262     ASSERT_EQ(errno, ENOMEM);
  263 }
  264 
  265 
  266 
  267 TEST(MemoryManagerTestingOverflowDetectionSuite, EmulateReallocarray) {
  268     EXPECT_GT(2 * sizeof(size_t), sizeof(void *));
  269 
  270     errno = 0;
  271     ASSERT_EQ(NULL, uriEmulateReallocarray(
  272             &defaultMemoryManager, NULL, (size_t)-1, (size_t)-1));
  273     ASSERT_EQ(errno, ENOMEM);
  274 }
  275 
  276 
  277 
  278 TEST(MemoryManagerTestingSuite, EmulateCallocAndReallocarray) {
  279     UriMemoryManager partialEmulationMemoryManager;
  280     memcpy(&partialEmulationMemoryManager, &defaultMemoryManager,
  281             sizeof(UriMemoryManager));
  282     partialEmulationMemoryManager.calloc = uriEmulateCalloc;
  283     partialEmulationMemoryManager.reallocarray = uriEmulateReallocarray;
  284 
  285     ASSERT_EQ(uriTestMemoryManager(&partialEmulationMemoryManager),
  286             URI_SUCCESS);
  287 }
  288 
  289 
  290 
  291 TEST(FailingMemoryManagerSuite, AddBaseUriExMm) {
  292     UriUriA absoluteDest;
  293     UriUriA relativeSource = parse("foo");
  294     UriUriA absoluteBase = parse("http://example.org/bar");
  295     const UriResolutionOptions options = URI_RESOLVE_STRICTLY;
  296     FailingMemoryManager failingMemoryManager;
  297 
  298     ASSERT_EQ(uriAddBaseUriExMmA(&absoluteDest, &relativeSource,
  299             &absoluteBase, options, &failingMemoryManager),
  300             URI_ERROR_MALLOC);
  301 
  302     uriFreeUriMembersA(&relativeSource);
  303     uriFreeUriMembersA(&absoluteBase);
  304 }
  305 
  306 
  307 
  308 TEST(FailingMemoryManagerSuite, ComposeQueryMallocExMm) {
  309     char * dest = NULL;
  310     UriQueryListA * const queryList = parseQueryList("k1=v1");
  311     UriBool spaceToPlus = URI_TRUE;  // not of interest
  312     UriBool normalizeBreaks = URI_TRUE;  // not of interest
  313     FailingMemoryManager failingMemoryManager;
  314 
  315     ASSERT_EQ(uriComposeQueryMallocExMmA(&dest, queryList,
  316             spaceToPlus, normalizeBreaks, &failingMemoryManager),
  317             URI_ERROR_MALLOC);
  318 
  319     uriFreeQueryListA(queryList);
  320 }
  321 
  322 
  323 
  324 TEST(FailingMemoryManagerSuite, DissectQueryMallocExMm) {
  325     UriQueryListA * queryList;
  326     int itemCount;
  327     const char * const first = "k1=v1&k2=v2";
  328     const char * const afterLast = first + strlen(first);
  329     const UriBool plusToSpace = URI_TRUE;  // not of interest
  330     const UriBreakConversion breakConversion = URI_BR_DONT_TOUCH;  // not o. i.
  331     FailingMemoryManager failingMemoryManager;
  332 
  333     ASSERT_EQ(uriDissectQueryMallocExMmA(&queryList, &itemCount,
  334             first, afterLast, plusToSpace, breakConversion,
  335             &failingMemoryManager),
  336             URI_ERROR_MALLOC);
  337 }
  338 
  339 
  340 
  341 TEST(FailingMemoryManagerSuite, FreeQueryListMm) {
  342     UriQueryListA * const queryList = parseQueryList("k1=v1");
  343     FailingMemoryManager failingMemoryManager;
  344     ASSERT_EQ(failingMemoryManager.getCallCountFree(), 0U);
  345 
  346     uriFreeQueryListMmA(queryList, &failingMemoryManager);
  347 
  348     ASSERT_GE(failingMemoryManager.getCallCountFree(), 1U);
  349 }
  350 
  351 
  352 
  353 TEST(FailingMemoryManagerSuite, FreeUriMembersMm) {
  354     UriUriA uri = parse("http://example.org/");
  355     FailingMemoryManager failingMemoryManager;
  356     ASSERT_EQ(failingMemoryManager.getCallCountFree(), 0U);
  357 
  358     uriFreeUriMembersMmA(&uri, &failingMemoryManager);
  359 
  360     ASSERT_GE(failingMemoryManager.getCallCountFree(), 1U);
  361     uriFreeUriMembersA(&uri);
  362 }
  363 
  364 namespace {
  365     void testNormalizeSyntaxWithFailingMallocCallsFreeTimes(const char * uriString,
  366                                                             unsigned int mask,
  367                                                             unsigned int failAllocAfterTimes = 0,
  368                                                             unsigned int expectedCallCountFree = 0) {
  369         UriUriA uri = parse(uriString);
  370         FailingMemoryManager failingMemoryManager(failAllocAfterTimes);
  371 
  372         ASSERT_EQ(uriNormalizeSyntaxExMmA(&uri, mask, &failingMemoryManager),
  373                   URI_ERROR_MALLOC);
  374 
  375         EXPECT_EQ(failingMemoryManager.getCallCountFree(), expectedCallCountFree);
  376 
  377         uriFreeUriMembersA(&uri);
  378     }
  379 }  // namespace
  380 
  381 TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmScheme) {
  382     testNormalizeSyntaxWithFailingMallocCallsFreeTimes("hTTp://example.org/path", URI_NORMALIZE_SCHEME);
  383 }
  384 
  385 TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmEmptyUserInfo) {
  386     testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//@:123", URI_NORMALIZE_USER_INFO);
  387 }
  388 
  389 TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmEmptyHostRegname) {
  390     testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//:123", URI_NORMALIZE_HOST);
  391 }
  392 
  393 TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmEmptyQuery) {
  394     testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//:123?", URI_NORMALIZE_QUERY);
  395 }
  396 
  397 TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmEmptyFragment) {
  398     testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//:123#", URI_NORMALIZE_FRAGMENT);
  399 }
  400 
  401 TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmHostTextIp4) {  // issue #121
  402     testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//192.0.2.0:123" /* RFC 5737 */, URI_NORMALIZE_HOST, 1, 1);
  403 }
  404 
  405 TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmHostTextIp6) {  // issue #121
  406     testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//[2001:db8::]:123" /* RFC 3849 */, URI_NORMALIZE_HOST, 1, 1);
  407 }
  408 
  409 TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmHostTextRegname) {  // issue #121
  410     testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//host123.test:123" /* RFC 6761 */, URI_NORMALIZE_HOST, 1, 1);
  411 }
  412 
  413 TEST(FailingMemoryManagerSuite, NormalizeSyntaxExMmHostTextFuture) {  // issue #121
  414     testNormalizeSyntaxWithFailingMallocCallsFreeTimes("//[v7.X]:123" /* arbitrary IPvFuture */, URI_NORMALIZE_HOST, 1, 1);
  415 }
  416 
  417 
  418 
  419 TEST(FailingMemoryManagerSuite, ParseSingleUriExMm) {
  420     UriUriA uri;
  421     const char * const first = "k1=v1&k2=v2";
  422     const char * const afterLast = first + strlen(first);
  423     FailingMemoryManager failingMemoryManager;
  424 
  425     ASSERT_EQ(uriParseSingleUriExMmA(&uri, first, afterLast, NULL,
  426             &failingMemoryManager),
  427             URI_ERROR_MALLOC);
  428 }
  429 
  430 
  431 
  432 TEST(FailingMemoryManagerSuite, RemoveBaseUriMm) {
  433     UriUriA dest;
  434     UriUriA absoluteSource = parse("http://example.org/a/b/c/");
  435     UriUriA absoluteBase = parse("http://example.org/a/");
  436     const UriBool domainRootMode = URI_TRUE;  // not of interest
  437     FailingMemoryManager failingMemoryManager;
  438 
  439     ASSERT_EQ(uriRemoveBaseUriMmA(&dest, &absoluteSource, &absoluteBase,
  440             domainRootMode, &failingMemoryManager),
  441             URI_ERROR_MALLOC);
  442 
  443     uriFreeUriMembersA(&absoluteSource);
  444     uriFreeUriMembersA(&absoluteBase);
  445 }