diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/UriCommon.c | 77 | ||||
-rw-r--r-- | src/UriCommon.h | 19 | ||||
-rw-r--r-- | src/UriMemory.c | 470 | ||||
-rw-r--r-- | src/UriMemory.h | 59 | ||||
-rw-r--r-- | src/UriNormalize.c | 165 | ||||
-rw-r--r-- | src/UriParse.c | 691 | ||||
-rw-r--r-- | src/UriQuery.c | 107 | ||||
-rw-r--r-- | src/UriResolve.c | 69 | ||||
-rw-r--r-- | src/UriShorten.c | 48 |
9 files changed, 1252 insertions, 453 deletions
diff --git a/src/UriCommon.c b/src/UriCommon.c index 571d6d4..039beda 100644 --- a/src/UriCommon.c +++ b/src/UriCommon.c @@ -75,6 +75,9 @@ void URI_FUNC(ResetUri)(URI_TYPE(Uri) * uri) { + if (uri == NULL) { + return; + } memset(uri, 0, sizeof(URI_TYPE(Uri))); } @@ -118,17 +121,17 @@ int URI_FUNC(CompareRange)( /* Properly removes "." and ".." path segments */ UriBool URI_FUNC(RemoveDotSegments)(URI_TYPE(Uri) * uri, - UriBool relative) { + UriBool relative, UriMemoryManager * memory) { if (uri == NULL) { return URI_TRUE; } - return URI_FUNC(RemoveDotSegmentsEx)(uri, relative, uri->owner); + return URI_FUNC(RemoveDotSegmentsEx)(uri, relative, uri->owner, memory); } UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri, - UriBool relative, UriBool pathOwned) { + UriBool relative, UriBool pathOwned, UriMemoryManager * memory) { URI_TYPE(PathSegment) * walker; if ((uri == NULL) || (uri->pathHead == NULL)) { return URI_TRUE; @@ -173,13 +176,13 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri, } if (pathOwned && (walker->text.first != walker->text.afterLast)) { - free((URI_CHAR *)walker->text.first); + memory->free(memory, (URI_CHAR *)walker->text.first); } - free(walker); + memory->free(memory, walker); } else { /* Last segment */ if (pathOwned && (walker->text.first != walker->text.afterLast)) { - free((URI_CHAR *)walker->text.first); + memory->free(memory, (URI_CHAR *)walker->text.first); } if (prev == NULL) { @@ -189,7 +192,7 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri, walker->text.first = URI_FUNC(SafeToPointTo); walker->text.afterLast = URI_FUNC(SafeToPointTo); } else { - free(walker); + memory->free(memory, walker); uri->pathHead = NULL; uri->pathTail = NULL; @@ -237,21 +240,20 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri, walker->next->reserved = prevPrev; } else { /* Last segment -> insert "" segment to represent trailing slash, update tail */ - URI_TYPE(PathSegment) * const segment = malloc(1 * sizeof(URI_TYPE(PathSegment))); + URI_TYPE(PathSegment) * const segment = memory->calloc(memory, 1, sizeof(URI_TYPE(PathSegment))); if (segment == NULL) { if (pathOwned && (walker->text.first != walker->text.afterLast)) { - free((URI_CHAR *)walker->text.first); + memory->free(memory, (URI_CHAR *)walker->text.first); } - free(walker); + memory->free(memory, walker); if (pathOwned && (prev->text.first != prev->text.afterLast)) { - free((URI_CHAR *)prev->text.first); + memory->free(memory, (URI_CHAR *)prev->text.first); } - free(prev); + memory->free(memory, prev); return URI_FALSE; /* Raises malloc error */ } - memset(segment, 0, sizeof(URI_TYPE(PathSegment))); segment->text.first = URI_FUNC(SafeToPointTo); segment->text.afterLast = URI_FUNC(SafeToPointTo); prevPrev->next = segment; @@ -259,14 +261,14 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri, } if (pathOwned && (walker->text.first != walker->text.afterLast)) { - free((URI_CHAR *)walker->text.first); + memory->free(memory, (URI_CHAR *)walker->text.first); } - free(walker); + memory->free(memory, walker); if (pathOwned && (prev->text.first != prev->text.afterLast)) { - free((URI_CHAR *)prev->text.first); + memory->free(memory, (URI_CHAR *)prev->text.first); } - free(prev); + memory->free(memory, prev); walker = nextBackup; } else { @@ -276,14 +278,14 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri, walker->next->reserved = NULL; if (pathOwned && (walker->text.first != walker->text.afterLast)) { - free((URI_CHAR *)walker->text.first); + memory->free(memory, (URI_CHAR *)walker->text.first); } - free(walker); + memory->free(memory, walker); } else { /* Re-use segment for "" path segment to represent trailing slash, update tail */ URI_TYPE(PathSegment) * const segment = walker; if (pathOwned && (segment->text.first != segment->text.afterLast)) { - free((URI_CHAR *)segment->text.first); + memory->free(memory, (URI_CHAR *)segment->text.first); } segment->text.first = URI_FUNC(SafeToPointTo); segment->text.afterLast = URI_FUNC(SafeToPointTo); @@ -292,9 +294,9 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri, } if (pathOwned && (prev->text.first != prev->text.afterLast)) { - free((URI_CHAR *)prev->text.first); + memory->free(memory, (URI_CHAR *)prev->text.first); } - free(prev); + memory->free(memory, prev); walker = nextBackup; } @@ -310,9 +312,9 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri, } if (pathOwned && (walker->text.first != walker->text.afterLast)) { - free((URI_CHAR *)walker->text.first); + memory->free(memory, (URI_CHAR *)walker->text.first); } - free(walker); + memory->free(memory, walker); walker = anotherNextBackup; } @@ -339,9 +341,10 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri, /* Properly removes "." and ".." path segments */ -UriBool URI_FUNC(RemoveDotSegmentsAbsolute)(URI_TYPE(Uri) * uri) { +UriBool URI_FUNC(RemoveDotSegmentsAbsolute)(URI_TYPE(Uri) * uri, + UriMemoryManager * memory) { const UriBool ABSOLUTE = URI_FALSE; - return URI_FUNC(RemoveDotSegments)(uri, ABSOLUTE); + return URI_FUNC(RemoveDotSegments)(uri, ABSOLUTE, memory); } @@ -429,7 +432,7 @@ UriBool URI_FUNC(IsHostSet)(const URI_TYPE(Uri) * uri) { /* Copies the path segment list from one URI to another. */ UriBool URI_FUNC(CopyPath)(URI_TYPE(Uri) * dest, - const URI_TYPE(Uri) * source) { + const URI_TYPE(Uri) * source, UriMemoryManager * memory) { if (source->pathHead == NULL) { /* No path component */ dest->pathHead = NULL; @@ -439,7 +442,7 @@ UriBool URI_FUNC(CopyPath)(URI_TYPE(Uri) * dest, URI_TYPE(PathSegment) * sourceWalker = source->pathHead; URI_TYPE(PathSegment) * destPrev = NULL; do { - URI_TYPE(PathSegment) * cur = malloc(sizeof(URI_TYPE(PathSegment))); + URI_TYPE(PathSegment) * cur = memory->malloc(memory, sizeof(URI_TYPE(PathSegment))); if (cur == NULL) { /* Fix broken list */ if (destPrev != NULL) { @@ -472,10 +475,10 @@ UriBool URI_FUNC(CopyPath)(URI_TYPE(Uri) * dest, /* Copies the authority part of an URI over to another. */ UriBool URI_FUNC(CopyAuthority)(URI_TYPE(Uri) * dest, - const URI_TYPE(Uri) * source) { + const URI_TYPE(Uri) * source, UriMemoryManager * memory) { /* From this functions usage we know that * * the dest URI cannot be uri->owner */ - + /* Copy userInfo */ dest->userInfo = source->userInfo; @@ -484,7 +487,7 @@ UriBool URI_FUNC(CopyAuthority)(URI_TYPE(Uri) * dest, /* Copy hostData */ if (source->hostData.ip4 != NULL) { - dest->hostData.ip4 = malloc(sizeof(UriIp4)); + dest->hostData.ip4 = memory->malloc(memory, sizeof(UriIp4)); if (dest->hostData.ip4 == NULL) { return URI_FALSE; /* Raises malloc error */ } @@ -494,7 +497,7 @@ UriBool URI_FUNC(CopyAuthority)(URI_TYPE(Uri) * dest, dest->hostData.ipFuture.afterLast = NULL; } else if (source->hostData.ip6 != NULL) { dest->hostData.ip4 = NULL; - dest->hostData.ip6 = malloc(sizeof(UriIp6)); + dest->hostData.ip6 = memory->malloc(memory, sizeof(UriIp6)); if (dest->hostData.ip6 == NULL) { return URI_FALSE; /* Raises malloc error */ } @@ -515,7 +518,8 @@ UriBool URI_FUNC(CopyAuthority)(URI_TYPE(Uri) * dest, -UriBool URI_FUNC(FixAmbiguity)(URI_TYPE(Uri) * uri) { +UriBool URI_FUNC(FixAmbiguity)(URI_TYPE(Uri) * uri, + UriMemoryManager * memory) { URI_TYPE(PathSegment) * segment; if ( /* Case 1: absolute path, empty first segment */ @@ -534,7 +538,7 @@ UriBool URI_FUNC(FixAmbiguity)(URI_TYPE(Uri) * uri) { return URI_TRUE; } - segment = malloc(1 * sizeof(URI_TYPE(PathSegment))); + segment = memory->malloc(memory, 1 * sizeof(URI_TYPE(PathSegment))); if (segment == NULL) { return URI_FALSE; /* Raises malloc error */ } @@ -549,14 +553,15 @@ UriBool URI_FUNC(FixAmbiguity)(URI_TYPE(Uri) * uri) { -void URI_FUNC(FixEmptyTrailSegment)(URI_TYPE(Uri) * uri) { +void URI_FUNC(FixEmptyTrailSegment)(URI_TYPE(Uri) * uri, + UriMemoryManager * memory) { /* Fix path if only one empty segment */ if (!uri->absolutePath && !URI_FUNC(IsHostSet)(uri) && (uri->pathHead != NULL) && (uri->pathHead->next == NULL) && (uri->pathHead->text.first == uri->pathHead->text.afterLast)) { - free(uri->pathHead); + memory->free(memory, uri->pathHead); uri->pathHead = NULL; uri->pathTail = NULL; } diff --git a/src/UriCommon.h b/src/UriCommon.h index b062fcc..916055c 100644 --- a/src/UriCommon.h +++ b/src/UriCommon.h @@ -82,10 +82,12 @@ int URI_FUNC(CompareRange)( const URI_TYPE(TextRange) * a, const URI_TYPE(TextRange) * b); -UriBool URI_FUNC(RemoveDotSegmentsAbsolute)(URI_TYPE(Uri) * uri); -UriBool URI_FUNC(RemoveDotSegments)(URI_TYPE(Uri) * uri, UriBool relative); +UriBool URI_FUNC(RemoveDotSegmentsAbsolute)(URI_TYPE(Uri) * uri, + UriMemoryManager * memory); +UriBool URI_FUNC(RemoveDotSegments)(URI_TYPE(Uri) * uri, UriBool relative, + UriMemoryManager * memory); UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri, - UriBool relative, UriBool pathOwned); + UriBool relative, UriBool pathOwned, UriMemoryManager * memory); unsigned char URI_FUNC(HexdigToInt)(URI_CHAR hexdig); URI_CHAR URI_FUNC(HexToLetter)(unsigned int value); @@ -93,11 +95,14 @@ URI_CHAR URI_FUNC(HexToLetterEx)(unsigned int value, UriBool uppercase); UriBool URI_FUNC(IsHostSet)(const URI_TYPE(Uri) * uri); -UriBool URI_FUNC(CopyPath)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * source); -UriBool URI_FUNC(CopyAuthority)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * source); +UriBool URI_FUNC(CopyPath)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * source, + UriMemoryManager * memory); +UriBool URI_FUNC(CopyAuthority)(URI_TYPE(Uri) * dest, + const URI_TYPE(Uri) * source, UriMemoryManager * memory); -UriBool URI_FUNC(FixAmbiguity)(URI_TYPE(Uri) * uri); -void URI_FUNC(FixEmptyTrailSegment)(URI_TYPE(Uri) * uri); +UriBool URI_FUNC(FixAmbiguity)(URI_TYPE(Uri) * uri, UriMemoryManager * memory); +void URI_FUNC(FixEmptyTrailSegment)(URI_TYPE(Uri) * uri, + UriMemoryManager * memory); #endif diff --git a/src/UriMemory.c b/src/UriMemory.c new file mode 100644 index 0000000..5e6bcc4 --- /dev/null +++ b/src/UriMemory.c @@ -0,0 +1,470 @@ +/* + * uriparser - RFC 3986 URI parsing library + * + * Copyright (C) 2018, Weijia Song <songweijia@gmail.com> + * Copyright (C) 2018, Sebastian Pipping <sebastian@pipping.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * * Neither the name of the <ORGANIZATION> nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file UriMemory.c + * Holds memory manager implementation. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#if HAVE_REALLOCARRAY +# ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +# endif +#endif + +#include <errno.h> +#include <stdlib.h> + + + +#ifndef URI_DOXYGEN +# include "UriMemory.h" +#endif + + + +#define URI_CHECK_ALLOC_OVERFLOW(total_size, nmemb, size) \ + do { \ + /* check for unsigned overflow */ \ + if ((nmemb != 0) && (total_size / nmemb != size)) { \ + errno = ENOMEM; \ + return NULL; \ + } \ + } while (0) + + + +static void * uriDefaultMalloc(UriMemoryManager * URI_UNUSED(memory), + size_t size) { + return malloc(size); +} + + + +static void * uriDefaultCalloc(UriMemoryManager * URI_UNUSED(memory), + size_t nmemb, size_t size) { + return calloc(nmemb, size); +} + + + +static void * uriDefaultRealloc(UriMemoryManager * URI_UNUSED(memory), + void * ptr, size_t size) { + return realloc(ptr, size); +} + + + +static void * uriDefaultReallocarray(UriMemoryManager * URI_UNUSED(memory), + void * ptr, size_t nmemb, size_t size) { +#if HAVE_REALLOCARRAY + return reallocarray(ptr, nmemb, size); +#else + const size_t total_size = nmemb * size; + + URI_CHECK_ALLOC_OVERFLOW(total_size, nmemb, size); /* may return */ + + return realloc(ptr, total_size); +#endif +} + + + +static void uriDefaultFree(UriMemoryManager * URI_UNUSED(memory), + void * ptr) { + free(ptr); +} + + + +UriBool uriMemoryManagerIsComplete(const UriMemoryManager * memory) { + return (memory + && memory->malloc + && memory->calloc + && memory->realloc + && memory->reallocarray + && memory->free) ? URI_TRUE : URI_FALSE; +} + + + +void * uriEmulateCalloc(UriMemoryManager * memory, size_t nmemb, size_t size) { + void * buffer; + const size_t total_size = nmemb * size; + + if (memory == NULL) { + errno = EINVAL; + return NULL; + } + + URI_CHECK_ALLOC_OVERFLOW(total_size, nmemb, size); /* may return */ + + buffer = memory->malloc(memory, total_size); + if (buffer == NULL) { + /* errno set by malloc */ + return NULL; + } + memset(buffer, 0, total_size); + return buffer; +} + + + +void * uriEmulateReallocarray(UriMemoryManager * memory, + void * ptr, size_t nmemb, size_t size) { + const size_t total_size = nmemb * size; + + if (memory == NULL) { + errno = EINVAL; + return NULL; + } + + URI_CHECK_ALLOC_OVERFLOW(total_size, nmemb, size); /* may return */ + + return memory->realloc(memory, ptr, total_size); +} + + + +static void * uriDecorateMalloc(UriMemoryManager * memory, + size_t size) { + UriMemoryManager * backend; + const size_t extraBytes = sizeof(size_t); + void * buffer; + + if (memory == NULL) { + errno = EINVAL; + return NULL; + } + + /* check for unsigned overflow */ + if (size > ((size_t)-1) - extraBytes) { + errno = ENOMEM; + return NULL; + } + + backend = (UriMemoryManager *)memory->userData; + if (backend == NULL) { + errno = EINVAL; + return NULL; + } + + buffer = backend->malloc(backend, extraBytes + size); + if (buffer == NULL) { + return NULL; + } + + *(size_t *)buffer = size; + + return (char *)buffer + extraBytes; +} + + + +static void * uriDecorateRealloc(UriMemoryManager * memory, + void * ptr, size_t size) { + void * newBuffer; + size_t prevSize; + + if (memory == NULL) { + errno = EINVAL; + return NULL; + } + + /* man realloc: "If ptr is NULL, then the call is equivalent to + * malloc(size), for *all* values of size" */ + if (ptr == NULL) { + return memory->malloc(memory, size); + } + + /* man realloc: "If size is equal to zero, and ptr is *not* NULL, + * then the call is equivalent to free(ptr)." */ + if (size == 0) { + memory->free(memory, ptr); + return NULL; + } + + prevSize = *((size_t *)((char *)ptr - sizeof(size_t))); + + /* Anything to do? */ + if (size <= prevSize) { + return ptr; + } + + newBuffer = memory->malloc(memory, size); + if (newBuffer == NULL) { + /* errno set by malloc */ + return NULL; + } + + memcpy(newBuffer, ptr, prevSize); + + memory->free(memory, ptr); + + return newBuffer; +} + + + +static void uriDecorateFree(UriMemoryManager * memory, void * ptr) { + UriMemoryManager * backend; + + if ((ptr == NULL) || (memory == NULL)) { + return; + } + + backend = (UriMemoryManager *)memory->userData; + if (backend == NULL) { + return; + } + + backend->free(backend, (char *)ptr - sizeof(size_t)); +} + + + +int uriCompleteMemoryManager(UriMemoryManager * memory, + UriMemoryManager * backend) { + if ((memory == NULL) || (backend == NULL)) { + return URI_ERROR_NULL; + } + + if ((backend->malloc == NULL) || (backend->free == NULL)) { + return URI_ERROR_MEMORY_MANAGER_INCOMPLETE; + } + + memory->calloc = uriEmulateCalloc; + memory->reallocarray = uriEmulateReallocarray; + + memory->malloc = uriDecorateMalloc; + memory->realloc = uriDecorateRealloc; + memory->free = uriDecorateFree; + + memory->userData = backend; + + return URI_SUCCESS; +} + + + +int uriTestMemoryManager(UriMemoryManager * memory) { + const size_t mallocSize = 7; + const size_t callocNmemb = 3; + const size_t callocSize = 5; + const size_t callocTotalSize = callocNmemb * callocSize; + const size_t reallocSize = 11; + const size_t reallocarrayNmemb = 5; + const size_t reallocarraySize = 7; + const size_t reallocarrayTotal = reallocarrayNmemb * reallocarraySize; + size_t index; + char * buffer; + + if (memory == NULL) { + return URI_ERROR_NULL; + } + + if (uriMemoryManagerIsComplete(memory) != URI_TRUE) { + return URI_ERROR_MEMORY_MANAGER_INCOMPLETE; + } + + /* malloc + free*/ + buffer = memory->malloc(memory, mallocSize); + if (buffer == NULL) { + return URI_ERROR_MEMORY_MANAGER_FAULTY; + } + buffer[mallocSize - 1] = '\xF1'; + memory->free(memory, buffer); + buffer = NULL; + + /* calloc + free */ + buffer = memory->calloc(memory, callocNmemb, callocSize); + if (buffer == NULL) { + return URI_ERROR_MEMORY_MANAGER_FAULTY; + } + for (index = 0; index < callocTotalSize; index++) { /* all zeros? */ + if (buffer[index] != '\0') { + return URI_ERROR_MEMORY_MANAGER_FAULTY; + } + } + buffer[callocTotalSize - 1] = '\xF2'; + memory->free(memory, buffer); + buffer = NULL; + + /* malloc + realloc + free */ + buffer = memory->malloc(memory, mallocSize); + if (buffer == NULL) { + return URI_ERROR_MEMORY_MANAGER_FAULTY; + } + for (index = 0; index < mallocSize; index++) { + buffer[index] = '\xF3'; + } + buffer = memory->realloc(memory, buffer, reallocSize); + if (buffer == NULL) { + return URI_ERROR_MEMORY_MANAGER_FAULTY; + } + for (index = 0; index < mallocSize; index++) { /* previous content? */ + if (buffer[index] != '\xF3') { + return URI_ERROR_MEMORY_MANAGER_FAULTY; + } + } + buffer[reallocSize - 1] = '\xF4'; + memory->free(memory, buffer); + buffer = NULL; + + /* malloc + realloc ptr!=NULL size==0 (equals free) */ + buffer = memory->malloc(memory, mallocSize); + if (buffer == NULL) { + return URI_ERROR_MEMORY_MANAGER_FAULTY; + } + buffer[mallocSize - 1] = '\xF5'; + memory->realloc(memory, buffer, 0); + buffer = NULL; + + /* realloc ptr==NULL size!=0 (equals malloc) + free */ + buffer = memory->realloc(memory, NULL, mallocSize); + if (buffer == NULL) { + return URI_ERROR_MEMORY_MANAGER_FAULTY; + } + buffer[mallocSize - 1] = '\xF6'; + memory->free(memory, buffer); + buffer = NULL; + + /* realloc ptr==NULL size==0 (equals malloc) + free */ + buffer = memory->realloc(memory, NULL, 0); + if (buffer != NULL) { + memory->free(memory, buffer); + buffer = NULL; + } + + /* malloc + reallocarray + free */ + buffer = memory->malloc(memory, mallocSize); + if (buffer == NULL) { + return URI_ERROR_MEMORY_MANAGER_FAULTY; + } + for (index = 0; index < mallocSize; index++) { + buffer[index] = '\xF7'; + } + buffer = memory->reallocarray(memory, buffer, reallocarrayNmemb, + reallocarraySize); + if (buffer == NULL) { + return URI_ERROR_MEMORY_MANAGER_FAULTY; + } + for (index = 0; index < mallocSize; index++) { /* previous content? */ + if (buffer[index] != '\xF7') { + return URI_ERROR_MEMORY_MANAGER_FAULTY; + } + } + buffer[reallocarrayTotal - 1] = '\xF8'; + memory->free(memory, buffer); + buffer = NULL; + + /* malloc + reallocarray ptr!=NULL nmemb==0 size!=0 (equals free) */ + buffer = memory->malloc(memory, mallocSize); + if (buffer == NULL) { + return URI_ERROR_MEMORY_MANAGER_FAULTY; + } + buffer[mallocSize - 1] = '\xF9'; + memory->reallocarray(memory, buffer, 0, reallocarraySize); + buffer = NULL; + + /* malloc + reallocarray ptr!=NULL nmemb!=0 size==0 (equals free) */ + buffer = memory->malloc(memory, mallocSize); + if (buffer == NULL) { + return URI_ERROR_MEMORY_MANAGER_FAULTY; + } + buffer[mallocSize - 1] = '\xFA'; + memory->reallocarray(memory, buffer, reallocarrayNmemb, 0); + buffer = NULL; + + /* malloc + reallocarray ptr!=NULL nmemb==0 size==0 (equals free) */ + buffer = memory->malloc(memory, mallocSize); + if (buffer == NULL) { + return URI_ERROR_MEMORY_MANAGER_FAULTY; + } + buffer[mallocSize - 1] = '\xFB'; + memory->reallocarray(memory, buffer, 0, 0); + buffer = NULL; + + /* reallocarray ptr==NULL nmemb!=0 size!=0 (equals malloc) + free */ + buffer = memory->reallocarray(memory, NULL, callocNmemb, callocSize); + if (buffer == NULL) { + return URI_ERROR_MEMORY_MANAGER_FAULTY; + } + buffer[callocTotalSize - 1] = '\xFC'; + memory->free(memory, buffer); + buffer = NULL; + + /* reallocarray ptr==NULL nmemb==0 size!=0 (equals malloc) + free */ + buffer = memory->reallocarray(memory, NULL, 0, callocSize); + if (buffer != NULL) { + memory->free(memory, buffer); + buffer = NULL; + } + + /* reallocarray ptr==NULL nmemb!=0 size==0 (equals malloc) + free */ + buffer = memory->reallocarray(memory, NULL, callocNmemb, 0); + if (buffer != NULL) { + memory->free(memory, buffer); + buffer = NULL; + } + + /* reallocarray ptr==NULL nmemb==0 size==0 (equals malloc) + free */ + buffer = memory->reallocarray(memory, NULL, 0, 0); + if (buffer != NULL) { + memory->free(memory, buffer); + buffer = NULL; + } + + return URI_SUCCESS; +} + + + +/*extern*/ UriMemoryManager defaultMemoryManager = { + uriDefaultMalloc, + uriDefaultCalloc, + uriDefaultRealloc, + uriDefaultReallocarray, + uriDefaultFree, + NULL /* userData */ +}; diff --git a/src/UriMemory.h b/src/UriMemory.h new file mode 100644 index 0000000..c40c072 --- /dev/null +++ b/src/UriMemory.h @@ -0,0 +1,59 @@ +/* + * uriparser - RFC 3986 URI parsing library + * + * Copyright (C) 2018, Weijia Song <songweijia@gmail.com> + * Copyright (C) 2018, Sebastian Pipping <sebastian@pipping.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * * Neither the name of the <ORGANIZATION> nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef URI_DOXYGEN +# include <uriparser/Uri.h> +#endif + + + +#define URI_CHECK_MEMORY_MANAGER(memory) \ + do { \ + if (memory == NULL) { \ + memory = &defaultMemoryManager; \ + } else if (uriMemoryManagerIsComplete(memory) != URI_TRUE) { \ + return URI_ERROR_MEMORY_MANAGER_INCOMPLETE; \ + } \ + } while (0) + + + +extern UriMemoryManager defaultMemoryManager; + +UriBool uriMemoryManagerIsComplete(const UriMemoryManager * memory); diff --git a/src/UriNormalize.c b/src/UriNormalize.c index d68c371..0e798c0 100644 --- a/src/UriNormalize.c +++ b/src/UriNormalize.c @@ -71,22 +71,28 @@ # include <uriparser/Uri.h> # include "UriNormalizeBase.h" # include "UriCommon.h" +# include "UriMemory.h" #endif +#include <assert.h> + + + static int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, unsigned int inMask, - unsigned int * outMask); + unsigned int * outMask, UriMemoryManager * memory); static UriBool URI_FUNC(MakeRangeOwner)(unsigned int * doneMask, - unsigned int maskTest, URI_TYPE(TextRange) * range); + unsigned int maskTest, URI_TYPE(TextRange) * range, + UriMemoryManager * memory); static UriBool URI_FUNC(MakeOwner)(URI_TYPE(Uri) * uri, - unsigned int * doneMask); + unsigned int * doneMask, UriMemoryManager * memory); static void URI_FUNC(FixPercentEncodingInplace)(const URI_CHAR * first, const URI_CHAR ** afterLast); static UriBool URI_FUNC(FixPercentEncodingMalloc)(const URI_CHAR ** first, - const URI_CHAR ** afterLast); + const URI_CHAR ** afterLast, UriMemoryManager * memory); static void URI_FUNC(FixPercentEncodingEngine)( const URI_CHAR * inFirst, const URI_CHAR * inAfterLast, const URI_CHAR * outFirst, const URI_CHAR ** outAfterLast); @@ -99,23 +105,23 @@ static UriBool URI_FUNC(ContainsUglyPercentEncoding)(const URI_CHAR * first, static void URI_FUNC(LowercaseInplace)(const URI_CHAR * first, const URI_CHAR * afterLast); static UriBool URI_FUNC(LowercaseMalloc)(const URI_CHAR ** first, - const URI_CHAR ** afterLast); + const URI_CHAR ** afterLast, UriMemoryManager * memory); static void URI_FUNC(PreventLeakage)(URI_TYPE(Uri) * uri, - unsigned int revertMask); + unsigned int revertMask, UriMemoryManager * memory); static URI_INLINE void URI_FUNC(PreventLeakage)(URI_TYPE(Uri) * uri, - unsigned int revertMask) { + unsigned int revertMask, UriMemoryManager * memory) { if (revertMask & URI_NORMALIZE_SCHEME) { - free((URI_CHAR *)uri->scheme.first); + memory->free(memory, (URI_CHAR *)uri->scheme.first); uri->scheme.first = NULL; uri->scheme.afterLast = NULL; } if (revertMask & URI_NORMALIZE_USER_INFO) { - free((URI_CHAR *)uri->userInfo.first); + memory->free(memory, (URI_CHAR *)uri->userInfo.first); uri->userInfo.first = NULL; uri->userInfo.afterLast = NULL; } @@ -123,7 +129,7 @@ static URI_INLINE void URI_FUNC(PreventLeakage)(URI_TYPE(Uri) * uri, if (revertMask & URI_NORMALIZE_HOST) { if (uri->hostData.ipFuture.first != NULL) { /* IPvFuture */ - free((URI_CHAR *)uri->hostData.ipFuture.first); + memory->free(memory, (URI_CHAR *)uri->hostData.ipFuture.first); uri->hostData.ipFuture.first = NULL; uri->hostData.ipFuture.afterLast = NULL; uri->hostText.first = NULL; @@ -132,7 +138,7 @@ static URI_INLINE void URI_FUNC(PreventLeakage)(URI_TYPE(Uri) * uri, && (uri->hostData.ip4 == NULL) && (uri->hostData.ip6 == NULL)) { /* Regname */ - free((URI_CHAR *)uri->hostText.first); + memory->free(memory, (URI_CHAR *)uri->hostText.first); uri->hostText.first = NULL; uri->hostText.afterLast = NULL; } @@ -145,9 +151,9 @@ static URI_INLINE void URI_FUNC(PreventLeakage)(URI_TYPE(Uri) * uri, while (walker != NULL) { URI_TYPE(PathSegment) * const next = walker->next; if (walker->text.afterLast > walker->text.first) { - free((URI_CHAR *)walker->text.first); + memory->free(memory, (URI_CHAR *)walker->text.first); } - free(walker); + memory->free(memory, walker); walker = next; } uri->pathHead = NULL; @@ -155,13 +161,13 @@ static URI_INLINE void URI_FUNC(PreventLeakage)(URI_TYPE(Uri) * uri, } if (revertMask & URI_NORMALIZE_QUERY) { - free((URI_CHAR *)uri->query.first); + memory->free(memory, (URI_CHAR *)uri->query.first); uri->query.first = NULL; uri->query.afterLast = NULL; } if (revertMask & URI_NORMALIZE_FRAGMENT) { - free((URI_CHAR *)uri->fragment.first); + memory->free(memory, (URI_CHAR *)uri->fragment.first); uri->fragment.first = NULL; uri->fragment.afterLast = NULL; } @@ -230,7 +236,7 @@ static URI_INLINE void URI_FUNC(LowercaseInplace)(const URI_CHAR * first, static URI_INLINE UriBool URI_FUNC(LowercaseMalloc)(const URI_CHAR ** first, - const URI_CHAR ** afterLast) { + const URI_CHAR ** afterLast, UriMemoryManager * memory) { int lenInChars; const int lowerUpperDiff = (_UT('a') - _UT('A')); URI_CHAR * buffer; @@ -248,7 +254,7 @@ static URI_INLINE UriBool URI_FUNC(LowercaseMalloc)(const URI_CHAR ** first, return URI_FALSE; } - buffer = malloc(lenInChars * sizeof(URI_CHAR)); + buffer = memory->malloc(memory, lenInChars * sizeof(URI_CHAR)); if (buffer == NULL) { return URI_FALSE; } @@ -330,7 +336,7 @@ static URI_INLINE void URI_FUNC(FixPercentEncodingInplace)(const URI_CHAR * firs static URI_INLINE UriBool URI_FUNC(FixPercentEncodingMalloc)(const URI_CHAR ** first, - const URI_CHAR ** afterLast) { + const URI_CHAR ** afterLast, UriMemoryManager * memory) { int lenInChars; URI_CHAR * buffer; @@ -349,7 +355,7 @@ static URI_INLINE UriBool URI_FUNC(FixPercentEncodingMalloc)(const URI_CHAR ** f } /* New buffer */ - buffer = malloc(lenInChars * sizeof(URI_CHAR)); + buffer = memory->malloc(memory, lenInChars * sizeof(URI_CHAR)); if (buffer == NULL) { return URI_FALSE; } @@ -363,14 +369,15 @@ static URI_INLINE UriBool URI_FUNC(FixPercentEncodingMalloc)(const URI_CHAR ** f static URI_INLINE UriBool URI_FUNC(MakeRangeOwner)(unsigned int * doneMask, - unsigned int maskTest, URI_TYPE(TextRange) * range) { + unsigned int maskTest, URI_TYPE(TextRange) * range, + UriMemoryManager * memory) { if (((*doneMask & maskTest) == 0) && (range->first != NULL) && (range->afterLast != NULL) && (range->afterLast > range->first)) { const int lenInChars = (int)(range->afterLast - range->first); const int lenInBytes = lenInChars * sizeof(URI_CHAR); - URI_CHAR * dup = malloc(lenInBytes); + URI_CHAR * dup = memory->malloc(memory, lenInBytes); if (dup == NULL) { return URI_FALSE; /* Raises malloc error */ } @@ -385,16 +392,16 @@ static URI_INLINE UriBool URI_FUNC(MakeRangeOwner)(unsigned int * doneMask, static URI_INLINE UriBool URI_FUNC(MakeOwner)(URI_TYPE(Uri) * uri, - unsigned int * doneMask) { + unsigned int * doneMask, UriMemoryManager * memory) { URI_TYPE(PathSegment) * walker = uri->pathHead; if (!URI_FUNC(MakeRangeOwner)(doneMask, URI_NORMALIZE_SCHEME, - &(uri->scheme)) + &(uri->scheme), memory) || !URI_FUNC(MakeRangeOwner)(doneMask, URI_NORMALIZE_USER_INFO, - &(uri->userInfo)) + &(uri->userInfo), memory) || !URI_FUNC(MakeRangeOwner)(doneMask, URI_NORMALIZE_QUERY, - &(uri->query)) + &(uri->query), memory) || !URI_FUNC(MakeRangeOwner)(doneMask, URI_NORMALIZE_FRAGMENT, - &(uri->fragment))) { + &(uri->fragment), memory)) { return URI_FALSE; /* Raises malloc error */ } @@ -405,7 +412,7 @@ static URI_INLINE UriBool URI_FUNC(MakeOwner)(URI_TYPE(Uri) * uri, if (uri->hostData.ipFuture.first != NULL) { /* IPvFuture */ if (!URI_FUNC(MakeRangeOwner)(doneMask, URI_NORMALIZE_HOST, - &(uri->hostData.ipFuture))) { + &(uri->hostData.ipFuture), memory)) { return URI_FALSE; /* Raises malloc error */ } uri->hostText.first = uri->hostData.ipFuture.first; @@ -413,7 +420,7 @@ static URI_INLINE UriBool URI_FUNC(MakeOwner)(URI_TYPE(Uri) * uri, } else if (uri->hostText.first != NULL) { /* Regname */ if (!URI_FUNC(MakeRangeOwner)(doneMask, URI_NORMALIZE_HOST, - &(uri->hostText))) { + &(uri->hostText), memory)) { return URI_FALSE; /* Raises malloc error */ } } @@ -423,7 +430,7 @@ static URI_INLINE UriBool URI_FUNC(MakeOwner)(URI_TYPE(Uri) * uri, /* Path */ if ((*doneMask & URI_NORMALIZE_PATH) == 0) { while (walker != NULL) { - if (!URI_FUNC(MakeRangeOwner)(doneMask, 0, &(walker->text))) { + if (!URI_FUNC(MakeRangeOwner)(doneMask, 0, &(walker->text), memory)) { /* Free allocations done so far and kill path */ /* Kill path to one before walker (if any) */ @@ -433,16 +440,16 @@ static URI_INLINE UriBool URI_FUNC(MakeOwner)(URI_TYPE(Uri) * uri, if ((ranger->text.first != NULL) && (ranger->text.afterLast != NULL) && (ranger->text.afterLast > ranger->text.first)) { - free((URI_CHAR *)ranger->text.first); + memory->free(memory, (URI_CHAR *)ranger->text.first); } - free(ranger); + memory->free(memory, ranger); ranger = next; } /* Kill path from walker */ while (walker != NULL) { URI_TYPE(PathSegment) * const next = walker->next; - free(walker); + memory->free(memory, walker); walker = next; } @@ -458,7 +465,7 @@ static URI_INLINE UriBool URI_FUNC(MakeOwner)(URI_TYPE(Uri) * uri, /* Port text, must come last so we don't have to undo that one if it fails. * * Otherwise we would need and extra enum flag for it although the port * * cannot go unnormalized... */ - if (!URI_FUNC(MakeRangeOwner)(doneMask, 0, &(uri->portText))) { + if (!URI_FUNC(MakeRangeOwner)(doneMask, 0, &(uri->portText), memory)) { return URI_FALSE; /* Raises malloc error */ } @@ -468,23 +475,50 @@ static URI_INLINE UriBool URI_FUNC(MakeOwner)(URI_TYPE(Uri) * uri, unsigned int URI_FUNC(NormalizeSyntaxMaskRequired)(const URI_TYPE(Uri) * uri) { - unsigned int res; + unsigned int outMask = URI_NORMALIZED; /* for NULL uri */ + URI_FUNC(NormalizeSyntaxMaskRequiredEx)(uri, &outMask); + return outMask; +} + + + +int URI_FUNC(NormalizeSyntaxMaskRequiredEx)(const URI_TYPE(Uri) * uri, + unsigned int * outMask) { + UriMemoryManager * const memory = NULL; /* no use of memory manager */ + #if defined(__GNUC__) && ((__GNUC__ > 4) \ - || ((__GNUC__ == 4) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 2))) - /* Slower code that fixes a warning, not sure if this is a smart idea */ + || ((__GNUC__ == 4) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 2))) + /* Slower code that fixes a warning, not sure if this is a smart idea */ URI_TYPE(Uri) writeableClone; +#endif + + if ((uri == NULL) || (outMask == NULL)) { + return URI_ERROR_NULL; + } + +#if defined(__GNUC__) && ((__GNUC__ > 4) \ + || ((__GNUC__ == 4) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 2))) + /* Slower code that fixes a warning, not sure if this is a smart idea */ memcpy(&writeableClone, uri, 1 * sizeof(URI_TYPE(Uri))); - URI_FUNC(NormalizeSyntaxEngine)(&writeableClone, 0, &res); + URI_FUNC(NormalizeSyntaxEngine)(&writeableClone, 0, outMask, memory); #else - URI_FUNC(NormalizeSyntaxEngine)((URI_TYPE(Uri) *)uri, 0, &res); + URI_FUNC(NormalizeSyntaxEngine)((URI_TYPE(Uri) *)uri, 0, outMask, memory); #endif - return res; + return URI_SUCCESS; } int URI_FUNC(NormalizeSyntaxEx)(URI_TYPE(Uri) * uri, unsigned int mask) { - return URI_FUNC(NormalizeSyntaxEngine)(uri, mask, NULL); + return URI_FUNC(NormalizeSyntaxExMm)(uri, mask, NULL); +} + + + +int URI_FUNC(NormalizeSyntaxExMm)(URI_TYPE(Uri) * uri, unsigned int mask, + UriMemoryManager * memory) { + URI_CHECK_MEMORY_MANAGER(memory); /* may return */ + return URI_FUNC(NormalizeSyntaxEngine)(uri, mask, NULL, memory); } @@ -495,8 +529,16 @@ int URI_FUNC(NormalizeSyntax)(URI_TYPE(Uri) * uri) { -static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, unsigned int inMask, unsigned int * outMask) { +static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, + unsigned int inMask, unsigned int * outMask, + UriMemoryManager * memory) { unsigned int doneMask = URI_NORMALIZED; + + /* Not just doing inspection? -> memory manager required! */ + if (outMask == NULL) { + assert(memory != NULL); + } + if (uri == NULL) { if (outMask != NULL) { *outMask = URI_NORMALIZED; @@ -539,8 +581,8 @@ static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, unsig if (uri->owner) { URI_FUNC(LowercaseInplace)(uri->scheme.first, uri->scheme.afterLast); } else { - if (!URI_FUNC(LowercaseMalloc)(&(uri->scheme.first), &(uri->scheme.afterLast))) { - URI_FUNC(PreventLeakage)(uri, doneMask); + if (!URI_FUNC(LowercaseMalloc)(&(uri->scheme.first), &(uri->scheme.afterLast), memory)) { + URI_FUNC(PreventLeakage)(uri, doneMask, memory); return URI_ERROR_MALLOC; } doneMask |= URI_NORMALIZE_SCHEME; @@ -556,8 +598,8 @@ static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, unsig uri->hostData.ipFuture.afterLast); } else { if (!URI_FUNC(LowercaseMalloc)(&(uri->hostData.ipFuture.first), - &(uri->hostData.ipFuture.afterLast))) { - URI_FUNC(PreventLeakage)(uri, doneMask); + &(uri->hostData.ipFuture.afterLast), memory)) { + URI_FUNC(PreventLeakage)(uri, doneMask, memory); return URI_ERROR_MALLOC; } doneMask |= URI_NORMALIZE_HOST; @@ -574,8 +616,9 @@ static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, unsig } else { if (!URI_FUNC(FixPercentEncodingMalloc)( &(uri->hostText.first), - &(uri->hostText.afterLast))) { - URI_FUNC(PreventLeakage)(uri, doneMask); + &(uri->hostText.afterLast), + memory)) { + URI_FUNC(PreventLeakage)(uri, doneMask, memory); return URI_ERROR_MALLOC; } doneMask |= URI_NORMALIZE_HOST; @@ -600,8 +643,8 @@ static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, unsig URI_FUNC(FixPercentEncodingInplace)(uri->userInfo.first, &(uri->userInfo.afterLast)); } else { if (!URI_FUNC(FixPercentEncodingMalloc)(&(uri->userInfo.first), - &(uri->userInfo.afterLast))) { - URI_FUNC(PreventLeakage)(uri, doneMask); + &(uri->userInfo.afterLast), memory)) { + URI_FUNC(PreventLeakage)(uri, doneMask, memory); return URI_ERROR_MALLOC; } doneMask |= URI_NORMALIZE_USER_INFO; @@ -648,8 +691,8 @@ static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, unsig } else { while (walker != NULL) { if (!URI_FUNC(FixPercentEncodingMalloc)(&(walker->text.first), - &(walker->text.afterLast))) { - URI_FUNC(PreventLeakage)(uri, doneMask); + &(walker->text.afterLast), memory)) { + URI_FUNC(PreventLeakage)(uri, doneMask, memory); return URI_ERROR_MALLOC; } walker = walker->next; @@ -660,12 +703,12 @@ static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, unsig /* 6.2.2.3 Path Segment Normalization */ if (!URI_FUNC(RemoveDotSegmentsEx)(uri, relative, (uri->owner == URI_TRUE) - || ((doneMask & URI_NORMALIZE_PATH) != 0) - )) { - URI_FUNC(PreventLeakage)(uri, doneMask); + || ((doneMask & URI_NORMALIZE_PATH) != 0), + memory)) { + URI_FUNC(PreventLeakage)(uri, doneMask, memory); return URI_ERROR_MALLOC; } - URI_FUNC(FixEmptyTrailSegment)(uri); + URI_FUNC(FixEmptyTrailSegment)(uri, memory); } /* Query, fragment */ @@ -688,8 +731,8 @@ static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, unsig URI_FUNC(FixPercentEncodingInplace)(uri->query.first, &(uri->query.afterLast)); } else { if (!URI_FUNC(FixPercentEncodingMalloc)(&(uri->query.first), - &(uri->query.afterLast))) { - URI_FUNC(PreventLeakage)(uri, doneMask); + &(uri->query.afterLast), memory)) { + URI_FUNC(PreventLeakage)(uri, doneMask, memory); return URI_ERROR_MALLOC; } doneMask |= URI_NORMALIZE_QUERY; @@ -702,8 +745,8 @@ static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, unsig URI_FUNC(FixPercentEncodingInplace)(uri->fragment.first, &(uri->fragment.afterLast)); } else { if (!URI_FUNC(FixPercentEncodingMalloc)(&(uri->fragment.first), - &(uri->fragment.afterLast))) { - URI_FUNC(PreventLeakage)(uri, doneMask); + &(uri->fragment.afterLast), memory)) { + URI_FUNC(PreventLeakage)(uri, doneMask, memory); return URI_ERROR_MALLOC; } doneMask |= URI_NORMALIZE_FRAGMENT; @@ -713,8 +756,8 @@ static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, unsig /* Dup all not duped yet */ if ((outMask == NULL) && !uri->owner) { - if (!URI_FUNC(MakeOwner)(uri, &doneMask)) { - URI_FUNC(PreventLeakage)(uri, doneMask); + if (!URI_FUNC(MakeOwner)(uri, &doneMask, memory)) { + URI_FUNC(PreventLeakage)(uri, doneMask, memory); return URI_ERROR_MALLOC; } uri->owner = URI_TRUE; diff --git a/src/UriParse.c b/src/UriParse.c index e087753..f4bdda9 100644 --- a/src/UriParse.c +++ b/src/UriParse.c @@ -71,6 +71,7 @@ # include <uriparser/Uri.h> # include <uriparser/UriIp4.h> # include "UriCommon.h" +# include "UriMemory.h" # include "UriParseBase.h" #endif @@ -155,64 +156,70 @@ -static const URI_CHAR * URI_FUNC(ParseAuthority)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); +static const URI_CHAR * URI_FUNC(ParseAuthority)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParseAuthorityTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); static const URI_CHAR * URI_FUNC(ParseHexZero)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseHierPart)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseIpFutLoop)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseIpFutStopGo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseIpLit2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseMustBeSegmentNzNc)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseOwnHost)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseOwnHost2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseOwnHostUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseOwnHostUserInfoNz)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseOwnPortUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseOwnUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParsePartHelperTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParsePathAbsEmpty)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParsePathAbsNoLeadSlash)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParsePathRootless)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParsePchar)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParsePctEncoded)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParsePctSubUnres)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); +static const URI_CHAR * URI_FUNC(ParseHierPart)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParseIpFutLoop)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParseIpFutStopGo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParseIpLit2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParseMustBeSegmentNzNc)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParseOwnHost)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParseOwnHost2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParseOwnHostUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParseOwnHostUserInfoNz)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParseOwnPortUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParseOwnUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParsePartHelperTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParsePathAbsEmpty)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParsePathAbsNoLeadSlash)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParsePathRootless)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParsePchar)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParsePctEncoded)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParsePctSubUnres)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); static const URI_CHAR * URI_FUNC(ParsePort)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseQueryFrag)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseSegment)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseSegmentNz)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseSegmentNzNcOrScheme2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseUriReference)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseUriTail)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseUriTailTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); -static const URI_CHAR * URI_FUNC(ParseZeroMoreSlashSegs)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); - -static UriBool URI_FUNC(OnExitOwnHost2)(URI_TYPE(ParserState) * state, const URI_CHAR * first); -static UriBool URI_FUNC(OnExitOwnHostUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first); -static UriBool URI_FUNC(OnExitOwnPortUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first); -static UriBool URI_FUNC(OnExitSegmentNzNcOrScheme2)(URI_TYPE(ParserState) * state, const URI_CHAR * first); +static const URI_CHAR * URI_FUNC(ParseQueryFrag)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParseSegment)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParseSegmentNz)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParseSegmentNzNcOrScheme2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParseUriReference)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParseUriTail)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParseUriTailTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); +static const URI_CHAR * URI_FUNC(ParseZeroMoreSlashSegs)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory); + +static UriBool URI_FUNC(OnExitOwnHost2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, UriMemoryManager * memory); +static UriBool URI_FUNC(OnExitOwnHostUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, UriMemoryManager * memory); +static UriBool URI_FUNC(OnExitOwnPortUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, UriMemoryManager * memory); +static UriBool URI_FUNC(OnExitSegmentNzNcOrScheme2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, UriMemoryManager * memory); static void URI_FUNC(OnExitPartHelperTwo)(URI_TYPE(ParserState) * state); static void URI_FUNC(ResetParserStateExceptUri)(URI_TYPE(ParserState) * state); -static UriBool URI_FUNC(PushPathSegment)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast); +static UriBool URI_FUNC(PushPathSegment)(URI_TYPE(ParserState) * state, + const URI_CHAR * first, const URI_CHAR * afterLast, + UriMemoryManager * memory); -static void URI_FUNC(StopSyntax)(URI_TYPE(ParserState) * state, const URI_CHAR * errorPos); -static void URI_FUNC(StopMalloc)(URI_TYPE(ParserState) * state); +static void URI_FUNC(StopSyntax)(URI_TYPE(ParserState) * state, const URI_CHAR * errorPos, UriMemoryManager * memory); +static void URI_FUNC(StopMalloc)(URI_TYPE(ParserState) * state, UriMemoryManager * memory); + +static int URI_FUNC(ParseUriExMm)(URI_TYPE(ParserState) * state, + const URI_CHAR * first, const URI_CHAR * afterLast, + UriMemoryManager * memory); static URI_INLINE void URI_FUNC(StopSyntax)(URI_TYPE(ParserState) * state, - const URI_CHAR * errorPos) { - URI_FUNC(FreeUriMembers)(state->uri); + const URI_CHAR * errorPos, UriMemoryManager * memory) { + URI_FUNC(FreeUriMembersMm)(state->uri, memory); state->errorPos = errorPos; state->errorCode = URI_ERROR_SYNTAX; } -static URI_INLINE void URI_FUNC(StopMalloc)(URI_TYPE(ParserState) * state) { - URI_FUNC(FreeUriMembers)(state->uri); +static URI_INLINE void URI_FUNC(StopMalloc)(URI_TYPE(ParserState) * state, UriMemoryManager * memory) { + URI_FUNC(FreeUriMembersMm)(state->uri, memory); state->errorPos = NULL; state->errorCode = URI_ERROR_MALLOC; } @@ -224,7 +231,9 @@ static URI_INLINE void URI_FUNC(StopMalloc)(URI_TYPE(ParserState) * state) { * [authority]->[ownHostUserInfoNz] * [authority]-><NULL> */ -static URI_INLINE const URI_CHAR * URI_FUNC(ParseAuthority)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static URI_INLINE const URI_CHAR * URI_FUNC(ParseAuthority)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { /* "" regname host */ state->uri->hostText.first = URI_FUNC(SafeToPointTo); @@ -236,7 +245,7 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseAuthority)(URI_TYPE(ParserState case _UT('['): { const URI_CHAR * const afterIpLit2 - = URI_FUNC(ParseIpLit2)(state, first + 1, afterLast); + = URI_FUNC(ParseIpLit2)(state, first + 1, afterLast, memory); if (afterIpLit2 == NULL) { return NULL; } @@ -265,7 +274,7 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseAuthority)(URI_TYPE(ParserState case URI_SET_DIGIT: case URI_SET_ALPHA: state->uri->userInfo.first = first; /* USERINFO BEGIN */ - return URI_FUNC(ParseOwnHostUserInfoNz)(state, first, afterLast); + return URI_FUNC(ParseOwnHostUserInfoNz)(state, first, afterLast, memory); default: /* "" regname host */ @@ -330,7 +339,9 @@ static const URI_CHAR * URI_FUNC(ParseHexZero)(URI_TYPE(ParserState) * state, co * [hierPart]-></>[partHelperTwo] * [hierPart]-><NULL> */ -static URI_INLINE const URI_CHAR * URI_FUNC(ParseHierPart)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static URI_INLINE const URI_CHAR * URI_FUNC(ParseHierPart)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { return afterLast; } @@ -356,10 +367,10 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseHierPart)(URI_TYPE(ParserState) case _UT('='): case URI_SET_DIGIT: case URI_SET_ALPHA: - return URI_FUNC(ParsePathRootless)(state, first, afterLast); + return URI_FUNC(ParsePathRootless)(state, first, afterLast, memory); case _UT('/'): - return URI_FUNC(ParsePartHelperTwo)(state, first + 1, afterLast); + return URI_FUNC(ParsePartHelperTwo)(state, first + 1, afterLast, memory); default: return first; @@ -373,9 +384,11 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseHierPart)(URI_TYPE(ParserState) * [ipFutLoop]->[unreserved][ipFutStopGo] * [ipFutLoop]-><:>[ipFutStopGo] */ -static const URI_CHAR * URI_FUNC(ParseIpFutLoop)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static const URI_CHAR * URI_FUNC(ParseIpFutLoop)(URI_TYPE(ParserState) * state, + const URI_CHAR * first, const URI_CHAR * afterLast, + UriMemoryManager * memory) { if (first >= afterLast) { - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } @@ -398,10 +411,10 @@ static const URI_CHAR * URI_FUNC(ParseIpFutLoop)(URI_TYPE(ParserState) * state, case _UT('='): case URI_SET_DIGIT: case URI_SET_ALPHA: - return URI_FUNC(ParseIpFutStopGo)(state, first + 1, afterLast); + return URI_FUNC(ParseIpFutStopGo)(state, first + 1, afterLast, memory); default: - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } } @@ -412,7 +425,10 @@ static const URI_CHAR * URI_FUNC(ParseIpFutLoop)(URI_TYPE(ParserState) * state, * [ipFutStopGo]->[ipFutLoop] * [ipFutStopGo]-><NULL> */ -static const URI_CHAR * URI_FUNC(ParseIpFutStopGo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static const URI_CHAR * URI_FUNC(ParseIpFutStopGo)( + URI_TYPE(ParserState) * state, + const URI_CHAR * first, const URI_CHAR * afterLast, + UriMemoryManager * memory) { if (first >= afterLast) { return afterLast; } @@ -436,7 +452,7 @@ static const URI_CHAR * URI_FUNC(ParseIpFutStopGo)(URI_TYPE(ParserState) * state case _UT('='): case URI_SET_DIGIT: case URI_SET_ALPHA: - return URI_FUNC(ParseIpFutLoop)(state, first, afterLast); + return URI_FUNC(ParseIpFutLoop)(state, first, afterLast, memory); default: return first; @@ -448,9 +464,11 @@ static const URI_CHAR * URI_FUNC(ParseIpFutStopGo)(URI_TYPE(ParserState) * state /* * [ipFuture]-><v>[HEXDIG][hexZero]<.>[ipFutLoop] */ -static const URI_CHAR * URI_FUNC(ParseIpFuture)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static const URI_CHAR * URI_FUNC(ParseIpFuture)(URI_TYPE(ParserState) * state, + const URI_CHAR * first, const URI_CHAR * afterLast, + UriMemoryManager * memory) { if (first >= afterLast) { - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } @@ -462,7 +480,7 @@ static const URI_CHAR * URI_FUNC(ParseIpFuture)(URI_TYPE(ParserState) * state, c case _UT('v'): */ if (first + 1 >= afterLast) { - URI_FUNC(StopSyntax)(state, first + 1); + URI_FUNC(StopSyntax)(state, first + 1, memory); return NULL; } @@ -477,12 +495,12 @@ static const URI_CHAR * URI_FUNC(ParseIpFuture)(URI_TYPE(ParserState) * state, c } if ((afterHexZero >= afterLast) || (*afterHexZero != _UT('.'))) { - URI_FUNC(StopSyntax)(state, afterHexZero); + URI_FUNC(StopSyntax)(state, afterHexZero, memory); return NULL; } state->uri->hostText.first = first; /* HOST BEGIN */ state->uri->hostData.ipFuture.first = first; /* IPFUTURE BEGIN */ - afterIpFutLoop = URI_FUNC(ParseIpFutLoop)(state, afterHexZero + 1, afterLast); + afterIpFutLoop = URI_FUNC(ParseIpFutLoop)(state, afterHexZero + 1, afterLast, memory); if (afterIpFutLoop == NULL) { return NULL; } @@ -492,13 +510,13 @@ static const URI_CHAR * URI_FUNC(ParseIpFuture)(URI_TYPE(ParserState) * state, c } default: - URI_FUNC(StopSyntax)(state, first + 1); + URI_FUNC(StopSyntax)(state, first + 1, memory); return NULL; } /* default: - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } */ @@ -510,9 +528,11 @@ static const URI_CHAR * URI_FUNC(ParseIpFuture)(URI_TYPE(ParserState) * state, c * [ipLit2]->[ipFuture]<]> * [ipLit2]->[IPv6address2] */ -static URI_INLINE const URI_CHAR * URI_FUNC(ParseIpLit2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static URI_INLINE const URI_CHAR * URI_FUNC(ParseIpLit2)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } @@ -520,13 +540,13 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseIpLit2)(URI_TYPE(ParserState) * case _UT('v'): { const URI_CHAR * const afterIpFuture - = URI_FUNC(ParseIpFuture)(state, first, afterLast); + = URI_FUNC(ParseIpFuture)(state, first, afterLast, memory); if (afterIpFuture == NULL) { return NULL; } if ((afterIpFuture >= afterLast) || (*afterIpFuture != _UT(']'))) { - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } return afterIpFuture + 1; @@ -535,15 +555,15 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseIpLit2)(URI_TYPE(ParserState) * case _UT(':'): case _UT(']'): case URI_SET_HEXDIG: - state->uri->hostData.ip6 = malloc(1 * sizeof(UriIp6)); /* Freed when stopping on parse error */ + state->uri->hostData.ip6 = memory->malloc(memory, 1 * sizeof(UriIp6)); /* Freed when stopping on parse error */ if (state->uri->hostData.ip6 == NULL) { - URI_FUNC(StopMalloc)(state); + URI_FUNC(StopMalloc)(state, memory); return NULL; } - return URI_FUNC(ParseIPv6address2)(state, first, afterLast); + return URI_FUNC(ParseIPv6address2)(state, first, afterLast, memory); default: - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } } @@ -553,7 +573,10 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseIpLit2)(URI_TYPE(ParserState) * /* * [IPv6address2]->..<]> */ -static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static const URI_CHAR * URI_FUNC(ParseIPv6address2)( + URI_TYPE(ParserState) * state, + const URI_CHAR * first, const URI_CHAR * afterLast, + UriMemoryManager * memory) { int zipperEver = 0; int quadsDone = 0; int digitCount = 0; @@ -566,7 +589,7 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat for (;;) { if (first >= afterLast) { - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } @@ -577,7 +600,7 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat switch (*first) { case URI_SET_DIGIT: if (digitCount == 4) { - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } digitHistory[digitCount++] = (unsigned char)(9 + *first - _UT('9')); @@ -588,17 +611,17 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat || (digitCount == 0) || (digitCount == 4)) { /* Invalid digit or octet count */ - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } else if ((digitCount > 1) && (digitHistory[0] == 0)) { /* Leading zero */ - URI_FUNC(StopSyntax)(state, first - digitCount); + URI_FUNC(StopSyntax)(state, first - digitCount, memory); return NULL; } else if ((digitCount > 2) && (digitHistory[1] == 0)) { /* Leading zero */ - URI_FUNC(StopSyntax)(state, first - digitCount + 1); + URI_FUNC(StopSyntax)(state, first - digitCount + 1, memory); return NULL; } else if ((digitCount == 3) && (100 * digitHistory[0] @@ -606,11 +629,11 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat + digitHistory[2] > 255)) { /* Octet value too large */ if (digitHistory[0] > 2) { - URI_FUNC(StopSyntax)(state, first - 3); + URI_FUNC(StopSyntax)(state, first - 3, memory); } else if (digitHistory[1] > 5) { - URI_FUNC(StopSyntax)(state, first - 2); + URI_FUNC(StopSyntax)(state, first - 2, memory); } else { - URI_FUNC(StopSyntax)(state, first - 1); + URI_FUNC(StopSyntax)(state, first - 1, memory); } return NULL; } @@ -626,17 +649,17 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat || (digitCount == 0) || (digitCount == 4)) { /* Invalid digit or octet count */ - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } else if ((digitCount > 1) && (digitHistory[0] == 0)) { /* Leading zero */ - URI_FUNC(StopSyntax)(state, first - digitCount); + URI_FUNC(StopSyntax)(state, first - digitCount, memory); return NULL; } else if ((digitCount > 2) && (digitHistory[1] == 0)) { /* Leading zero */ - URI_FUNC(StopSyntax)(state, first - digitCount + 1); + URI_FUNC(StopSyntax)(state, first - digitCount + 1, memory); return NULL; } else if ((digitCount == 3) && (100 * digitHistory[0] @@ -644,11 +667,11 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat + digitHistory[2] > 255)) { /* Octet value too large */ if (digitHistory[0] > 2) { - URI_FUNC(StopSyntax)(state, first - 3); + URI_FUNC(StopSyntax)(state, first - 3, memory); } else if (digitHistory[1] > 5) { - URI_FUNC(StopSyntax)(state, first - 2); + URI_FUNC(StopSyntax)(state, first - 2, memory); } else { - URI_FUNC(StopSyntax)(state, first - 1); + URI_FUNC(StopSyntax)(state, first - 1, memory); } return NULL; } @@ -665,7 +688,7 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat return first + 1; default: - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } first++; @@ -679,7 +702,7 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat case URI_SET_HEX_LETTER_LOWER: letterAmong = 1; if (digitCount == 4) { - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } digitHistory[digitCount] = (unsigned char)(15 + *first - _UT('f')); @@ -689,7 +712,7 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat case URI_SET_HEX_LETTER_UPPER: letterAmong = 1; if (digitCount == 4) { - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } digitHistory[digitCount] = (unsigned char)(15 + *first - _UT('F')); @@ -698,7 +721,7 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat case URI_SET_DIGIT: if (digitCount == 4) { - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } digitHistory[digitCount] = (unsigned char)(9 + *first - _UT('9')); @@ -723,13 +746,13 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat /* Too many quads? */ if (quadsDone >= 8 - zipperEver) { - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } /* "::"? */ if (first + 1 >= afterLast) { - URI_FUNC(StopSyntax)(state, first + 1); + URI_FUNC(StopSyntax)(state, first + 1, memory); return NULL; } if (first[1] == _UT(':')) { @@ -737,7 +760,7 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat first++; if (zipperEver) { - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; /* "::.+::" */ } @@ -747,11 +770,11 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat /* ":::+"? */ if (first + 1 >= afterLast) { - URI_FUNC(StopSyntax)(state, first + 1); + URI_FUNC(StopSyntax)(state, first + 1, memory); return NULL; /* No ']' yet */ } if (first[1] == _UT(':')) { - URI_FUNC(StopSyntax)(state, first + 1); + URI_FUNC(StopSyntax)(state, first + 1, memory); return NULL; /* ":::+ "*/ } } @@ -769,17 +792,17 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat || (digitCount == 0) || (digitCount == 4)) { /* Invalid octet before */ - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } else if ((digitCount > 1) && (digitHistory[0] == 0)) { /* Leading zero */ - URI_FUNC(StopSyntax)(state, first - digitCount); + URI_FUNC(StopSyntax)(state, first - digitCount, memory); return NULL; } else if ((digitCount > 2) && (digitHistory[1] == 0)) { /* Leading zero */ - URI_FUNC(StopSyntax)(state, first - digitCount + 1); + URI_FUNC(StopSyntax)(state, first - digitCount + 1, memory); return NULL; } else if ((digitCount == 3) && (100 * digitHistory[0] @@ -787,11 +810,11 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat + digitHistory[2] > 255)) { /* Octet value too large */ if (digitHistory[0] > 2) { - URI_FUNC(StopSyntax)(state, first - 3); + URI_FUNC(StopSyntax)(state, first - 3, memory); } else if (digitHistory[1] > 5) { - URI_FUNC(StopSyntax)(state, first - 2); + URI_FUNC(StopSyntax)(state, first - 2, memory); } else { - URI_FUNC(StopSyntax)(state, first - 1); + URI_FUNC(StopSyntax)(state, first - 1, memory); } return NULL; } @@ -808,7 +831,7 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat case _UT(']'): /* Too little quads? */ if (!zipperEver && !((quadsDone == 7) && (digitCount > 0))) { - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } @@ -833,13 +856,13 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat return first + 1; /* Fine */ default: - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } first++; if (first >= afterLast) { - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; /* No ']' yet */ } } while (walking); @@ -857,10 +880,12 @@ static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * stat * [mustBeSegmentNzNc]-></>[segment][zeroMoreSlashSegs][uriTail] * [mustBeSegmentNzNc]-><@>[mustBeSegmentNzNc] */ -static const URI_CHAR * URI_FUNC(ParseMustBeSegmentNzNc)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static const URI_CHAR * URI_FUNC(ParseMustBeSegmentNzNc)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { - if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first)) { /* SEGMENT BOTH */ - URI_FUNC(StopMalloc)(state); + if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first, memory)) { /* SEGMENT BOTH */ + URI_FUNC(StopMalloc)(state, memory); return NULL; } state->uri->scheme.first = NULL; /* Not a scheme, reset */ @@ -871,11 +896,11 @@ static const URI_CHAR * URI_FUNC(ParseMustBeSegmentNzNc)(URI_TYPE(ParserState) * case _UT('%'): { const URI_CHAR * const afterPctEncoded - = URI_FUNC(ParsePctEncoded)(state, first, afterLast); + = URI_FUNC(ParsePctEncoded)(state, first, afterLast, memory); if (afterPctEncoded == NULL) { return NULL; } - return URI_FUNC(ParseMustBeSegmentNzNc)(state, afterPctEncoded, afterLast); + return URI_FUNC(ParseMustBeSegmentNzNc)(state, afterPctEncoded, afterLast, memory); } case _UT('@'): @@ -896,40 +921,40 @@ static const URI_CHAR * URI_FUNC(ParseMustBeSegmentNzNc)(URI_TYPE(ParserState) * case _UT('~'): case URI_SET_DIGIT: case URI_SET_ALPHA: - return URI_FUNC(ParseMustBeSegmentNzNc)(state, first + 1, afterLast); + return URI_FUNC(ParseMustBeSegmentNzNc)(state, first + 1, afterLast, memory); case _UT('/'): { const URI_CHAR * afterZeroMoreSlashSegs; const URI_CHAR * afterSegment; - if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first)) { /* SEGMENT BOTH */ - URI_FUNC(StopMalloc)(state); + if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first, memory)) { /* SEGMENT BOTH */ + URI_FUNC(StopMalloc)(state, memory); return NULL; } state->uri->scheme.first = NULL; /* Not a scheme, reset */ - afterSegment = URI_FUNC(ParseSegment)(state, first + 1, afterLast); + afterSegment = URI_FUNC(ParseSegment)(state, first + 1, afterLast, memory); if (afterSegment == NULL) { return NULL; } - if (!URI_FUNC(PushPathSegment)(state, first + 1, afterSegment)) { /* SEGMENT BOTH */ - URI_FUNC(StopMalloc)(state); + if (!URI_FUNC(PushPathSegment)(state, first + 1, afterSegment, memory)) { /* SEGMENT BOTH */ + URI_FUNC(StopMalloc)(state, memory); return NULL; } afterZeroMoreSlashSegs - = URI_FUNC(ParseZeroMoreSlashSegs)(state, afterSegment, afterLast); + = URI_FUNC(ParseZeroMoreSlashSegs)(state, afterSegment, afterLast, memory); if (afterZeroMoreSlashSegs == NULL) { return NULL; } - return URI_FUNC(ParseUriTail)(state, afterZeroMoreSlashSegs, afterLast); + return URI_FUNC(ParseUriTail)(state, afterZeroMoreSlashSegs, afterLast, memory); } default: - if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first)) { /* SEGMENT BOTH */ - URI_FUNC(StopMalloc)(state); + if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first, memory)) { /* SEGMENT BOTH */ + URI_FUNC(StopMalloc)(state, memory); return NULL; } state->uri->scheme.first = NULL; /* Not a scheme, reset */ - return URI_FUNC(ParseUriTail)(state, first, afterLast); + return URI_FUNC(ParseUriTail)(state, first, afterLast, memory); } } @@ -939,7 +964,9 @@ static const URI_CHAR * URI_FUNC(ParseMustBeSegmentNzNc)(URI_TYPE(ParserState) * * [ownHost]-><[>[ipLit2][authorityTwo] * [ownHost]->[ownHost2] // can take <NULL> */ -static URI_INLINE const URI_CHAR * URI_FUNC(ParseOwnHost)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static URI_INLINE const URI_CHAR * URI_FUNC(ParseOwnHost)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { state->uri->hostText.afterLast = afterLast; /* HOST END */ return afterLast; @@ -949,7 +976,7 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseOwnHost)(URI_TYPE(ParserState) case _UT('['): { const URI_CHAR * const afterIpLit2 - = URI_FUNC(ParseIpLit2)(state, first + 1, afterLast); + = URI_FUNC(ParseIpLit2)(state, first + 1, afterLast, memory); if (afterIpLit2 == NULL) { return NULL; } @@ -958,24 +985,26 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseOwnHost)(URI_TYPE(ParserState) } default: - return URI_FUNC(ParseOwnHost2)(state, first, afterLast); + return URI_FUNC(ParseOwnHost2)(state, first, afterLast, memory); } } -static URI_INLINE UriBool URI_FUNC(OnExitOwnHost2)(URI_TYPE(ParserState) * state, const URI_CHAR * first) { +static URI_INLINE UriBool URI_FUNC(OnExitOwnHost2)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + UriMemoryManager * memory) { state->uri->hostText.afterLast = first; /* HOST END */ /* Valid IPv4 or just a regname? */ - state->uri->hostData.ip4 = malloc(1 * sizeof(UriIp4)); /* Freed when stopping on parse error */ + state->uri->hostData.ip4 = memory->malloc(memory, 1 * sizeof(UriIp4)); /* Freed when stopping on parse error */ if (state->uri->hostData.ip4 == NULL) { return URI_FALSE; /* Raises malloc error */ } if (URI_FUNC(ParseIpFourAddress)(state->uri->hostData.ip4->data, state->uri->hostText.first, state->uri->hostText.afterLast)) { /* Not IPv4 */ - free(state->uri->hostData.ip4); + memory->free(memory, state->uri->hostData.ip4); state->uri->hostData.ip4 = NULL; } return URI_TRUE; /* Success */ @@ -987,10 +1016,12 @@ static URI_INLINE UriBool URI_FUNC(OnExitOwnHost2)(URI_TYPE(ParserState) * state * [ownHost2]->[authorityTwo] // can take <NULL> * [ownHost2]->[pctSubUnres][ownHost2] */ -static const URI_CHAR * URI_FUNC(ParseOwnHost2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static const URI_CHAR * URI_FUNC(ParseOwnHost2)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { - if (!URI_FUNC(OnExitOwnHost2)(state, first)) { - URI_FUNC(StopMalloc)(state); + if (!URI_FUNC(OnExitOwnHost2)(state, first, memory)) { + URI_FUNC(StopMalloc)(state, memory); return NULL; } return afterLast; @@ -1017,16 +1048,16 @@ static const URI_CHAR * URI_FUNC(ParseOwnHost2)(URI_TYPE(ParserState) * state, c case URI_SET_ALPHA: { const URI_CHAR * const afterPctSubUnres - = URI_FUNC(ParsePctSubUnres)(state, first, afterLast); + = URI_FUNC(ParsePctSubUnres)(state, first, afterLast, memory); if (afterPctSubUnres == NULL) { return NULL; } - return URI_FUNC(ParseOwnHost2)(state, afterPctSubUnres, afterLast); + return URI_FUNC(ParseOwnHost2)(state, afterPctSubUnres, afterLast, memory); } default: - if (!URI_FUNC(OnExitOwnHost2)(state, first)) { - URI_FUNC(StopMalloc)(state); + if (!URI_FUNC(OnExitOwnHost2)(state, first, memory)) { + URI_FUNC(StopMalloc)(state, memory); return NULL; } return URI_FUNC(ParseAuthorityTwo)(state, first, afterLast); @@ -1035,20 +1066,22 @@ static const URI_CHAR * URI_FUNC(ParseOwnHost2)(URI_TYPE(ParserState) * state, c -static URI_INLINE UriBool URI_FUNC(OnExitOwnHostUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first) { +static URI_INLINE UriBool URI_FUNC(OnExitOwnHostUserInfo)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + UriMemoryManager * memory) { state->uri->hostText.first = state->uri->userInfo.first; /* Host instead of userInfo, update */ state->uri->userInfo.first = NULL; /* Not a userInfo, reset */ state->uri->hostText.afterLast = first; /* HOST END */ /* Valid IPv4 or just a regname? */ - state->uri->hostData.ip4 = malloc(1 * sizeof(UriIp4)); /* Freed when stopping on parse error */ + state->uri->hostData.ip4 = memory->malloc(memory, 1 * sizeof(UriIp4)); /* Freed when stopping on parse error */ if (state->uri->hostData.ip4 == NULL) { return URI_FALSE; /* Raises malloc error */ } if (URI_FUNC(ParseIpFourAddress)(state->uri->hostData.ip4->data, state->uri->hostText.first, state->uri->hostText.afterLast)) { /* Not IPv4 */ - free(state->uri->hostData.ip4); + memory->free(memory, state->uri->hostData.ip4); state->uri->hostData.ip4 = NULL; } return URI_TRUE; /* Success */ @@ -1060,10 +1093,12 @@ static URI_INLINE UriBool URI_FUNC(OnExitOwnHostUserInfo)(URI_TYPE(ParserState) * [ownHostUserInfo]->[ownHostUserInfoNz] * [ownHostUserInfo]-><NULL> */ -static URI_INLINE const URI_CHAR * URI_FUNC(ParseOwnHostUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static URI_INLINE const URI_CHAR * URI_FUNC(ParseOwnHostUserInfo)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { - if (!URI_FUNC(OnExitOwnHostUserInfo)(state, first)) { - URI_FUNC(StopMalloc)(state); + if (!URI_FUNC(OnExitOwnHostUserInfo)(state, first, memory)) { + URI_FUNC(StopMalloc)(state, memory); return NULL; } return afterLast; @@ -1090,11 +1125,11 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseOwnHostUserInfo)(URI_TYPE(Parse case _UT('='): case URI_SET_DIGIT: case URI_SET_ALPHA: - return URI_FUNC(ParseOwnHostUserInfoNz)(state, first, afterLast); + return URI_FUNC(ParseOwnHostUserInfoNz)(state, first, afterLast, memory); default: - if (!URI_FUNC(OnExitOwnHostUserInfo)(state, first)) { - URI_FUNC(StopMalloc)(state); + if (!URI_FUNC(OnExitOwnHostUserInfo)(state, first, memory)) { + URI_FUNC(StopMalloc)(state, memory); return NULL; } return first; @@ -1108,9 +1143,11 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseOwnHostUserInfo)(URI_TYPE(Parse * [ownHostUserInfoNz]-><:>[ownPortUserInfo] * [ownHostUserInfoNz]-><@>[ownHost] */ -static const URI_CHAR * URI_FUNC(ParseOwnHostUserInfoNz)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static const URI_CHAR * URI_FUNC(ParseOwnHostUserInfoNz)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } @@ -1135,45 +1172,47 @@ static const URI_CHAR * URI_FUNC(ParseOwnHostUserInfoNz)(URI_TYPE(ParserState) * case URI_SET_ALPHA: { const URI_CHAR * const afterPctSubUnres - = URI_FUNC(ParsePctSubUnres)(state, first, afterLast); + = URI_FUNC(ParsePctSubUnres)(state, first, afterLast, memory); if (afterPctSubUnres == NULL) { return NULL; } - return URI_FUNC(ParseOwnHostUserInfo)(state, afterPctSubUnres, afterLast); + return URI_FUNC(ParseOwnHostUserInfo)(state, afterPctSubUnres, afterLast, memory); } case _UT(':'): state->uri->hostText.afterLast = first; /* HOST END */ state->uri->portText.first = first + 1; /* PORT BEGIN */ - return URI_FUNC(ParseOwnPortUserInfo)(state, first + 1, afterLast); + return URI_FUNC(ParseOwnPortUserInfo)(state, first + 1, afterLast, memory); case _UT('@'): state->uri->userInfo.afterLast = first; /* USERINFO END */ state->uri->hostText.first = first + 1; /* HOST BEGIN */ - return URI_FUNC(ParseOwnHost)(state, first + 1, afterLast); + return URI_FUNC(ParseOwnHost)(state, first + 1, afterLast, memory); default: - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } } -static URI_INLINE UriBool URI_FUNC(OnExitOwnPortUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first) { +static URI_INLINE UriBool URI_FUNC(OnExitOwnPortUserInfo)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + UriMemoryManager * memory) { state->uri->hostText.first = state->uri->userInfo.first; /* Host instead of userInfo, update */ state->uri->userInfo.first = NULL; /* Not a userInfo, reset */ state->uri->portText.afterLast = first; /* PORT END */ /* Valid IPv4 or just a regname? */ - state->uri->hostData.ip4 = malloc(1 * sizeof(UriIp4)); /* Freed when stopping on parse error */ + state->uri->hostData.ip4 = memory->malloc(memory, 1 * sizeof(UriIp4)); /* Freed when stopping on parse error */ if (state->uri->hostData.ip4 == NULL) { return URI_FALSE; /* Raises malloc error */ } if (URI_FUNC(ParseIpFourAddress)(state->uri->hostData.ip4->data, state->uri->hostText.first, state->uri->hostText.afterLast)) { /* Not IPv4 */ - free(state->uri->hostData.ip4); + memory->free(memory, state->uri->hostData.ip4); state->uri->hostData.ip4 = NULL; } return URI_TRUE; /* Success */ @@ -1194,10 +1233,12 @@ static URI_INLINE UriBool URI_FUNC(OnExitOwnPortUserInfo)(URI_TYPE(ParserState) * [ownPortUserInfo]-><@>[ownHost] * [ownPortUserInfo]-><NULL> */ -static const URI_CHAR * URI_FUNC(ParseOwnPortUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static const URI_CHAR * URI_FUNC(ParseOwnPortUserInfo)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { - if (!URI_FUNC(OnExitOwnPortUserInfo)(state, first)) { - URI_FUNC(StopMalloc)(state); + if (!URI_FUNC(OnExitOwnPortUserInfo)(state, first, memory)) { + URI_FUNC(StopMalloc)(state, memory); return NULL; } return afterLast; @@ -1227,20 +1268,20 @@ static const URI_CHAR * URI_FUNC(ParseOwnPortUserInfo)(URI_TYPE(ParserState) * s case URI_SET_ALPHA: state->uri->hostText.afterLast = NULL; /* Not a host, reset */ state->uri->portText.first = NULL; /* Not a port, reset */ - return URI_FUNC(ParseOwnUserInfo)(state, first + 1, afterLast); + return URI_FUNC(ParseOwnUserInfo)(state, first + 1, afterLast, memory); case URI_SET_DIGIT: - return URI_FUNC(ParseOwnPortUserInfo)(state, first + 1, afterLast); + return URI_FUNC(ParseOwnPortUserInfo)(state, first + 1, afterLast, memory); case _UT('%'): state->uri->portText.first = NULL; /* Not a port, reset */ { const URI_CHAR * const afterPct - = URI_FUNC(ParsePctEncoded)(state, first, afterLast); + = URI_FUNC(ParsePctEncoded)(state, first, afterLast, memory); if (afterPct == NULL) { return NULL; } - return URI_FUNC(ParseOwnUserInfo)(state, afterPct, afterLast); + return URI_FUNC(ParseOwnUserInfo)(state, afterPct, afterLast, memory); } case _UT('@'): @@ -1248,11 +1289,11 @@ static const URI_CHAR * URI_FUNC(ParseOwnPortUserInfo)(URI_TYPE(ParserState) * s state->uri->portText.first = NULL; /* Not a port, reset */ state->uri->userInfo.afterLast = first; /* USERINFO END */ state->uri->hostText.first = first + 1; /* HOST BEGIN */ - return URI_FUNC(ParseOwnHost)(state, first + 1, afterLast); + return URI_FUNC(ParseOwnHost)(state, first + 1, afterLast, memory); default: - if (!URI_FUNC(OnExitOwnPortUserInfo)(state, first)) { - URI_FUNC(StopMalloc)(state); + if (!URI_FUNC(OnExitOwnPortUserInfo)(state, first, memory)) { + URI_FUNC(StopMalloc)(state, memory); return NULL; } return first; @@ -1266,9 +1307,11 @@ static const URI_CHAR * URI_FUNC(ParseOwnPortUserInfo)(URI_TYPE(ParserState) * s * [ownUserInfo]-><:>[ownUserInfo] * [ownUserInfo]-><@>[ownHost] */ -static const URI_CHAR * URI_FUNC(ParseOwnUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static const URI_CHAR * URI_FUNC(ParseOwnUserInfo)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } @@ -1293,24 +1336,24 @@ static const URI_CHAR * URI_FUNC(ParseOwnUserInfo)(URI_TYPE(ParserState) * state case URI_SET_ALPHA: { const URI_CHAR * const afterPctSubUnres - = URI_FUNC(ParsePctSubUnres)(state, first, afterLast); + = URI_FUNC(ParsePctSubUnres)(state, first, afterLast, memory); if (afterPctSubUnres == NULL) { return NULL; } - return URI_FUNC(ParseOwnUserInfo)(state, afterPctSubUnres, afterLast); + return URI_FUNC(ParseOwnUserInfo)(state, afterPctSubUnres, afterLast, memory); } case _UT(':'): - return URI_FUNC(ParseOwnUserInfo)(state, first + 1, afterLast); + return URI_FUNC(ParseOwnUserInfo)(state, first + 1, afterLast, memory); case _UT('@'): /* SURE */ state->uri->userInfo.afterLast = first; /* USERINFO END */ state->uri->hostText.first = first + 1; /* HOST BEGIN */ - return URI_FUNC(ParseOwnHost)(state, first + 1, afterLast); + return URI_FUNC(ParseOwnHost)(state, first + 1, afterLast, memory); default: - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } } @@ -1327,7 +1370,9 @@ static URI_INLINE void URI_FUNC(OnExitPartHelperTwo)(URI_TYPE(ParserState) * sta * [partHelperTwo]->[pathAbsNoLeadSlash] // can take <NULL> * [partHelperTwo]-></>[authority][pathAbsEmpty] */ -static URI_INLINE const URI_CHAR * URI_FUNC(ParsePartHelperTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static URI_INLINE const URI_CHAR * URI_FUNC(ParsePartHelperTwo)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { URI_FUNC(OnExitPartHelperTwo)(state); return afterLast; @@ -1337,21 +1382,21 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParsePartHelperTwo)(URI_TYPE(ParserS case _UT('/'): { const URI_CHAR * const afterAuthority - = URI_FUNC(ParseAuthority)(state, first + 1, afterLast); + = URI_FUNC(ParseAuthority)(state, first + 1, afterLast, memory); const URI_CHAR * afterPathAbsEmpty; if (afterAuthority == NULL) { return NULL; } - afterPathAbsEmpty = URI_FUNC(ParsePathAbsEmpty)(state, afterAuthority, afterLast); + afterPathAbsEmpty = URI_FUNC(ParsePathAbsEmpty)(state, afterAuthority, afterLast, memory); - URI_FUNC(FixEmptyTrailSegment)(state->uri); + URI_FUNC(FixEmptyTrailSegment)(state->uri, memory); return afterPathAbsEmpty; } default: URI_FUNC(OnExitPartHelperTwo)(state); - return URI_FUNC(ParsePathAbsNoLeadSlash)(state, first, afterLast); + return URI_FUNC(ParsePathAbsNoLeadSlash)(state, first, afterLast, memory); } } @@ -1361,7 +1406,9 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParsePartHelperTwo)(URI_TYPE(ParserS * [pathAbsEmpty]-></>[segment][pathAbsEmpty] * [pathAbsEmpty]-><NULL> */ -static const URI_CHAR * URI_FUNC(ParsePathAbsEmpty)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static const URI_CHAR * URI_FUNC(ParsePathAbsEmpty)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { return afterLast; } @@ -1370,15 +1417,15 @@ static const URI_CHAR * URI_FUNC(ParsePathAbsEmpty)(URI_TYPE(ParserState) * stat case _UT('/'): { const URI_CHAR * const afterSegment - = URI_FUNC(ParseSegment)(state, first + 1, afterLast); + = URI_FUNC(ParseSegment)(state, first + 1, afterLast, memory); if (afterSegment == NULL) { return NULL; } - if (!URI_FUNC(PushPathSegment)(state, first + 1, afterSegment)) { /* SEGMENT BOTH */ - URI_FUNC(StopMalloc)(state); + if (!URI_FUNC(PushPathSegment)(state, first + 1, afterSegment, memory)) { /* SEGMENT BOTH */ + URI_FUNC(StopMalloc)(state, memory); return NULL; } - return URI_FUNC(ParsePathAbsEmpty)(state, afterSegment, afterLast); + return URI_FUNC(ParsePathAbsEmpty)(state, afterSegment, afterLast, memory); } default: @@ -1392,7 +1439,9 @@ static const URI_CHAR * URI_FUNC(ParsePathAbsEmpty)(URI_TYPE(ParserState) * stat * [pathAbsNoLeadSlash]->[segmentNz][zeroMoreSlashSegs] * [pathAbsNoLeadSlash]-><NULL> */ -static URI_INLINE const URI_CHAR * URI_FUNC(ParsePathAbsNoLeadSlash)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static URI_INLINE const URI_CHAR * URI_FUNC(ParsePathAbsNoLeadSlash)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { return afterLast; } @@ -1420,15 +1469,15 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParsePathAbsNoLeadSlash)(URI_TYPE(Pa case URI_SET_ALPHA: { const URI_CHAR * const afterSegmentNz - = URI_FUNC(ParseSegmentNz)(state, first, afterLast); + = URI_FUNC(ParseSegmentNz)(state, first, afterLast, memory); if (afterSegmentNz == NULL) { return NULL; } - if (!URI_FUNC(PushPathSegment)(state, first, afterSegmentNz)) { /* SEGMENT BOTH */ - URI_FUNC(StopMalloc)(state); + if (!URI_FUNC(PushPathSegment)(state, first, afterSegmentNz, memory)) { /* SEGMENT BOTH */ + URI_FUNC(StopMalloc)(state, memory); return NULL; } - return URI_FUNC(ParseZeroMoreSlashSegs)(state, afterSegmentNz, afterLast); + return URI_FUNC(ParseZeroMoreSlashSegs)(state, afterSegmentNz, afterLast, memory); } default: @@ -1441,18 +1490,20 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParsePathAbsNoLeadSlash)(URI_TYPE(Pa /* * [pathRootless]->[segmentNz][zeroMoreSlashSegs] */ -static URI_INLINE const URI_CHAR * URI_FUNC(ParsePathRootless)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static URI_INLINE const URI_CHAR * URI_FUNC(ParsePathRootless)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + const URI_CHAR * afterLast, UriMemoryManager * memory) { const URI_CHAR * const afterSegmentNz - = URI_FUNC(ParseSegmentNz)(state, first, afterLast); + = URI_FUNC(ParseSegmentNz)(state, first, afterLast, memory); if (afterSegmentNz == NULL) { return NULL; } else { - if (!URI_FUNC(PushPathSegment)(state, first, afterSegmentNz)) { /* SEGMENT BOTH */ - URI_FUNC(StopMalloc)(state); + if (!URI_FUNC(PushPathSegment)(state, first, afterSegmentNz, memory)) { /* SEGMENT BOTH */ + URI_FUNC(StopMalloc)(state, memory); return NULL; } } - return URI_FUNC(ParseZeroMoreSlashSegs)(state, afterSegmentNz, afterLast); + return URI_FUNC(ParseZeroMoreSlashSegs)(state, afterSegmentNz, afterLast, memory); } @@ -1464,15 +1515,17 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParsePathRootless)(URI_TYPE(ParserSt * [pchar]-><:> * [pchar]-><@> */ -static const URI_CHAR * URI_FUNC(ParsePchar)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static const URI_CHAR * URI_FUNC(ParsePchar)(URI_TYPE(ParserState) * state, + const URI_CHAR * first, const URI_CHAR * afterLast, + UriMemoryManager * memory) { if (first >= afterLast) { - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } switch (*first) { case _UT('%'): - return URI_FUNC(ParsePctEncoded)(state, first, afterLast); + return URI_FUNC(ParsePctEncoded)(state, first, afterLast, memory); case _UT(':'): case _UT('@'): @@ -1496,7 +1549,7 @@ static const URI_CHAR * URI_FUNC(ParsePchar)(URI_TYPE(ParserState) * state, cons return first + 1; default: - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } } @@ -1506,9 +1559,12 @@ static const URI_CHAR * URI_FUNC(ParsePchar)(URI_TYPE(ParserState) * state, cons /* * [pctEncoded]-><%>[HEXDIG][HEXDIG] */ -static const URI_CHAR * URI_FUNC(ParsePctEncoded)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static const URI_CHAR * URI_FUNC(ParsePctEncoded)( + URI_TYPE(ParserState) * state, + const URI_CHAR * first, const URI_CHAR * afterLast, + UriMemoryManager * memory) { if (first >= afterLast) { - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } @@ -1520,14 +1576,14 @@ static const URI_CHAR * URI_FUNC(ParsePctEncoded)(URI_TYPE(ParserState) * state, case _UT('%'): */ if (first + 1 >= afterLast) { - URI_FUNC(StopSyntax)(state, first + 1); + URI_FUNC(StopSyntax)(state, first + 1, memory); return NULL; } switch (first[1]) { case URI_SET_HEXDIG: if (first + 2 >= afterLast) { - URI_FUNC(StopSyntax)(state, first + 2); + URI_FUNC(StopSyntax)(state, first + 2, memory); return NULL; } @@ -1536,18 +1592,18 @@ static const URI_CHAR * URI_FUNC(ParsePctEncoded)(URI_TYPE(ParserState) * state, return first + 3; default: - URI_FUNC(StopSyntax)(state, first + 2); + URI_FUNC(StopSyntax)(state, first + 2, memory); return NULL; } default: - URI_FUNC(StopSyntax)(state, first + 1); + URI_FUNC(StopSyntax)(state, first + 1, memory); return NULL; } /* default: - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } */ @@ -1560,15 +1616,18 @@ static const URI_CHAR * URI_FUNC(ParsePctEncoded)(URI_TYPE(ParserState) * state, * [pctSubUnres]->[subDelims] * [pctSubUnres]->[unreserved] */ -static const URI_CHAR * URI_FUNC(ParsePctSubUnres)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static const URI_CHAR * URI_FUNC(ParsePctSubUnres)( + URI_TYPE(ParserState) * state, + const URI_CHAR * first, const URI_CHAR * afterLast, + UriMemoryManager * memory) { if (first >= afterLast) { - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } switch (*first) { case _UT('%'): - return URI_FUNC(ParsePctEncoded)(state, first, afterLast); + return URI_FUNC(ParsePctEncoded)(state, first, afterLast, memory); case _UT('!'): case _UT('$'): @@ -1590,7 +1649,7 @@ static const URI_CHAR * URI_FUNC(ParsePctSubUnres)(URI_TYPE(ParserState) * state return first + 1; default: - URI_FUNC(StopSyntax)(state, first); + URI_FUNC(StopSyntax)(state, first, memory); return NULL; } } @@ -1623,7 +1682,9 @@ static const URI_CHAR * URI_FUNC(ParsePort)(URI_TYPE(ParserState) * state, const * [queryFrag]-><?>[queryFrag] * [queryFrag]-><NULL> */ -static const URI_CHAR * URI_FUNC(ParseQueryFrag)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static const URI_CHAR * URI_FUNC(ParseQueryFrag)(URI_TYPE(ParserState) * state, + const URI_CHAR * first, const URI_CHAR * afterLast, + UriMemoryManager * memory) { if (first >= afterLast) { return afterLast; } @@ -1651,16 +1712,16 @@ static const URI_CHAR * URI_FUNC(ParseQueryFrag)(URI_TYPE(ParserState) * state, case URI_SET_ALPHA: { const URI_CHAR * const afterPchar - = URI_FUNC(ParsePchar)(state, first, afterLast); + = URI_FUNC(ParsePchar)(state, first, afterLast, memory); if (afterPchar == NULL) { return NULL; } - return URI_FUNC(ParseQueryFrag)(state, afterPchar, afterLast); + return URI_FUNC(ParseQueryFrag)(state, afterPchar, afterLast, memory); } case _UT('/'): case _UT('?'): - return URI_FUNC(ParseQueryFrag)(state, first + 1, afterLast); + return URI_FUNC(ParseQueryFrag)(state, first + 1, afterLast, memory); default: return first; @@ -1673,7 +1734,9 @@ static const URI_CHAR * URI_FUNC(ParseQueryFrag)(URI_TYPE(ParserState) * state, * [segment]->[pchar][segment] * [segment]-><NULL> */ -static const URI_CHAR * URI_FUNC(ParseSegment)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static const URI_CHAR * URI_FUNC(ParseSegment)(URI_TYPE(ParserState) * state, + const URI_CHAR * first, const URI_CHAR * afterLast, + UriMemoryManager * memory) { if (first >= afterLast) { return afterLast; } @@ -1701,11 +1764,11 @@ static const URI_CHAR * URI_FUNC(ParseSegment)(URI_TYPE(ParserState) * state, co case URI_SET_ALPHA: { const URI_CHAR * const afterPchar - = URI_FUNC(ParsePchar)(state, first, afterLast); + = URI_FUNC(ParsePchar)(state, first, afterLast, memory); if (afterPchar == NULL) { return NULL; } - return URI_FUNC(ParseSegment)(state, afterPchar, afterLast); + return URI_FUNC(ParseSegment)(state, afterPchar, afterLast, memory); } default: @@ -1718,19 +1781,24 @@ static const URI_CHAR * URI_FUNC(ParseSegment)(URI_TYPE(ParserState) * state, co /* * [segmentNz]->[pchar][segment] */ -static URI_INLINE const URI_CHAR * URI_FUNC(ParseSegmentNz)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static URI_INLINE const URI_CHAR * URI_FUNC(ParseSegmentNz)( + URI_TYPE(ParserState) * state, + const URI_CHAR * first, const URI_CHAR * afterLast, + UriMemoryManager * memory) { const URI_CHAR * const afterPchar - = URI_FUNC(ParsePchar)(state, first, afterLast); + = URI_FUNC(ParsePchar)(state, first, afterLast, memory); if (afterPchar == NULL) { return NULL; } - return URI_FUNC(ParseSegment)(state, afterPchar, afterLast); + return URI_FUNC(ParseSegment)(state, afterPchar, afterLast, memory); } -static URI_INLINE UriBool URI_FUNC(OnExitSegmentNzNcOrScheme2)(URI_TYPE(ParserState) * state, const URI_CHAR * first) { - if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first)) { /* SEGMENT BOTH */ +static URI_INLINE UriBool URI_FUNC(OnExitSegmentNzNcOrScheme2)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + UriMemoryManager * memory) { + if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first, memory)) { /* SEGMENT BOTH */ return URI_FALSE; /* Raises malloc error*/ } state->uri->scheme.first = NULL; /* Not a scheme, reset */ @@ -1763,10 +1831,12 @@ static URI_INLINE UriBool URI_FUNC(OnExitSegmentNzNcOrScheme2)(URI_TYPE(ParserSt * [segmentNzNcOrScheme2]-><'>[mustBeSegmentNzNc] * [segmentNzNcOrScheme2]-><->[segmentNzNcOrScheme2] */ -static const URI_CHAR * URI_FUNC(ParseSegmentNzNcOrScheme2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static const URI_CHAR * URI_FUNC(ParseSegmentNzNcOrScheme2)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { - if (!URI_FUNC(OnExitSegmentNzNcOrScheme2)(state, first)) { - URI_FUNC(StopMalloc)(state); + if (!URI_FUNC(OnExitSegmentNzNcOrScheme2)(state, first, memory)) { + URI_FUNC(StopMalloc)(state, memory); return NULL; } return afterLast; @@ -1778,16 +1848,16 @@ static const URI_CHAR * URI_FUNC(ParseSegmentNzNcOrScheme2)(URI_TYPE(ParserState case _UT('-'): case URI_SET_ALPHA: case URI_SET_DIGIT: - return URI_FUNC(ParseSegmentNzNcOrScheme2)(state, first + 1, afterLast); + return URI_FUNC(ParseSegmentNzNcOrScheme2)(state, first + 1, afterLast, memory); case _UT('%'): { const URI_CHAR * const afterPctEncoded - = URI_FUNC(ParsePctEncoded)(state, first, afterLast); + = URI_FUNC(ParsePctEncoded)(state, first, afterLast, memory); if (afterPctEncoded == NULL) { return NULL; } - return URI_FUNC(ParseMustBeSegmentNzNc)(state, afterPctEncoded, afterLast); + return URI_FUNC(ParseMustBeSegmentNzNc)(state, afterPctEncoded, afterLast, memory); } case _UT('!'): @@ -1803,50 +1873,50 @@ static const URI_CHAR * URI_FUNC(ParseSegmentNzNcOrScheme2)(URI_TYPE(ParserState case _UT('~'): case _UT('='): case _UT('\''): - return URI_FUNC(ParseMustBeSegmentNzNc)(state, first + 1, afterLast); + return URI_FUNC(ParseMustBeSegmentNzNc)(state, first + 1, afterLast, memory); case _UT('/'): { const URI_CHAR * afterZeroMoreSlashSegs; const URI_CHAR * const afterSegment - = URI_FUNC(ParseSegment)(state, first + 1, afterLast); + = URI_FUNC(ParseSegment)(state, first + 1, afterLast, memory); if (afterSegment == NULL) { return NULL; } - if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first)) { /* SEGMENT BOTH */ - URI_FUNC(StopMalloc)(state); + if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first, memory)) { /* SEGMENT BOTH */ + URI_FUNC(StopMalloc)(state, memory); return NULL; } state->uri->scheme.first = NULL; /* Not a scheme, reset */ - if (!URI_FUNC(PushPathSegment)(state, first + 1, afterSegment)) { /* SEGMENT BOTH */ - URI_FUNC(StopMalloc)(state); + if (!URI_FUNC(PushPathSegment)(state, first + 1, afterSegment, memory)) { /* SEGMENT BOTH */ + URI_FUNC(StopMalloc)(state, memory); return NULL; } afterZeroMoreSlashSegs - = URI_FUNC(ParseZeroMoreSlashSegs)(state, afterSegment, afterLast); + = URI_FUNC(ParseZeroMoreSlashSegs)(state, afterSegment, afterLast, memory); if (afterZeroMoreSlashSegs == NULL) { return NULL; } - return URI_FUNC(ParseUriTail)(state, afterZeroMoreSlashSegs, afterLast); + return URI_FUNC(ParseUriTail)(state, afterZeroMoreSlashSegs, afterLast, memory); } case _UT(':'): { const URI_CHAR * const afterHierPart - = URI_FUNC(ParseHierPart)(state, first + 1, afterLast); + = URI_FUNC(ParseHierPart)(state, first + 1, afterLast, memory); state->uri->scheme.afterLast = first; /* SCHEME END */ if (afterHierPart == NULL) { return NULL; } - return URI_FUNC(ParseUriTail)(state, afterHierPart, afterLast); + return URI_FUNC(ParseUriTail)(state, afterHierPart, afterLast, memory); } default: - if (!URI_FUNC(OnExitSegmentNzNcOrScheme2)(state, first)) { - URI_FUNC(StopMalloc)(state); + if (!URI_FUNC(OnExitSegmentNzNcOrScheme2)(state, first, memory)) { + URI_FUNC(StopMalloc)(state, memory); return NULL; } - return URI_FUNC(ParseUriTail)(state, first, afterLast); + return URI_FUNC(ParseUriTail)(state, first, afterLast, memory); } } @@ -1865,7 +1935,9 @@ static const URI_CHAR * URI_FUNC(ParseSegmentNzNcOrScheme2)(URI_TYPE(ParserState * [uriReference]-><~>[mustBeSegmentNzNc] * [uriReference]-><->[mustBeSegmentNzNc] */ -static const URI_CHAR * URI_FUNC(ParseUriReference)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static const URI_CHAR * URI_FUNC(ParseUriReference)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { return afterLast; } @@ -1873,7 +1945,7 @@ static const URI_CHAR * URI_FUNC(ParseUriReference)(URI_TYPE(ParserState) * stat switch (*first) { case URI_SET_ALPHA: state->uri->scheme.first = first; /* SCHEME BEGIN */ - return URI_FUNC(ParseSegmentNzNcOrScheme2)(state, first + 1, afterLast); + return URI_FUNC(ParseSegmentNzNcOrScheme2)(state, first + 1, afterLast, memory); case URI_SET_DIGIT: case _UT('!'): @@ -1893,31 +1965,31 @@ static const URI_CHAR * URI_FUNC(ParseUriReference)(URI_TYPE(ParserState) * stat case _UT('-'): case _UT('@'): state->uri->scheme.first = first; /* SEGMENT BEGIN, ABUSE SCHEME POINTER */ - return URI_FUNC(ParseMustBeSegmentNzNc)(state, first + 1, afterLast); + return URI_FUNC(ParseMustBeSegmentNzNc)(state, first + 1, afterLast, memory); case _UT('%'): { const URI_CHAR * const afterPctEncoded - = URI_FUNC(ParsePctEncoded)(state, first, afterLast); + = URI_FUNC(ParsePctEncoded)(state, first, afterLast, memory); if (afterPctEncoded == NULL) { return NULL; } state->uri->scheme.first = first; /* SEGMENT BEGIN, ABUSE SCHEME POINTER */ - return URI_FUNC(ParseMustBeSegmentNzNc)(state, afterPctEncoded, afterLast); + return URI_FUNC(ParseMustBeSegmentNzNc)(state, afterPctEncoded, afterLast, memory); } case _UT('/'): { const URI_CHAR * const afterPartHelperTwo - = URI_FUNC(ParsePartHelperTwo)(state, first + 1, afterLast); + = URI_FUNC(ParsePartHelperTwo)(state, first + 1, afterLast, memory); if (afterPartHelperTwo == NULL) { return NULL; } - return URI_FUNC(ParseUriTail)(state, afterPartHelperTwo, afterLast); + return URI_FUNC(ParseUriTail)(state, afterPartHelperTwo, afterLast, memory); } default: - return URI_FUNC(ParseUriTail)(state, first, afterLast); + return URI_FUNC(ParseUriTail)(state, first, afterLast, memory); } } @@ -1928,7 +2000,10 @@ static const URI_CHAR * URI_FUNC(ParseUriReference)(URI_TYPE(ParserState) * stat * [uriTail]-><?>[queryFrag][uriTailTwo] * [uriTail]-><NULL> */ -static URI_INLINE const URI_CHAR * URI_FUNC(ParseUriTail)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static URI_INLINE const URI_CHAR * URI_FUNC(ParseUriTail)( + URI_TYPE(ParserState) * state, + const URI_CHAR * first, const URI_CHAR * afterLast, + UriMemoryManager * memory) { if (first >= afterLast) { return afterLast; } @@ -1936,7 +2011,7 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseUriTail)(URI_TYPE(ParserState) switch (*first) { case _UT('#'): { - const URI_CHAR * const afterQueryFrag = URI_FUNC(ParseQueryFrag)(state, first + 1, afterLast); + const URI_CHAR * const afterQueryFrag = URI_FUNC(ParseQueryFrag)(state, first + 1, afterLast, memory); if (afterQueryFrag == NULL) { return NULL; } @@ -1948,13 +2023,13 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseUriTail)(URI_TYPE(ParserState) case _UT('?'): { const URI_CHAR * const afterQueryFrag - = URI_FUNC(ParseQueryFrag)(state, first + 1, afterLast); + = URI_FUNC(ParseQueryFrag)(state, first + 1, afterLast, memory); if (afterQueryFrag == NULL) { return NULL; } state->uri->query.first = first + 1; /* QUERY BEGIN */ state->uri->query.afterLast = afterQueryFrag; /* QUERY END */ - return URI_FUNC(ParseUriTailTwo)(state, afterQueryFrag, afterLast); + return URI_FUNC(ParseUriTailTwo)(state, afterQueryFrag, afterLast, memory); } default: @@ -1968,7 +2043,10 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseUriTail)(URI_TYPE(ParserState) * [uriTailTwo]-><#>[queryFrag] * [uriTailTwo]-><NULL> */ -static URI_INLINE const URI_CHAR * URI_FUNC(ParseUriTailTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static URI_INLINE const URI_CHAR * URI_FUNC(ParseUriTailTwo)( + URI_TYPE(ParserState) * state, + const URI_CHAR * first, const URI_CHAR * afterLast, + UriMemoryManager * memory) { if (first >= afterLast) { return afterLast; } @@ -1976,7 +2054,7 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseUriTailTwo)(URI_TYPE(ParserStat switch (*first) { case _UT('#'): { - const URI_CHAR * const afterQueryFrag = URI_FUNC(ParseQueryFrag)(state, first + 1, afterLast); + const URI_CHAR * const afterQueryFrag = URI_FUNC(ParseQueryFrag)(state, first + 1, afterLast, memory); if (afterQueryFrag == NULL) { return NULL; } @@ -1996,7 +2074,9 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseUriTailTwo)(URI_TYPE(ParserStat * [zeroMoreSlashSegs]-></>[segment][zeroMoreSlashSegs] * [zeroMoreSlashSegs]-><NULL> */ -static const URI_CHAR * URI_FUNC(ParseZeroMoreSlashSegs)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +static const URI_CHAR * URI_FUNC(ParseZeroMoreSlashSegs)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + const URI_CHAR * afterLast, UriMemoryManager * memory) { if (first >= afterLast) { return afterLast; } @@ -2005,15 +2085,15 @@ static const URI_CHAR * URI_FUNC(ParseZeroMoreSlashSegs)(URI_TYPE(ParserState) * case _UT('/'): { const URI_CHAR * const afterSegment - = URI_FUNC(ParseSegment)(state, first + 1, afterLast); + = URI_FUNC(ParseSegment)(state, first + 1, afterLast, memory); if (afterSegment == NULL) { return NULL; } - if (!URI_FUNC(PushPathSegment)(state, first + 1, afterSegment)) { /* SEGMENT BOTH */ - URI_FUNC(StopMalloc)(state); + if (!URI_FUNC(PushPathSegment)(state, first + 1, afterSegment, memory)) { /* SEGMENT BOTH */ + URI_FUNC(StopMalloc)(state, memory); return NULL; } - return URI_FUNC(ParseZeroMoreSlashSegs)(state, afterSegment, afterLast); + return URI_FUNC(ParseZeroMoreSlashSegs)(state, afterSegment, afterLast, memory); } default: @@ -2031,12 +2111,13 @@ static URI_INLINE void URI_FUNC(ResetParserStateExceptUri)(URI_TYPE(ParserState) -static URI_INLINE UriBool URI_FUNC(PushPathSegment)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { - URI_TYPE(PathSegment) * segment = malloc(1 * sizeof(URI_TYPE(PathSegment))); +static URI_INLINE UriBool URI_FUNC(PushPathSegment)( + URI_TYPE(ParserState) * state, const URI_CHAR * first, + const URI_CHAR * afterLast, UriMemoryManager * memory) { + URI_TYPE(PathSegment) * segment = memory->calloc(memory, 1, sizeof(URI_TYPE(PathSegment))); if (segment == NULL) { return URI_FALSE; /* Raises malloc error */ } - memset(segment, 0, sizeof(URI_TYPE(PathSegment))); if (first == afterLast) { segment->text.first = URI_FUNC(SafeToPointTo); segment->text.afterLast = URI_FUNC(SafeToPointTo); @@ -2061,7 +2142,16 @@ static URI_INLINE UriBool URI_FUNC(PushPathSegment)(URI_TYPE(ParserState) * stat -int URI_FUNC(ParseUriEx)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) { +int URI_FUNC(ParseUriEx)(URI_TYPE(ParserState) * state, + const URI_CHAR * first, const URI_CHAR * afterLast) { + return URI_FUNC(ParseUriExMm)(state, first, afterLast, NULL); +} + + + +static int URI_FUNC(ParseUriExMm)(URI_TYPE(ParserState) * state, + const URI_CHAR * first, const URI_CHAR * afterLast, + UriMemoryManager * memory) { const URI_CHAR * afterUriReference; URI_TYPE(Uri) * uri; @@ -2069,6 +2159,8 @@ int URI_FUNC(ParseUriEx)(URI_TYPE(ParserState) * state, const URI_CHAR * first, if ((state == NULL) || (first == NULL) || (afterLast == NULL)) { return URI_ERROR_NULL; } + URI_CHECK_MEMORY_MANAGER(memory); /* may return */ + uri = state->uri; /* Init parser */ @@ -2076,12 +2168,12 @@ int URI_FUNC(ParseUriEx)(URI_TYPE(ParserState) * state, const URI_CHAR * first, URI_FUNC(ResetUri)(uri); /* Parse */ - afterUriReference = URI_FUNC(ParseUriReference)(state, first, afterLast); + afterUriReference = URI_FUNC(ParseUriReference)(state, first, afterLast, memory); if (afterUriReference == NULL) { return state->errorCode; } if (afterUriReference != afterLast) { - URI_FUNC(StopSyntax)(state, afterUriReference); + URI_FUNC(StopSyntax)(state, afterUriReference, memory); return state->errorCode; } return URI_SUCCESS; @@ -2098,16 +2190,70 @@ int URI_FUNC(ParseUri)(URI_TYPE(ParserState) * state, const URI_CHAR * text) { +int URI_FUNC(ParseSingleUri)(URI_TYPE(Uri) * uri, const URI_CHAR * text, + const URI_CHAR ** errorPos) { + return URI_FUNC(ParseSingleUriEx)(uri, text, NULL, errorPos); +} + + + +int URI_FUNC(ParseSingleUriEx)(URI_TYPE(Uri) * uri, + const URI_CHAR * first, const URI_CHAR * afterLast, + const URI_CHAR ** errorPos) { + if ((afterLast == NULL) && (first != NULL)) { + afterLast = first + URI_STRLEN(first); + } + return URI_FUNC(ParseSingleUriExMm)(uri, first, afterLast, errorPos, NULL); +} + + + +int URI_FUNC(ParseSingleUriExMm)(URI_TYPE(Uri) * uri, + const URI_CHAR * first, const URI_CHAR * afterLast, + const URI_CHAR ** errorPos, UriMemoryManager * memory) { + URI_TYPE(ParserState) state; + int res; + + /* Check params */ + if ((uri == NULL) || (first == NULL) || (afterLast == NULL)) { + return URI_ERROR_NULL; + } + URI_CHECK_MEMORY_MANAGER(memory); /* may return */ + + state.uri = uri; + + res = URI_FUNC(ParseUriExMm)(&state, first, afterLast, memory); + + if (res != URI_SUCCESS) { + if (errorPos != NULL) { + *errorPos = state.errorPos; + } + URI_FUNC(FreeUriMembersMm)(uri, memory); + } + + return res; +} + + + void URI_FUNC(FreeUriMembers)(URI_TYPE(Uri) * uri) { + URI_FUNC(FreeUriMembersMm)(uri, NULL); +} + + + +int URI_FUNC(FreeUriMembersMm)(URI_TYPE(Uri) * uri, UriMemoryManager * memory) { if (uri == NULL) { - return; + return URI_ERROR_NULL; } + URI_CHECK_MEMORY_MANAGER(memory); /* may return */ + if (uri->owner) { /* Scheme */ if (uri->scheme.first != NULL) { if (uri->scheme.first != uri->scheme.afterLast) { - free((URI_CHAR *)uri->scheme.first); + memory->free(memory, (URI_CHAR *)uri->scheme.first); } uri->scheme.first = NULL; uri->scheme.afterLast = NULL; @@ -2116,7 +2262,7 @@ void URI_FUNC(FreeUriMembers)(URI_TYPE(Uri) * uri) { /* User info */ if (uri->userInfo.first != NULL) { if (uri->userInfo.first != uri->userInfo.afterLast) { - free((URI_CHAR *)uri->userInfo.first); + memory->free(memory, (URI_CHAR *)uri->userInfo.first); } uri->userInfo.first = NULL; uri->userInfo.afterLast = NULL; @@ -2125,7 +2271,7 @@ void URI_FUNC(FreeUriMembers)(URI_TYPE(Uri) * uri) { /* Host data - IPvFuture */ if (uri->hostData.ipFuture.first != NULL) { if (uri->hostData.ipFuture.first != uri->hostData.ipFuture.afterLast) { - free((URI_CHAR *)uri->hostData.ipFuture.first); + memory->free(memory, (URI_CHAR *)uri->hostData.ipFuture.first); } uri->hostData.ipFuture.first = NULL; uri->hostData.ipFuture.afterLast = NULL; @@ -2139,7 +2285,7 @@ void URI_FUNC(FreeUriMembers)(URI_TYPE(Uri) * uri) { && (uri->hostData.ip6 == NULL)) { /* Real regname */ if (uri->hostText.first != uri->hostText.afterLast) { - free((URI_CHAR *)uri->hostText.first); + memory->free(memory, (URI_CHAR *)uri->hostText.first); } uri->hostText.first = NULL; uri->hostText.afterLast = NULL; @@ -2148,20 +2294,20 @@ void URI_FUNC(FreeUriMembers)(URI_TYPE(Uri) * uri) { /* Host data - IPv4 */ if (uri->hostData.ip4 != NULL) { - free(uri->hostData.ip4); + memory->free(memory, uri->hostData.ip4); uri->hostData.ip4 = NULL; } /* Host data - IPv6 */ if (uri->hostData.ip6 != NULL) { - free(uri->hostData.ip6); + memory->free(memory, uri->hostData.ip6); uri->hostData.ip6 = NULL; } /* Port text */ if (uri->owner && (uri->portText.first != NULL)) { if (uri->portText.first != uri->portText.afterLast) { - free((URI_CHAR *)uri->portText.first); + memory->free(memory, (URI_CHAR *)uri->portText.first); } uri->portText.first = NULL; uri->portText.afterLast = NULL; @@ -2174,9 +2320,9 @@ void URI_FUNC(FreeUriMembers)(URI_TYPE(Uri) * uri) { URI_TYPE(PathSegment) * const next = segWalk->next; if (uri->owner && (segWalk->text.first != NULL) && (segWalk->text.first < segWalk->text.afterLast)) { - free((URI_CHAR *)segWalk->text.first); + memory->free(memory, (URI_CHAR *)segWalk->text.first); } - free(segWalk); + memory->free(memory, segWalk); segWalk = next; } uri->pathHead = NULL; @@ -2187,7 +2333,7 @@ void URI_FUNC(FreeUriMembers)(URI_TYPE(Uri) * uri) { /* Query */ if (uri->query.first != NULL) { if (uri->query.first != uri->query.afterLast) { - free((URI_CHAR *)uri->query.first); + memory->free(memory, (URI_CHAR *)uri->query.first); } uri->query.first = NULL; uri->query.afterLast = NULL; @@ -2196,17 +2342,20 @@ void URI_FUNC(FreeUriMembers)(URI_TYPE(Uri) * uri) { /* Fragment */ if (uri->fragment.first != NULL) { if (uri->fragment.first != uri->fragment.afterLast) { - free((URI_CHAR *)uri->fragment.first); + memory->free(memory, (URI_CHAR *)uri->fragment.first); } uri->fragment.first = NULL; uri->fragment.afterLast = NULL; } } + + return URI_SUCCESS; } UriBool URI_FUNC(_TESTING_ONLY_ParseIpSix)(const URI_CHAR * text) { + UriMemoryManager * const memory = &defaultMemoryManager; URI_TYPE(Uri) uri; URI_TYPE(ParserState) parser; const URI_CHAR * const afterIpSix = text + URI_STRLEN(text); @@ -2215,9 +2364,9 @@ UriBool URI_FUNC(_TESTING_ONLY_ParseIpSix)(const URI_CHAR * text) { URI_FUNC(ResetUri)(&uri); parser.uri = &uri; URI_FUNC(ResetParserStateExceptUri)(&parser); - parser.uri->hostData.ip6 = malloc(1 * sizeof(UriIp6)); - res = URI_FUNC(ParseIPv6address2)(&parser, text, afterIpSix); - URI_FUNC(FreeUriMembers)(&uri); + parser.uri->hostData.ip6 = memory->malloc(memory, 1 * sizeof(UriIp6)); + res = URI_FUNC(ParseIPv6address2)(&parser, text, afterIpSix, memory); + URI_FUNC(FreeUriMembersMm)(&uri, memory); return res == afterIpSix ? URI_TRUE : URI_FALSE; } diff --git a/src/UriQuery.c b/src/UriQuery.c index f0cd4f8..326e963 100644 --- a/src/UriQuery.c +++ b/src/UriQuery.c @@ -64,10 +64,15 @@ #ifndef URI_DOXYGEN # include <uriparser/Uri.h> # include "UriCommon.h" +# include "UriMemory.h" #endif +#include <limits.h> + + + static int URI_FUNC(ComposeQueryEngine)(URI_CHAR * dest, const URI_TYPE(QueryList) * queryList, int maxChars, int * charsWritten, int * charsRequired, @@ -76,7 +81,8 @@ static int URI_FUNC(ComposeQueryEngine)(URI_CHAR * dest, static UriBool URI_FUNC(AppendQueryItem)(URI_TYPE(QueryList) ** prevNext, int * itemCount, const URI_CHAR * keyFirst, const URI_CHAR * keyAfter, const URI_CHAR * valueFirst, const URI_CHAR * valueAfter, - UriBool plusToSpace, UriBreakConversion breakConversion); + UriBool plusToSpace, UriBreakConversion breakConversion, + UriMemoryManager * memory); @@ -145,6 +151,16 @@ int URI_FUNC(ComposeQueryMalloc)(URI_CHAR ** dest, int URI_FUNC(ComposeQueryMallocEx)(URI_CHAR ** dest, const URI_TYPE(QueryList) * queryList, UriBool spaceToPlus, UriBool normalizeBreaks) { + return URI_FUNC(ComposeQueryMallocExMm)(dest, queryList, spaceToPlus, + normalizeBreaks, NULL); +} + + + +int URI_FUNC(ComposeQueryMallocExMm)(URI_CHAR ** dest, + const URI_TYPE(QueryList) * queryList, + UriBool spaceToPlus, UriBool normalizeBreaks, + UriMemoryManager * memory) { int charsRequired; int res; URI_CHAR * queryString; @@ -153,6 +169,8 @@ int URI_FUNC(ComposeQueryMallocEx)(URI_CHAR ** dest, return URI_ERROR_NULL; } + URI_CHECK_MEMORY_MANAGER(memory); /* may return */ + /* Calculate space */ res = URI_FUNC(ComposeQueryCharsRequiredEx)(queryList, &charsRequired, spaceToPlus, normalizeBreaks); @@ -162,7 +180,7 @@ int URI_FUNC(ComposeQueryMallocEx)(URI_CHAR ** dest, charsRequired++; /* Allocate space */ - queryString = malloc(charsRequired * sizeof(URI_CHAR)); + queryString = memory->malloc(memory, charsRequired * sizeof(URI_CHAR)); if (queryString == NULL) { return URI_ERROR_MALLOC; } @@ -171,7 +189,7 @@ int URI_FUNC(ComposeQueryMallocEx)(URI_CHAR ** dest, res = URI_FUNC(ComposeQueryEx)(queryString, queryList, charsRequired, NULL, spaceToPlus, normalizeBreaks); if (res != URI_SUCCESS) { - free(queryString); + memory->free(memory, queryString); return res; } @@ -186,7 +204,7 @@ int URI_FUNC(ComposeQueryEngine)(URI_CHAR * dest, int maxChars, int * charsWritten, int * charsRequired, UriBool spaceToPlus, UriBool normalizeBreaks) { UriBool firstItem = URI_TRUE; - int ampersandLen = 0; + int ampersandLen = 0; /* increased to 1 from second item on */ URI_CHAR * write = dest; /* Subtract terminator */ @@ -195,46 +213,48 @@ int URI_FUNC(ComposeQueryEngine)(URI_CHAR * dest, } else { maxChars--; } - + while (queryList != NULL) { const URI_CHAR * const key = queryList->key; const URI_CHAR * const value = queryList->value; const int worstCase = (normalizeBreaks == URI_TRUE ? 6 : 3); const int keyLen = (key == NULL) ? 0 : (int)URI_STRLEN(key); - const int keyRequiredChars = worstCase * keyLen; + int keyRequiredChars; const int valueLen = (value == NULL) ? 0 : (int)URI_STRLEN(value); - const int valueRequiredChars = worstCase * valueLen; + int valueRequiredChars; + + if ((keyLen >= INT_MAX / worstCase) || (valueLen >= INT_MAX / worstCase)) { + return URI_ERROR_OUTPUT_TOO_LARGE; + } + keyRequiredChars = worstCase * keyLen; + valueRequiredChars = worstCase * valueLen; if (dest == NULL) { + (*charsRequired) += ampersandLen + keyRequiredChars + ((value == NULL) + ? 0 + : 1 + valueRequiredChars); + if (firstItem == URI_TRUE) { ampersandLen = 1; firstItem = URI_FALSE; } - - (*charsRequired) += ampersandLen + keyRequiredChars + ((value == NULL) - ? 0 - : 1 + valueRequiredChars); } else { - URI_CHAR * afterKey; - if ((write - dest) + ampersandLen + keyRequiredChars > maxChars) { return URI_ERROR_OUTPUT_TOO_LARGE; } /* Copy key */ if (firstItem == URI_TRUE) { + ampersandLen = 1; firstItem = URI_FALSE; } else { write[0] = _UT('&'); write++; } - afterKey = URI_FUNC(EscapeEx)(key, key + keyLen, + write = URI_FUNC(EscapeEx)(key, key + keyLen, write, spaceToPlus, normalizeBreaks); - write += (afterKey - write); if (value != NULL) { - URI_CHAR * afterValue; - if ((write - dest) + 1 + valueRequiredChars > maxChars) { return URI_ERROR_OUTPUT_TOO_LARGE; } @@ -242,9 +262,8 @@ int URI_FUNC(ComposeQueryEngine)(URI_CHAR * dest, /* Copy value */ write[0] = _UT('='); write++; - afterValue = URI_FUNC(EscapeEx)(value, value + valueLen, + write = URI_FUNC(EscapeEx)(value, value + valueLen, write, spaceToPlus, normalizeBreaks); - write += (afterValue - write); } } @@ -266,7 +285,8 @@ int URI_FUNC(ComposeQueryEngine)(URI_CHAR * dest, UriBool URI_FUNC(AppendQueryItem)(URI_TYPE(QueryList) ** prevNext, int * itemCount, const URI_CHAR * keyFirst, const URI_CHAR * keyAfter, const URI_CHAR * valueFirst, const URI_CHAR * valueAfter, - UriBool plusToSpace, UriBreakConversion breakConversion) { + UriBool plusToSpace, UriBreakConversion breakConversion, + UriMemoryManager * memory) { const int keyLen = (int)(keyAfter - keyFirst); const int valueLen = (int)(valueAfter - valueFirst); URI_CHAR * key; @@ -281,7 +301,7 @@ UriBool URI_FUNC(AppendQueryItem)(URI_TYPE(QueryList) ** prevNext, } /* Append new empty item */ - *prevNext = malloc(1 * sizeof(URI_TYPE(QueryList))); + *prevNext = memory->malloc(memory, 1 * sizeof(URI_TYPE(QueryList))); if (*prevNext == NULL) { return URI_FALSE; /* Raises malloc error */ } @@ -289,9 +309,9 @@ UriBool URI_FUNC(AppendQueryItem)(URI_TYPE(QueryList) ** prevNext, /* Fill key */ - key = malloc((keyLen + 1) * sizeof(URI_CHAR)); + key = memory->malloc(memory, (keyLen + 1) * sizeof(URI_CHAR)); if (key == NULL) { - free(*prevNext); + memory->free(memory, *prevNext); *prevNext = NULL; return URI_FALSE; /* Raises malloc error */ } @@ -309,10 +329,10 @@ UriBool URI_FUNC(AppendQueryItem)(URI_TYPE(QueryList) ** prevNext, /* Fill value */ if (valueFirst != NULL) { - value = malloc((valueLen + 1) * sizeof(URI_CHAR)); + value = memory->malloc(memory, (valueLen + 1) * sizeof(URI_CHAR)); if (value == NULL) { - free(key); - free(*prevNext); + memory->free(memory, key); + memory->free(memory, *prevNext); *prevNext = NULL; return URI_FALSE; /* Raises malloc error */ } @@ -338,13 +358,22 @@ UriBool URI_FUNC(AppendQueryItem)(URI_TYPE(QueryList) ** prevNext, void URI_FUNC(FreeQueryList)(URI_TYPE(QueryList) * queryList) { + URI_FUNC(FreeQueryListMm)(queryList, NULL); +} + + + +int URI_FUNC(FreeQueryListMm)(URI_TYPE(QueryList) * queryList, + UriMemoryManager * memory) { + URI_CHECK_MEMORY_MANAGER(memory); /* may return */ while (queryList != NULL) { URI_TYPE(QueryList) * nextBackup = queryList->next; - free((URI_CHAR *)queryList->key); /* const cast */ - free((URI_CHAR *)queryList->value); /* const cast */ - free(queryList); + memory->free(memory, (URI_CHAR *)queryList->key); /* const cast */ + memory->free(memory, (URI_CHAR *)queryList->value); /* const cast */ + memory->free(memory, queryList); queryList = nextBackup; } + return URI_SUCCESS; } @@ -363,6 +392,16 @@ int URI_FUNC(DissectQueryMalloc)(URI_TYPE(QueryList) ** dest, int * itemCount, int URI_FUNC(DissectQueryMallocEx)(URI_TYPE(QueryList) ** dest, int * itemCount, const URI_CHAR * first, const URI_CHAR * afterLast, UriBool plusToSpace, UriBreakConversion breakConversion) { + return URI_FUNC(DissectQueryMallocExMm)(dest, itemCount, first, afterLast, + plusToSpace, breakConversion, NULL); +} + + + +int URI_FUNC(DissectQueryMallocExMm)(URI_TYPE(QueryList) ** dest, int * itemCount, + const URI_CHAR * first, const URI_CHAR * afterLast, + UriBool plusToSpace, UriBreakConversion breakConversion, + UriMemoryManager * memory) { const URI_CHAR * walk = first; const URI_CHAR * keyFirst = first; const URI_CHAR * keyAfter = NULL; @@ -380,6 +419,8 @@ int URI_FUNC(DissectQueryMallocEx)(URI_TYPE(QueryList) ** dest, int * itemCount, return URI_ERROR_RANGE_INVALID; } + URI_CHECK_MEMORY_MANAGER(memory); /* may return */ + *dest = NULL; *itemsAppended = 0; @@ -395,11 +436,11 @@ int URI_FUNC(DissectQueryMallocEx)(URI_TYPE(QueryList) ** dest, int * itemCount, if (URI_FUNC(AppendQueryItem)(prevNext, itemsAppended, keyFirst, keyAfter, valueFirst, valueAfter, - plusToSpace, breakConversion) + plusToSpace, breakConversion, memory) == URI_FALSE) { /* Free list we built */ *itemsAppended = 0; - URI_FUNC(FreeQueryList)(*dest); + URI_FUNC(FreeQueryListMm)(*dest, memory); return URI_ERROR_MALLOC; } @@ -444,11 +485,11 @@ int URI_FUNC(DissectQueryMallocEx)(URI_TYPE(QueryList) ** dest, int * itemCount, } if (URI_FUNC(AppendQueryItem)(prevNext, itemsAppended, keyFirst, keyAfter, - valueFirst, valueAfter, plusToSpace, breakConversion) + valueFirst, valueAfter, plusToSpace, breakConversion, memory) == URI_FALSE) { /* Free list we built */ *itemsAppended = 0; - URI_FUNC(FreeQueryList)(*dest); + URI_FUNC(FreeQueryListMm)(*dest, memory); return URI_ERROR_MALLOC; } diff --git a/src/UriResolve.c b/src/UriResolve.c index bb1d21a..6569819 100644 --- a/src/UriResolve.c +++ b/src/UriResolve.c @@ -64,6 +64,7 @@ #ifndef URI_DOXYGEN # include <uriparser/Uri.h> # include "UriCommon.h" +# include "UriMemory.h" #endif @@ -71,7 +72,7 @@ /* Appends a relative URI to an absolute. The last path segment of * the absolute URI is replaced. */ static URI_INLINE UriBool URI_FUNC(MergePath)(URI_TYPE(Uri) * absWork, - const URI_TYPE(Uri) * relAppend) { + const URI_TYPE(Uri) * relAppend, UriMemoryManager * memory) { URI_TYPE(PathSegment) * sourceWalker; URI_TYPE(PathSegment) * destPrev; if (relAppend->pathHead == NULL) { @@ -80,7 +81,7 @@ static URI_INLINE UriBool URI_FUNC(MergePath)(URI_TYPE(Uri) * absWork, /* Replace last segment ("" if trailing slash) with first of append chain */ if (absWork->pathHead == NULL) { - URI_TYPE(PathSegment) * const dup = malloc(sizeof(URI_TYPE(PathSegment))); + URI_TYPE(PathSegment) * const dup = memory->malloc(memory, sizeof(URI_TYPE(PathSegment))); if (dup == NULL) { return URI_FALSE; /* Raises malloc error */ } @@ -99,7 +100,7 @@ static URI_INLINE UriBool URI_FUNC(MergePath)(URI_TYPE(Uri) * absWork, destPrev = absWork->pathTail; for (;;) { - URI_TYPE(PathSegment) * const dup = malloc(sizeof(URI_TYPE(PathSegment))); + URI_TYPE(PathSegment) * const dup = memory->malloc(memory, sizeof(URI_TYPE(PathSegment))); if (dup == NULL) { destPrev->next = NULL; absWork->pathTail = destPrev; @@ -121,7 +122,8 @@ static URI_INLINE UriBool URI_FUNC(MergePath)(URI_TYPE(Uri) * absWork, } -static int URI_FUNC(ResolveAbsolutePathFlag)(URI_TYPE(Uri) * absWork) { +static int URI_FUNC(ResolveAbsolutePathFlag)(URI_TYPE(Uri) * absWork, + UriMemoryManager * memory) { if (absWork == NULL) { return URI_ERROR_NULL; } @@ -129,7 +131,7 @@ static int URI_FUNC(ResolveAbsolutePathFlag)(URI_TYPE(Uri) * absWork) { if (URI_FUNC(IsHostSet)(absWork) && absWork->absolutePath) { /* Empty segment needed, instead? */ if (absWork->pathHead == NULL) { - URI_TYPE(PathSegment) * const segment = malloc(sizeof(URI_TYPE(PathSegment))); + URI_TYPE(PathSegment) * const segment = memory->malloc(memory, sizeof(URI_TYPE(PathSegment))); if (segment == NULL) { return URI_ERROR_MALLOC; } @@ -151,7 +153,7 @@ static int URI_FUNC(ResolveAbsolutePathFlag)(URI_TYPE(Uri) * absWork) { static int URI_FUNC(AddBaseUriImpl)(URI_TYPE(Uri) * absDest, const URI_TYPE(Uri) * relSource, const URI_TYPE(Uri) * absBase, - UriResolutionOptions options) { + UriResolutionOptions options, UriMemoryManager * memory) { UriBool relSourceHasScheme; if (absDest == NULL) { @@ -186,14 +188,14 @@ static int URI_FUNC(AddBaseUriImpl)(URI_TYPE(Uri) * absDest, /* [02/32] T.scheme = R.scheme; */ absDest->scheme = relSource->scheme; /* [03/32] T.authority = R.authority; */ - if (!URI_FUNC(CopyAuthority)(absDest, relSource)) { + if (!URI_FUNC(CopyAuthority)(absDest, relSource, memory)) { return URI_ERROR_MALLOC; } /* [04/32] T.path = remove_dot_segments(R.path); */ - if (!URI_FUNC(CopyPath)(absDest, relSource)) { + if (!URI_FUNC(CopyPath)(absDest, relSource, memory)) { return URI_ERROR_MALLOC; } - if (!URI_FUNC(RemoveDotSegmentsAbsolute)(absDest)) { + if (!URI_FUNC(RemoveDotSegmentsAbsolute)(absDest, memory)) { return URI_ERROR_MALLOC; } /* [05/32] T.query = R.query; */ @@ -203,14 +205,14 @@ static int URI_FUNC(AddBaseUriImpl)(URI_TYPE(Uri) * absDest, /* [07/32] if defined(R.authority) then */ if (URI_FUNC(IsHostSet)(relSource)) { /* [08/32] T.authority = R.authority; */ - if (!URI_FUNC(CopyAuthority)(absDest, relSource)) { + if (!URI_FUNC(CopyAuthority)(absDest, relSource, memory)) { return URI_ERROR_MALLOC; } /* [09/32] T.path = remove_dot_segments(R.path); */ - if (!URI_FUNC(CopyPath)(absDest, relSource)) { + if (!URI_FUNC(CopyPath)(absDest, relSource, memory)) { return URI_ERROR_MALLOC; } - if (!URI_FUNC(RemoveDotSegmentsAbsolute)(absDest)) { + if (!URI_FUNC(RemoveDotSegmentsAbsolute)(absDest, memory)) { return URI_ERROR_MALLOC; } /* [10/32] T.query = R.query; */ @@ -218,13 +220,13 @@ static int URI_FUNC(AddBaseUriImpl)(URI_TYPE(Uri) * absDest, /* [11/32] else */ } else { /* [28/32] T.authority = Base.authority; */ - if (!URI_FUNC(CopyAuthority)(absDest, absBase)) { + if (!URI_FUNC(CopyAuthority)(absDest, absBase, memory)) { return URI_ERROR_MALLOC; } /* [12/32] if (R.path == "") then */ if (relSource->pathHead == NULL && !relSource->absolutePath) { /* [13/32] T.path = Base.path; */ - if (!URI_FUNC(CopyPath)(absDest, absBase)) { + if (!URI_FUNC(CopyPath)(absDest, absBase, memory)) { return URI_ERROR_MALLOC; } /* [14/32] if defined(R.query) then */ @@ -243,31 +245,31 @@ static int URI_FUNC(AddBaseUriImpl)(URI_TYPE(Uri) * absDest, if (relSource->absolutePath) { int res; /* [21/32] T.path = remove_dot_segments(R.path); */ - if (!URI_FUNC(CopyPath)(absDest, relSource)) { + if (!URI_FUNC(CopyPath)(absDest, relSource, memory)) { return URI_ERROR_MALLOC; } - res = URI_FUNC(ResolveAbsolutePathFlag)(absDest); + res = URI_FUNC(ResolveAbsolutePathFlag)(absDest, memory); if (res != URI_SUCCESS) { return res; } - if (!URI_FUNC(RemoveDotSegmentsAbsolute)(absDest)) { + if (!URI_FUNC(RemoveDotSegmentsAbsolute)(absDest, memory)) { return URI_ERROR_MALLOC; } /* [22/32] else */ } else { /* [23/32] T.path = merge(Base.path, R.path); */ - if (!URI_FUNC(CopyPath)(absDest, absBase)) { + if (!URI_FUNC(CopyPath)(absDest, absBase, memory)) { return URI_ERROR_MALLOC; } - if (!URI_FUNC(MergePath)(absDest, relSource)) { + if (!URI_FUNC(MergePath)(absDest, relSource, memory)) { return URI_ERROR_MALLOC; } /* [24/32] T.path = remove_dot_segments(T.path); */ - if (!URI_FUNC(RemoveDotSegmentsAbsolute)(absDest)) { + if (!URI_FUNC(RemoveDotSegmentsAbsolute)(absDest, memory)) { return URI_ERROR_MALLOC; } - if (!URI_FUNC(FixAmbiguity)(absDest)) { + if (!URI_FUNC(FixAmbiguity)(absDest, memory)) { return URI_ERROR_MALLOC; } /* [25/32] endif; */ @@ -276,7 +278,7 @@ static int URI_FUNC(AddBaseUriImpl)(URI_TYPE(Uri) * absDest, absDest->query = relSource->query; /* [27/32] endif; */ } - URI_FUNC(FixEmptyTrailSegment)(absDest); + URI_FUNC(FixEmptyTrailSegment)(absDest, memory); /* [29/32] endif; */ } /* [30/32] T.scheme = Base.scheme; */ @@ -294,11 +296,8 @@ static int URI_FUNC(AddBaseUriImpl)(URI_TYPE(Uri) * absDest, int URI_FUNC(AddBaseUri)(URI_TYPE(Uri) * absDest, const URI_TYPE(Uri) * relSource, const URI_TYPE(Uri) * absBase) { - const int res = URI_FUNC(AddBaseUriImpl)(absDest, relSource, absBase, URI_RESOLVE_STRICTLY); - if ((res != URI_SUCCESS) && (absDest != NULL)) { - URI_FUNC(FreeUriMembers)(absDest); - } - return res; + const UriResolutionOptions options = URI_RESOLVE_STRICTLY; + return URI_FUNC(AddBaseUriEx)(absDest, relSource, absBase, options); } @@ -306,9 +305,21 @@ int URI_FUNC(AddBaseUri)(URI_TYPE(Uri) * absDest, int URI_FUNC(AddBaseUriEx)(URI_TYPE(Uri) * absDest, const URI_TYPE(Uri) * relSource, const URI_TYPE(Uri) * absBase, UriResolutionOptions options) { - const int res = URI_FUNC(AddBaseUriImpl)(absDest, relSource, absBase, options); + return URI_FUNC(AddBaseUriExMm)(absDest, relSource, absBase, options, NULL); +} + + + +int URI_FUNC(AddBaseUriExMm)(URI_TYPE(Uri) * absDest, + const URI_TYPE(Uri) * relSource, const URI_TYPE(Uri) * absBase, + UriResolutionOptions options, UriMemoryManager * memory) { + int res; + + URI_CHECK_MEMORY_MANAGER(memory); /* may return */ + + res = URI_FUNC(AddBaseUriImpl)(absDest, relSource, absBase, options, memory); if ((res != URI_SUCCESS) && (absDest != NULL)) { - URI_FUNC(FreeUriMembers)(absDest); + URI_FUNC(FreeUriMembersMm)(absDest, memory); } return res; } diff --git a/src/UriShorten.c b/src/UriShorten.c index e7f6df4..7b0bc97 100644 --- a/src/UriShorten.c +++ b/src/UriShorten.c @@ -64,14 +64,16 @@ #ifndef URI_DOXYGEN # include <uriparser/Uri.h> # include "UriCommon.h" +# include "UriMemory.h" #endif static URI_INLINE UriBool URI_FUNC(AppendSegment)(URI_TYPE(Uri) * uri, - const URI_CHAR * first, const URI_CHAR * afterLast) { + const URI_CHAR * first, const URI_CHAR * afterLast, + UriMemoryManager * memory) { /* Create segment */ - URI_TYPE(PathSegment) * segment = malloc(1 * sizeof(URI_TYPE(PathSegment))); + URI_TYPE(PathSegment) * segment = memory->malloc(memory, 1 * sizeof(URI_TYPE(PathSegment))); if (segment == NULL) { return URI_FALSE; /* Raises malloc error */ } @@ -124,7 +126,7 @@ static URI_INLINE UriBool URI_FUNC(EqualsAuthority)(const URI_TYPE(Uri) * first, static int URI_FUNC(RemoveBaseUriImpl)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * absSource, const URI_TYPE(Uri) * absBase, - UriBool domainRootMode) { + UriBool domainRootMode, UriMemoryManager * memory) { if (dest == NULL) { return URI_ERROR_NULL; } @@ -149,11 +151,11 @@ static int URI_FUNC(RemoveBaseUriImpl)(URI_TYPE(Uri) * dest, /* [02/50] T.scheme = A.scheme; */ dest->scheme = absSource->scheme; /* [03/50] T.authority = A.authority; */ - if (!URI_FUNC(CopyAuthority)(dest, absSource)) { + if (!URI_FUNC(CopyAuthority)(dest, absSource, memory)) { return URI_ERROR_MALLOC; } /* [04/50] T.path = A.path; */ - if (!URI_FUNC(CopyPath)(dest, absSource)) { + if (!URI_FUNC(CopyPath)(dest, absSource, memory)) { return URI_ERROR_MALLOC; } /* [05/50] else */ @@ -163,11 +165,11 @@ static int URI_FUNC(RemoveBaseUriImpl)(URI_TYPE(Uri) * dest, /* [07/50] if (A.authority != Base.authority) then */ if (!URI_FUNC(EqualsAuthority)(absSource, absBase)) { /* [08/50] T.authority = A.authority; */ - if (!URI_FUNC(CopyAuthority)(dest, absSource)) { + if (!URI_FUNC(CopyAuthority)(dest, absSource, memory)) { return URI_ERROR_MALLOC; } /* [09/50] T.path = A.path; */ - if (!URI_FUNC(CopyPath)(dest, absSource)) { + if (!URI_FUNC(CopyPath)(dest, absSource, memory)) { return URI_ERROR_MALLOC; } /* [10/50] else */ @@ -185,12 +187,12 @@ static int URI_FUNC(RemoveBaseUriImpl)(URI_TYPE(Uri) * dest, /* [16/50] T.path = A.path; */ /* GROUPED */ /* [17/50] endif; */ - if (!URI_FUNC(CopyPath)(dest, absSource)) { + if (!URI_FUNC(CopyPath)(dest, absSource, memory)) { return URI_ERROR_MALLOC; } dest->absolutePath = URI_TRUE; - if (!URI_FUNC(FixAmbiguity)(dest)) { + if (!URI_FUNC(FixAmbiguity)(dest, memory)) { return URI_ERROR_MALLOC; } /* [18/50] else */ @@ -220,7 +222,7 @@ static int URI_FUNC(RemoveBaseUriImpl)(URI_TYPE(Uri) * dest, baseSeg = baseSeg->next; /* [28/50] T.path += "../"; */ if (!URI_FUNC(AppendSegment)(dest, URI_FUNC(ConstParent), - URI_FUNC(ConstParent) + 2)) { + URI_FUNC(ConstParent) + 2, memory)) { return URI_ERROR_MALLOC; } /* [29/50] pathNaked = false; */ @@ -244,14 +246,14 @@ static int URI_FUNC(RemoveBaseUriImpl)(URI_TYPE(Uri) * dest, if (containsColon) { /* [34/50] T.path += "./"; */ if (!URI_FUNC(AppendSegment)(dest, URI_FUNC(ConstPwd), - URI_FUNC(ConstPwd) + 1)) { + URI_FUNC(ConstPwd) + 1, memory)) { return URI_ERROR_MALLOC; } /* [35/50] elseif (first(A.path) == "") then */ } else if (sourceSeg->text.first == sourceSeg->text.afterLast) { /* [36/50] T.path += "/."; */ if (!URI_FUNC(AppendSegment)(dest, URI_FUNC(ConstPwd), - URI_FUNC(ConstPwd) + 1)) { + URI_FUNC(ConstPwd) + 1, memory)) { return URI_ERROR_MALLOC; } /* [37/50] endif; */ @@ -260,7 +262,7 @@ static int URI_FUNC(RemoveBaseUriImpl)(URI_TYPE(Uri) * dest, } /* [39/50] T.path += first(A.path); */ if (!URI_FUNC(AppendSegment)(dest, sourceSeg->text.first, - sourceSeg->text.afterLast)) { + sourceSeg->text.afterLast, memory)) { return URI_ERROR_MALLOC; } /* [40/50] pathNaked = false; */ @@ -295,10 +297,24 @@ int URI_FUNC(RemoveBaseUri)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * absSource, const URI_TYPE(Uri) * absBase, UriBool domainRootMode) { - const int res = URI_FUNC(RemoveBaseUriImpl)(dest, absSource, - absBase, domainRootMode); + return URI_FUNC(RemoveBaseUriMm)(dest, absSource, absBase, + domainRootMode, NULL); +} + + + +int URI_FUNC(RemoveBaseUriMm)(URI_TYPE(Uri) * dest, + const URI_TYPE(Uri) * absSource, + const URI_TYPE(Uri) * absBase, + UriBool domainRootMode, UriMemoryManager * memory) { + int res; + + URI_CHECK_MEMORY_MANAGER(memory); /* may return */ + + res = URI_FUNC(RemoveBaseUriImpl)(dest, absSource, + absBase, domainRootMode, memory); if ((res != URI_SUCCESS) && (dest != NULL)) { - URI_FUNC(FreeUriMembers)(dest); + URI_FUNC(FreeUriMembersMm)(dest, memory); } return res; } |