Skip to content

Conversation

@TimWolla
Copy link
Member

@TimWolla TimWolla commented Nov 9, 2025

This is specifically to backport uriparser/uriparser#276.

Fixes #20431.


Annoyingly this diff contains a large reformatting of the library. To make it easier to review, I did the following:

  1. I checked out the previous backport commit uriparser/uriparser@08df3b2 as uriparser.old
  2. I ran clang-format -i src/* and clang-format -i include/uriparser/* with the new clang format configuration.
  3. I ran git diff -w --word-diff for both src/ and include/.

From what I could see, the fix of this issue is the only functional change and the git log seems to agree:

Sebastian Pipping (30):
      CI: Update to Clang 21
      fuzzing.yml: Make use of the expected version of Clang waterproof
      Merge pull request #267 from uriparser/clang-21
      fuzz/ParseFuzzer.cpp: Address warning -Wunused-but-set-variable
      fuzzing.yml: Start specifying CXX and CXXFLAGS also
      Merge pull request #268 from uriparser/fuzzing-ci-cxxflags
      Make CI report on test coverage using LLVM
      Merge pull request #269 from uriparser/coverage-ci
      CMake: Drop support for CMake <3.15.0
      CMake: Remake static CRT approach following libexpat
      Migrate Windows build from AppVeyor to GitHub Actions
      README.md: Sync CMake arguments dump, now in alphabetical order
      ChangeLog: Document pull request 270
      Merge pull request #270 from uriparser/migrate-windows-ci-from-appveyor-to-github-actions
      Merge pull request #266 from TimWolla/mull-mutation
      Drop dead code
      Join two long lines back together
      Initialize .clang-format with default clang-format 21.1.3 config
      .clang-format: Tweak style
      Exclude parts of the code from auto-formatting
      Make "clang-format off" code blend in better
      Replace tabs by four spaces
      Make GitHub Actions enforce clang-format clean code
      Use artificial indent to restore original visual
      Merge pull request #272 from uriparser/clang-format
      Start requiring a C99 compiler
      Remove artificial C89 support scopes
      Merge pull request #273 from uriparser/issue-264-c99
      Merge pull request #274 from uriparser/dependabot/github_actions/actions/upload-artifact-5.0.0
      Merge pull request #276 from TimWolla/set-host-no-path

Tim Düsterhus (5):
      Fully exercise UriParseBase.c in tests
      Add mull.yml configuration
      src/UriMemory.c: Exclude `uriTestMemoryManagerEx()` from mutation testing
      src/UriMemory.c: Exclude mutant without consequence in `uriDecorateRealloc()`
      src/UriSetHostCommon.c: Do not set `absolutePath` for empty paths when removing host

clang-format 21.1.3 (2):
      Mass-apply clang-format 21.1.3
      Mass-apply clang-format 21.1.3

dependabot[bot] (1):
      Actions(deps): Bump actions/upload-artifact from 4.6.2 to 5.0.0

@TimWolla TimWolla requested review from a team and ndossche November 9, 2025 16:19
@TimWolla TimWolla requested a review from kocsismate as a code owner November 9, 2025 16:20
@TimWolla
Copy link
Member Author

TimWolla commented Nov 9, 2025

include/ (excluding changes to COPYING):

diff --git 1/uriparser.old/include/uriparser/Uri.h 2/uriparser/include/uriparser/Uri.h
index 6d05299..ea52097 100644
--- 1/uriparser.old/include/uriparser/Uri.h
+++ 2/uriparser/include/uriparser/Uri.h
@@ -153,9 +153,8 @@ typedef struct URI_TYPE(UriStruct) {
    URI_TYPE(PathSegment) * pathTail; /**< Tail of the list behind pathHead */
    URI_TYPE(TextRange) query; /**< Query without leading "?" */
    URI_TYPE(TextRange) fragment; /**< Query without leading "#" */
    UriBool absolutePath; /**< Absolute path flag, distincting "a" and "/a"; always
                             <c>URI_FALSE</c> for URIs with host */
    UriBool owner; /**< Memory owner flag */

    void * reserved; /**< Reserved to the parser */
diff --git 1/uriparser.old/include/uriparser/UriBase.h 2/uriparser/include/uriparser/UriBase.h
index 5422b9e..f825695 100644
--- 1/uriparser.old/include/uriparser/UriBase.h
+++ 2/uriparser/include/uriparser/UriBase.h
@@ -110,8 +110,8 @@ typedef int UriBool; /**< Boolean type */
#  define URI_SUCCESS 0
#  define URI_ERROR_SYNTAX 1 /* Parsed text violates expected format */
#  define URI_ERROR_NULL \
      2 /* One of the params passed was NULL[-\-] although it mustn't be {+\+}
         */
#  define URI_ERROR_MALLOC 3 /* Requested memory could not be allocated */
#  define URI_ERROR_OUTPUT_TOO_LARGE \
      4 /* Some output is to large for the receiving buffer */

@TimWolla
Copy link
Member Author

TimWolla commented Nov 9, 2025

src/ (excluding changes to COPYING):

--- 1/uriparser.old/src/UriCommon.c
+++ 2/uriparser/src/UriCommon.c
@@ -671,7 +671,6 @@ static UriBool URI_FUNC(PrependNewDotSegment)(URI_TYPE(Uri) * uri,
    assert(uri != NULL);
    assert(memory != NULL);

[-    {-]
    URI_TYPE(PathSegment) * const segment =
        memory->malloc(memory, 1 * sizeof(URI_TYPE(PathSegment)));

@@ -681,24 +680,20 @@ static UriBool URI_FUNC(PrependNewDotSegment)(URI_TYPE(Uri) * uri,

    segment->next = uri->pathHead;

[-        {-]
    URI_TYPE(TextRange) dotRange;
    dotRange.first = URI_FUNC(ConstPwd);
    dotRange.afterLast = URI_FUNC(ConstPwd) + 1;

    if (uri->owner == URI_TRUE) {
        if (URI_FUNC(CopyRange)(&(segment->text), &dotRange, memory) == URI_FALSE) {
            memory->free(memory, segment);
            return URI_FALSE; /* i.e. raise malloc error */
        }
    } else {
        segment->text = dotRange; /* copies all members */
    }
[-        }-]

    uri->pathHead = segment;
[-    }-]

    return URI_TRUE;
}
@@ -730,7 +725,6 @@ UriBool URI_FUNC(FixPathNoScheme)(URI_TYPE(Uri) * uri, UriMemoryManager * memory
    }

    /* Check for troublesome first path segment containing a colon */
[-    {-]
    UriBool colonFound = URI_FALSE;
    const URI_CHAR * walker = uri->pathHead->text.first;

@@ -747,7 +741,6 @@ UriBool URI_FUNC(FixPathNoScheme)(URI_TYPE(Uri) * uri, UriMemoryManager * memory
    if (colonFound == URI_FALSE) {
        return URI_TRUE; /* i.e. nothing to do */
    }
[-    }-]

    /* Insert "." segment in front */
    return URI_FUNC(PrependNewDotSegment)(uri, memory);
diff --git 1/uriparser.old/src/UriFile.c 2/uriparser/src/UriFile.c
index 0367cf6..7510e70 100644
--- 1/uriparser.old/src/UriFile.c
+++ 2/uriparser/src/UriFile.c
@@ -140,7 +140,6 @@ static URI_INLINE int URI_FUNC(UriStringToFilename)(const URI_CHAR * uriString,
        return URI_ERROR_NULL;
    }

[-    {-]
    const UriBool file_unknown_slashes =
        URI_STRNCMP(uriString, _UT("file:"), URI_STRLEN(_UT("file:"))) == 0;
    const UriBool file_one_or_more_slashes =
@@ -151,13 +150,11 @@ static URI_INLINE int URI_FUNC(UriStringToFilename)(const URI_CHAR * uriString,
        && (URI_STRNCMP(uriString, _UT("file://"), URI_STRLEN(_UT("file://"))) == 0);
    const UriBool file_three_or_more_slashes =
        file_two_or_more_slashes
        && (URI_STRNCMP(uriString, _UT("file:///"), URI_STRLEN(_UT("file:///"))) == 0);

    const size_t charsToSkip =
        file_two_or_more_slashes
            ? file_three_or_more_slashes ? toUnix
                                               /* file:///bin/bash */
                                               ? URI_STRLEN(_UT("file://"))
                                               /* file:///E:/Documents%20and%20Settings */
@@ -175,9 +172,8 @@ static URI_INLINE int URI_FUNC(UriStringToFilename)(const URI_CHAR * uriString,
                          : 0));
    const size_t charsToCopy = URI_STRLEN(uriString + charsToSkip) + 1;

    const UriBool is_windows_network_with_authority =
        (toUnix == URI_FALSE) && file_two_or_more_slashes && !file_three_or_more_slashes;

    URI_CHAR * const unescape_target =
        is_windows_network_with_authority ? (filename + 2) : filename;
@@ -189,7 +185,6 @@ static URI_INLINE int URI_FUNC(UriStringToFilename)(const URI_CHAR * uriString,

    memcpy(unescape_target, uriString + charsToSkip, charsToCopy * sizeof(URI_CHAR));
    URI_FUNC(UnescapeInPlaceEx)(filename, URI_FALSE, URI_BR_DONT_TOUCH);
[-    }-]

    /* Convert forward slashes to backslashes */
    if (!toUnix) {
diff --git 1/uriparser.old/src/UriMemory.c 2/uriparser/src/UriMemory.c
index e872c09..3caf819 100644
--- 1/uriparser.old/src/UriMemory.c
+++ 2/uriparser/src/UriMemory.c
@@ -205,6 +205,7 @@ static void * uriDecorateRealloc(UriMemoryManager * memory, void * ptr, size_t s
    prevSize = *((size_t *)((char *)ptr - sizeof(size_t) - URI_MALLOC_PADDING));

    /* Anything to do? */
    {+/* mull-ignore-next cxx_le_to_lt */+}
    if (size <= prevSize) {
        return ptr;
    }
@@ -258,6 +259,7 @@ int uriCompleteMemoryManager(UriMemoryManager * memory, UriMemoryManager * backe
    return URI_SUCCESS;
}

{+/* mull-off */+}
int uriTestMemoryManagerEx(UriMemoryManager * memory, UriBool challengeAlignment) {
    const size_t mallocSize = 7;
    const size_t callocNmemb = 3;
@@ -434,7 +436,6 @@ int uriTestMemoryManagerEx(UriMemoryManager * memory, UriBool challengeAlignment
            ptr[2] = 2.2L;
            ptr[3] = 3.3L;

[-            {-]
            long double * const ptrNew =
                memory->realloc(memory, ptr, 8 * sizeof(long double));
            if (ptrNew != NULL) {
@@ -444,7 +445,6 @@ int uriTestMemoryManagerEx(UriMemoryManager * memory, UriBool challengeAlignment
                ptr[6] = 6.6L;
                ptr[7] = 7.7L;
            }
[-            }-]

            memory->free(memory, ptr);
        }
@@ -452,6 +452,7 @@ int uriTestMemoryManagerEx(UriMemoryManager * memory, UriBool challengeAlignment

    return URI_SUCCESS;
}
{+/* mull-on */+}

int uriTestMemoryManager(UriMemoryManager * memory) {
    return uriTestMemoryManagerEx(memory, /*challengeAlignment=*/URI_FALSE);
diff --git 1/uriparser.old/src/UriNormalize.c 2/uriparser/src/UriNormalize.c
index 29626d6..8c812d3 100644
--- 1/uriparser.old/src/UriNormalize.c
+++ 2/uriparser/src/UriNormalize.c
@@ -524,7 +524,6 @@ static const URI_CHAR * URI_FUNC(PastLeadingZeros)(const URI_CHAR * first,
    assert(afterLast != NULL);
    assert(first != afterLast);

[-    {-]
    /* Find the first non-zero character */
    const URI_CHAR * remainderFirst = first;
    while ((remainderFirst < afterLast) && (remainderFirst[0] == _UT('0'))) {
@@ -542,7 +541,6 @@ static const URI_CHAR * URI_FUNC(PastLeadingZeros)(const URI_CHAR * first,

    return remainderFirst;
}
[-}-]

static void URI_FUNC(DropLeadingZerosInplace)(URI_CHAR * first,
                                              const URI_CHAR ** afterLast) {
@@ -554,9 +552,7 @@ static void URI_FUNC(DropLeadingZerosInplace)(URI_CHAR * first,
        return;
    }

[-{-]    const URI_CHAR * const remainderFirst = URI_FUNC(PastLeadingZeros)(first, *afterLast);

    if (remainderFirst > first) {
        const size_t remainderLen = *afterLast - remainderFirst;
@@ -565,7 +561,6 @@ static void URI_FUNC(DropLeadingZerosInplace)(URI_CHAR * first,
        *afterLast = first + remainderLen;
    }
}
[-}-]

static void URI_FUNC(AdvancePastLeadingZeros)(const URI_CHAR ** first,
                                              const URI_CHAR * afterLast) {
@@ -577,14 +572,11 @@ static void URI_FUNC(AdvancePastLeadingZeros)(const URI_CHAR ** first,
        return;
    }

[-{-]    const URI_CHAR * const remainderFirst = URI_FUNC(PastLeadingZeros)(*first, afterLast);

    /* Cut off leading zeros */
    *first = remainderFirst;
}
[-}-]

static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri,
                                                      unsigned int inMask,
diff --git 1/uriparser.old/src/UriParse.c 2/uriparser/src/UriParse.c
index 9dfb0f8..db48b38 100644
--- 1/uriparser.old/src/UriParse.c
+++ 2/uriparser/src/UriParse.c
@@ -1361,14 +1361,12 @@ static const URI_CHAR * URI_FUNC(ParseOwnPortUserInfo)(URI_TYPE(ParserState) * s

    case _UT('%'):
        state->uri->portText.first = NULL; /* Not a port, reset */
[-        {-]
        const URI_CHAR * const afterPct =
            URI_FUNC(ParsePctEncoded)(state, first, afterLast, memory);
        if (afterPct == NULL) {
            return NULL;
        }
        return URI_FUNC(ParseOwnUserInfo)(state, afterPct, afterLast, memory);
[-        }-]

    case _UT('@'):
        state->uri->hostText.afterLast = NULL; /* Not a host, reset */
diff --git 1/uriparser.old/src/UriRecompose.c 2/uriparser/src/UriRecompose.c
index d407a21..61ffee7 100644
--- 1/uriparser.old/src/UriRecompose.c
+++ 2/uriparser/src/UriRecompose.c
@@ -97,16 +97,27 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
    }
    maxChars--; /* So we don't have to subtract 1 for '\0' all the time */

    {+/* NOTE: The curly brackets here force deeper indent (and that's all) */+}
{+    {+}
{+        {+}
{+            {+}
{+                /* clang-format off */+}
    /* [01/19] result = "" */
                {+/* clang-format on */+}
                if (dest != NULL) {
                    dest[0] = _UT('\0');
                } else {
                    (*charsRequired) = 0;
                }
                {+/* clang-format off */+}
    /* [02/19] if defined(scheme) then */
                {+/* clang-format on */+}
                if (uri->scheme.first != NULL) {
                    {+/* clang-format off */+}
    /* [03/19]     append scheme to result; */
                    {+/* clang-format on */+}
                    const int charsToWrite =
                        (int)(uri->scheme.afterLast - uri->scheme.first);
                    if (dest != NULL) {
                        if (written + charsToWrite <= maxChars) {
                            memcpy(dest + written, uri->scheme.first,
@@ -122,7 +133,9 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                    } else {
                        (*charsRequired) += charsToWrite;
                    }
                    {+/* clang-format off */+}
    /* [04/19]     append ":" to result; */
                    {+/* clang-format on */+}
                    if (dest != NULL) {
                        if (written + 1 <= maxChars) {
                            memcpy(dest + written, _UT(":"), 1 * sizeof(URI_CHAR));
@@ -137,11 +150,17 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                    } else {
                        (*charsRequired) += 1;
                    }
                    {+/* clang-format off */+}
    /* [05/19] endif; */
                    {+/* clang-format on */+}
                }
                {+/* clang-format off */+}
    /* [06/19] if defined(authority) then */
                {+/* clang-format on */+}
                if (URI_FUNC(HasHost)(uri)) {
                    {+/* clang-format off */+}
    /* [07/19]     append "//" to result; */
                    {+/* clang-format on */+}
                    if (dest != NULL) {
                        if (written + 2 <= maxChars) {
                            memcpy(dest + written, _UT("//"), 2 * sizeof(URI_CHAR));
@@ -156,10 +175,13 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                    } else {
                        (*charsRequired) += 2;
                    }
                    {+/* clang-format off */+}
    /* [08/19]     append authority to result; */
                    {+/* clang-format on */+}
                    /* UserInfo */
                    if (uri->userInfo.first != NULL) {
                        const int charsToWrite =
                            (int)(uri->userInfo.afterLast - uri->userInfo.first);
                        if (dest != NULL) {
                            if (written + charsToWrite <= maxChars) {
                                memcpy(dest + written, uri->userInfo.first,
@@ -194,7 +216,8 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                        int i = 0;
                        for (; i < 4; i++) {
                            const unsigned char value = uri->hostData.ip4->data[i];
                            const int charsToWrite =
                                (value > 99) ? 3 : ((value > 9) ? 2 : 1);
                            if (dest != NULL) {
                                if (written + charsToWrite <= maxChars) {
                                    URI_CHAR text[4];
@@ -209,7 +232,8 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                                        text[0] = _UT('0') + value;
                                    }
                                    text[charsToWrite] = _UT('\0');
                                    memcpy(dest + written, text,
                                           charsToWrite * sizeof(URI_CHAR));
                                    written += charsToWrite;
                                } else {
                                    dest[0] = _UT('\0');
@@ -220,7 +244,8 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                                }
                                if (i < 3) {
                                    if (written + 1 <= maxChars) {
                                        memcpy(dest + written, _UT("."),
                                               1 * sizeof(URI_CHAR));
                                        written += 1;
                                    } else {
                                        dest[0] = _UT('\0');
@@ -257,8 +282,10 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                            if (dest != NULL) {
                                if (written + 2 <= maxChars) {
                                    URI_CHAR text[3];
                                    text[0] =
                                        URI_FUNC(HexToLetterEx)(value / 16, URI_FALSE);
                                    text[1] =
                                        URI_FUNC(HexToLetterEx)(value % 16, URI_FALSE);
                                    text[2] = _UT('\0');
                                    memcpy(dest + written, text, 2 * sizeof(URI_CHAR));
                                    written += 2;
@@ -275,7 +302,8 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                            if (((i & 1) == 1) && (i < 15)) {
                                if (dest != NULL) {
                                    if (written + 1 <= maxChars) {
                                        memcpy(dest + written, _UT(":"),
                                               1 * sizeof(URI_CHAR));
                                        written += 1;
                                    } else {
                                        dest[0] = _UT('\0');
@@ -306,8 +334,8 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                        }
                    } else if (uri->hostData.ipFuture.first != NULL) {
                        /* IPvFuture */
                        const int charsToWrite = (int)(uri->hostData.ipFuture.afterLast
                                                       - uri->hostData.ipFuture.first);
                        if (dest != NULL) {
                            if (written + 1 <= maxChars) {
                                memcpy(dest + written, _UT("["), 1 * sizeof(URI_CHAR));
@@ -347,7 +375,8 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                        }
                    } else if (uri->hostText.first != NULL) {
                        /* Regname */
                        const int charsToWrite =
                            (int)(uri->hostText.afterLast - uri->hostText.first);
                        if (dest != NULL) {
                            if (written + charsToWrite <= maxChars) {
                                memcpy(dest + written, uri->hostText.first,
@@ -367,7 +396,8 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U

                    /* Port */
                    if (uri->portText.first != NULL) {
                        const int charsToWrite =
                            (int)(uri->portText.afterLast - uri->portText.first);
                        if (dest != NULL) {
                            /* Leading ':' */
                            if (written + 1 <= maxChars) {
@@ -397,11 +427,16 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                            (*charsRequired) += 1 + charsToWrite;
                        }
                    }
                    {+/* clang-format off */+}
    /* [09/19] endif; */
                    {+/* clang-format on */+}
                }
                {+/* clang-format off */+}
    /* [10/19] append path to result; */
                {+/* clang-format on */+}
                /* Slash needed here? */
                if (uri->absolutePath
                    || ((uri->pathHead != NULL) && URI_FUNC(HasHost)(uri))) {
                    if (dest != NULL) {
                        if (written + 1 <= maxChars) {
                            memcpy(dest + written, _UT("/"), 1 * sizeof(URI_CHAR));
@@ -421,7 +456,8 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                if (uri->pathHead != NULL) {
                    URI_TYPE(PathSegment) * walker = uri->pathHead;
                    do {
                        const int charsToWrite =
                            (int)(walker->text.afterLast - walker->text.first);
                        if (dest != NULL) {
                            if (written + charsToWrite <= maxChars) {
                                memcpy(dest + written, walker->text.first,
@@ -442,7 +478,8 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                        if (walker->next != NULL) {
                            if (dest != NULL) {
                                if (written + 1 <= maxChars) {
                                    memcpy(dest + written, _UT("/"),
                                           1 * sizeof(URI_CHAR));
                                    written += 1;
                                } else {
                                    dest[0] = _UT('\0');
@@ -459,9 +496,13 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                        walker = walker->next;
                    } while (walker != NULL);
                }
                {+/* clang-format off */+}
    /* [11/19] if defined(query) then */
                {+/* clang-format on */+}
                if (uri->query.first != NULL) {
                    {+/* clang-format off */+}
    /* [12/19]     append "?" to result; */
                    {+/* clang-format on */+}
                    if (dest != NULL) {
                        if (written + 1 <= maxChars) {
                            memcpy(dest + written, _UT("?"), 1 * sizeof(URI_CHAR));
@@ -476,9 +517,11 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                    } else {
                        (*charsRequired) += 1;
                    }
                    {+/* clang-format off */+}
    /* [13/19]     append query to result; */
                    [-{-]{+/* clang-format on */+}
                    const int charsToWrite =
                        (int)(uri->query.afterLast - uri->query.first);
                    if (dest != NULL) {
                        if (written + charsToWrite <= maxChars) {
                            memcpy(dest + written, uri->query.first,
@@ -494,12 +537,17 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                    } else {
                        (*charsRequired) += charsToWrite;
                    }
                    [-}-]{+/* clang-format off */+}
    /* [14/19] endif; */
                    {+/* clang-format on */+}
                }
                {+/* clang-format off */+}
    /* [15/19] if defined(fragment) then */
                {+/* clang-format on */+}
                if (uri->fragment.first != NULL) {
                    {+/* clang-format off */+}
    /* [16/19]     append "#" to result; */
                    {+/* clang-format on */+}
                    if (dest != NULL) {
                        if (written + 1 <= maxChars) {
                            memcpy(dest + written, _UT("#"), 1 * sizeof(URI_CHAR));
@@ -514,9 +562,11 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                    } else {
                        (*charsRequired) += 1;
                    }
                    {+/* clang-format off */+}
    /* [17/19]     append fragment to result; */
                    [-{-]{+/* clang-format on */+}
                    const int charsToWrite =
                        (int)(uri->fragment.afterLast - uri->fragment.first);
                    if (dest != NULL) {
                        if (written + charsToWrite <= maxChars) {
                            memcpy(dest + written, uri->fragment.first,
@@ -532,10 +582,13 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                    } else {
                        (*charsRequired) += charsToWrite;
                    }
                    [-}-]{+/* clang-format off */+}
    /* [18/19] endif; */
                    {+/* clang-format on */+}
                }
                {+/* clang-format off */+}
    /* [19/19] return result; */
                {+/* clang-format on */+}
                if (dest != NULL) {
                    dest[written++] = _UT('\0');
                    if (charsWritten != NULL) {
@@ -544,5 +597,8 @@ static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(U
                }
                return URI_SUCCESS;
            }
        {+}+}
{+    }+}
{+}+}

#endif
diff --git 1/uriparser.old/src/UriResolve.c 2/uriparser/src/UriResolve.c
index 4036259..302665d 100644
--- 1/uriparser.old/src/UriResolve.c
+++ 2/uriparser/src/UriResolve.c
@@ -169,82 +169,138 @@ static int URI_FUNC(AddBaseUriImpl)(URI_TYPE(Uri) * absDest,
        return URI_ERROR_ADDBASE_REL_BASE;
    }

    {+/* NOTE: The curly brackets here force deeper indent (and that's all) */+}
{+    {+}
{+        {+}
{+            {+}
{+                /* clang-format off */+}
    /* [00/32] -- A non-strict parser may ignore a scheme in the reference */
    /* [00/32] -- if it is identical to the base URI's scheme. */
    /* [00/32] if ((not strict) and (R.scheme == Base.scheme)) then */
                {+/* clang-format on */+}
                relSourceHasScheme =
                    (relSource->scheme.first != NULL) ? URI_TRUE : URI_FALSE;
                if ((options & URI_RESOLVE_IDENTICAL_SCHEME_COMPAT)
                    && (absBase->scheme.first != NULL)
                    && (relSource->scheme.first != NULL)
                    && (0
                        == URI_FUNC(CompareRange)(&(absBase->scheme),
                                                  &(relSource->scheme)))) {
                    {+/* clang-format off */+}
    /* [00/32]     undefine(R.scheme); */
                    {+/* clang-format on */+}
                    relSourceHasScheme = URI_FALSE;
                    {+/* clang-format off */+}
    /* [00/32] endif; */
                    {+/* clang-format on */+}
                }

                {+/* clang-format off */+}
    /* [01/32] if defined(R.scheme) then */
                {+/* clang-format on */+}
                if (relSourceHasScheme) {
                    {+/* clang-format off */+}
    /* [02/32]     T.scheme = R.scheme; */
                    {+/* clang-format on */+}
                    absDest->scheme = relSource->scheme;
                    {+/* clang-format off */+}
    /* [03/32]     T.authority = R.authority; */
                    {+/* clang-format on */+}
                    if (!URI_FUNC(CopyAuthority)(absDest, relSource, memory)) {
                        return URI_ERROR_MALLOC;
                    }
                    {+/* clang-format off */+}
    /* [04/32]     T.path = remove_dot_segments(R.path); */
                    {+/* clang-format on */+}
                    if (!URI_FUNC(CopyPath)(absDest, relSource, memory)) {
                        return URI_ERROR_MALLOC;
                    }
                    if (!URI_FUNC(RemoveDotSegmentsAbsolute)(absDest, memory)) {
                        return URI_ERROR_MALLOC;
                    }
                    {+/* clang-format off */+}
    /* [05/32]     T.query = R.query; */
                    {+/* clang-format on */+}
                    absDest->query = relSource->query;
                    {+/* clang-format off */+}
    /* [06/32] else */
                    {+/* clang-format on */+}
                } else {
                    {+/* clang-format off */+}
    /* [07/32]     if defined(R.authority) then */
                    {+/* clang-format on */+}
                    if (URI_FUNC(HasHost)(relSource)) {
                        {+/* clang-format off */+}
    /* [08/32]         T.authority = R.authority; */
                        {+/* clang-format on */+}
                        if (!URI_FUNC(CopyAuthority)(absDest, relSource, memory)) {
                            return URI_ERROR_MALLOC;
                        }
                        {+/* clang-format off */+}
    /* [09/32]         T.path = remove_dot_segments(R.path); */
                        {+/* clang-format on */+}
                        if (!URI_FUNC(CopyPath)(absDest, relSource, memory)) {
                            return URI_ERROR_MALLOC;
                        }
                        if (!URI_FUNC(RemoveDotSegmentsAbsolute)(absDest, memory)) {
                            return URI_ERROR_MALLOC;
                        }
                        {+/* clang-format off */+}
    /* [10/32]         T.query = R.query; */
                        {+/* clang-format on */+}
                        absDest->query = relSource->query;
                        {+/* clang-format off */+}
    /* [11/32]     else */
                        {+/* clang-format on */+}
                    } else {
                        {+/* clang-format off */+}
    /* [28/32]         T.authority = Base.authority; */
                        {+/* clang-format on */+}
                        if (!URI_FUNC(CopyAuthority)(absDest, absBase, memory)) {
                            return URI_ERROR_MALLOC;
                        }
                        {+/* clang-format off */+}
    /* [12/32]         if (R.path == "") then */
                        {+/* clang-format on */+}
                        if (relSource->pathHead == NULL && !relSource->absolutePath) {
                            {+/* clang-format off */+}
    /* [13/32]             T.path = Base.path; */
                            {+/* clang-format on */+}
                            if (!URI_FUNC(CopyPath)(absDest, absBase, memory)) {
                                return URI_ERROR_MALLOC;
                            }
                            {+/* clang-format off */+}
    /* [14/32]             if defined(R.query) then */
                            {+/* clang-format on */+}
                            if (relSource->query.first != NULL) {
                                {+/* clang-format off */+}
    /* [15/32]                 T.query = R.query; */
                                {+/* clang-format on */+}
                                absDest->query = relSource->query;
                                {+/* clang-format off */+}
    /* [16/32]             else */
                                {+/* clang-format on */+}
                            } else {
                                {+/* clang-format off */+}
    /* [17/32]                 T.query = Base.query; */
                                {+/* clang-format on */+}
                                absDest->query = absBase->query;
                                {+/* clang-format off */+}
    /* [18/32]             endif; */
                                {+/* clang-format on */+}
                            }
                            {+/* clang-format off */+}
    /* [19/32]         else */
                            {+/* clang-format on */+}
                        } else {
                            /* {+clang-format off */+}
{+    /*+} [20/32]             if (R.path starts-with "/") then */
                            {+/* clang-format on */+}
                            if (relSource->absolutePath) {
                                int res;
                                /* {+clang-format off */+}
{+    /*+} [21/32]                 T.path =[-*-] remove_dot_segments(R.path); */
                                {+/* clang-format on */+}
                                if (!URI_FUNC(CopyPath)(absDest, relSource, memory)) {
                                    return URI_ERROR_MALLOC;
                                }
@@ -252,44 +308,65 @@ static int URI_FUNC(AddBaseUriImpl)(URI_TYPE(Uri) * absDest,
                                if (res != URI_SUCCESS) {
                                    return res;
                                }
                                if (!URI_FUNC(RemoveDotSegmentsAbsolute)(absDest,
                                                                         memory)) {
                                    return URI_ERROR_MALLOC;
                                }
                                {+/* clang-format off */+}
    /* [22/32]             else */
                                {+/* clang-format on */+}
                            } else {
                                /* {+clang-format off */+}
{+    /*+} [23/32]                 T.path = merge(Base.path,[-*-] R.path); */
                                {+/* clang-format on */+}
                                if (!URI_FUNC(CopyPath)(absDest, absBase, memory)) {
                                    return URI_ERROR_MALLOC;
                                }
                                if (!URI_FUNC(MergePath)(absDest, relSource, memory)) {
                                    return URI_ERROR_MALLOC;
                                }
                                /* {+clang-format off */+}
{+    /*+} [24/32]                 T.path =[-*-] remove_dot_segments(T.path); */
                                {+/* clang-format on */+}
                                if (!URI_FUNC(RemoveDotSegmentsAbsolute)(absDest,
                                                                         memory)) {
                                    return URI_ERROR_MALLOC;
                                }

                                if (!URI_FUNC(FixAmbiguity)(absDest, memory)) {
                                    return URI_ERROR_MALLOC;
                                }
                                {+/* clang-format off */+}
    /* [25/32]             endif; */
                            }
    {+/* clang-format off */+}
    /* [26/32]             T.query = R.query; */
                            {+/* clang-format on */+}
                            absDest->query = relSource->query;
                            {+/* clang-format off */+}
    /* [27/32]         endif; */
                            {+/* clang-format on */+}
                        }
                        URI_FUNC(FixEmptyTrailSegment)(absDest, memory);
                        {+/* clang-format off */+}
    /* [29/32]     endif; */
                        {+/* clang-format on */+}
                    }
                    {+/* clang-format off */+}
    /* [30/32]     T.scheme = Base.scheme; */
                    {+/* clang-format on */+}
                    absDest->scheme = absBase->scheme;
                    {+/* clang-format off */+}
    /* [31/32] endif; */
                    {+/* clang-format on */+}
                }
                {+/* clang-format off */+}
    /* [32/32] T.fragment = R.fragment; */
                {+/* clang-format on */+}
                absDest->fragment = relSource->fragment;
            {+}+}
{+        }+}
{+    }+}
    return URI_SUCCESS;
}

diff --git 1/uriparser.old/src/UriSetFragment.c 2/uriparser/src/UriSetFragment.c
index 90e8969..b9c5c53 100644
--- 1/uriparser.old/src/UriSetFragment.c
+++ 2/uriparser/src/UriSetFragment.c
@@ -254,16 +254,13 @@ int URI_FUNC(SetFragmentMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
    assert(uri->owner == URI_TRUE);

    /* Apply new value */
[-    {-]
    URI_TYPE(TextRange) sourceRange;
    sourceRange.first = first;
    sourceRange.afterLast = afterLast;

    if (URI_FUNC(CopyRangeAsNeeded)(&uri->fragment, &sourceRange, memory) == URI_FALSE) {
        return URI_ERROR_MALLOC;
    }
[-    }-]

    return URI_SUCCESS;
}
diff --git 1/uriparser.old/src/UriSetHostAuto.c 2/uriparser/src/UriSetHostAuto.c
index 294488b..df01588 100644
--- 1/uriparser.old/src/UriSetHostAuto.c
+++ 2/uriparser/src/UriSetHostAuto.c
@@ -80,7 +80,6 @@ int URI_FUNC(SetHostAutoMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
    }

    /* Auto-detect type and then apply */
[-    {-]
    UriHostType hostType;

    /* IPv6 or IPvFuture? */
@@ -116,7 +115,6 @@ int URI_FUNC(SetHostAutoMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,

    return URI_FUNC(InternalSetHostMm)(uri, hostType, first, afterLast, memory);
}
[-}-]

int URI_FUNC(SetHostAuto)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
                          const URI_CHAR * afterLast) {
diff --git 1/uriparser.old/src/UriSetHostCommon.c 2/uriparser/src/UriSetHostCommon.c
index 0062cab..bd8095a 100644
--- 1/uriparser.old/src/UriSetHostCommon.c
+++ 2/uriparser/src/UriSetHostCommon.c
@@ -131,7 +131,6 @@ int URI_FUNC(InternalSetHostMm)(URI_TYPE(Uri) * uri, UriHostType hostType,
        }
    }

[-    {-]
    /* Clear old value */
    const UriBool hadHostBefore = URI_FUNC(HasHost)(uri);
    if (uri->hostData.ipFuture.first != NULL) {
@@ -167,18 +166,17 @@ int URI_FUNC(InternalSetHostMm)(URI_TYPE(Uri) * uri, UriHostType hostType,
    if (first == NULL) {
        /* Yes, but disambiguate as needed */
        if (hadHostBefore == URI_TRUE) {
            {+if (uri->pathHead != NULL) {+}
                uri->absolutePath = URI_TRUE;
            {+}+}

[-                {-]
            const UriBool success =
                URI_FUNC(EnsureThatPathIsNotMistakenForHost)(uri, memory);
            return (success == URI_TRUE) ? URI_SUCCESS : URI_ERROR_MALLOC;
        }
[-            }-]

        return URI_SUCCESS;
    }
[-    }-]

    assert(first != NULL);

@@ -193,13 +191,11 @@ int URI_FUNC(InternalSetHostMm)(URI_TYPE(Uri) * uri, UriHostType hostType,
    assert(uri->owner == URI_TRUE);

    /* Apply new value; NOTE that .hostText is set for all four host types */
[-    {-]
    URI_TYPE(TextRange) sourceRange;
    sourceRange.first = first;
    sourceRange.afterLast = afterLast;

    if (URI_FUNC(CopyRangeAsNeeded)(&uri->hostText, &sourceRange, memory) == URI_FALSE) {
        return URI_ERROR_MALLOC;
    }

@@ -213,16 +209,13 @@ int URI_FUNC(InternalSetHostMm)(URI_TYPE(Uri) * uri, UriHostType hostType,
            return URI_ERROR_MALLOC;
        }

[-{-]        const int res =
            URI_FUNC(ParseIpFourAddress)(uri->hostData.ip4->data, first, afterLast);
#  if defined(NDEBUG)
        (void)res; /* i.e. mark as unused */
#  else
        assert(res == URI_SUCCESS); /* because checked for well-formedness earlier */
#  endif
[-            }-]
    } break;
    case URI_HOST_TYPE_IP6: {
        uri->hostData.ip6 = memory->malloc(memory, sizeof(UriIp6));
@@ -230,16 +223,14 @@ int URI_FUNC(InternalSetHostMm)(URI_TYPE(Uri) * uri, UriHostType hostType,
            return URI_ERROR_MALLOC;
        }

[-{-]        const int res =
            URI_FUNC(ParseIpSixAddressMm)(uri->hostData.ip6, first, afterLast, memory);
        assert((res == URI_SUCCESS)
               || (res == URI_ERROR_MALLOC)); /* because checked for
                                                 well-formedness earlier */
        if (res != URI_SUCCESS) {
            return res;
        }
[-            }-]
    } break;
    case URI_HOST_TYPE_IPFUTURE:
        uri->hostData.ipFuture.first = uri->hostText.first;
@@ -250,7 +241,6 @@ int URI_FUNC(InternalSetHostMm)(URI_TYPE(Uri) * uri, UriHostType hostType,
    default:
        assert(0 && "Unsupported URI host type");
    }
[-    }-]

    return URI_SUCCESS;
}
diff --git 1/uriparser.old/src/UriSetHostIp4.c 2/uriparser/src/UriSetHostIp4.c
index ce6d8bb..e52880b 100644
--- 1/uriparser.old/src/UriSetHostIp4.c
+++ 2/uriparser/src/UriSetHostIp4.c
@@ -72,14 +72,11 @@ UriBool URI_FUNC(IsWellFormedHostIp4)(const URI_CHAR * first,
        return URI_FALSE;
    }

[-    {-]
    unsigned char octetOutput[4];
    return (URI_FUNC(ParseIpFourAddress)(octetOutput, first, afterLast) == URI_SUCCESS)
               ? URI_TRUE
               : URI_FALSE;
}
[-}-]

int URI_FUNC(SetHostIp4Mm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
                           const URI_CHAR * afterLast, UriMemoryManager * memory) {
diff --git 1/uriparser.old/src/UriSetHostIp6.c 2/uriparser/src/UriSetHostIp6.c
index 2558077..9637a43 100644
--- 1/uriparser.old/src/UriSetHostIp6.c
+++ 2/uriparser/src/UriSetHostIp6.c
@@ -68,7 +68,8 @@
#  include <assert.h>
#  include <string.h> /* for memcpy */

#  define URI_MAX_IP6_LEN {+\+}
      (8 * 4 + 7 * 1) /* i.e. 8 full quads plus 7 colon separators \
                       */

int URI_FUNC(ParseIpSixAddressMm)(UriIp6 * output, const URI_CHAR * first,
@@ -92,7 +93,6 @@ int URI_FUNC(ParseIpSixAddressMm)(UriIp6 * output, const URI_CHAR * first,
    }

    /* Are we dealing with IPv6 input? */
[-    {-]
    /* Assemble "//[..]" input wrap for upcoming parse as a URI
     * NOTE: If the input contains closing "]" on its own, the resulting
     *       string will not be valid URI syntax, and hence there is
@@ -110,7 +110,6 @@ int URI_FUNC(ParseIpSixAddressMm)(UriIp6 * output, const URI_CHAR * first,
           2 * sizeof(URI_CHAR)); /* includes zero terminator */

    /* Parse as an RFC 3986 URI */
[-        {-]
    const size_t candidateLenChars = 3 + inputLenChars + 1;
    URI_TYPE(Uri) uri;
    const int res = URI_FUNC(ParseSingleUriExMm)(
@@ -131,8 +130,6 @@ int URI_FUNC(ParseIpSixAddressMm)(UriIp6 * output, const URI_CHAR * first,

    return res;
}
[-    }-]
[-}-]

int URI_FUNC(ParseIpSixAddress)(UriIp6 * output, const URI_CHAR * first,
                                const URI_CHAR * afterLast) {
diff --git 1/uriparser.old/src/UriSetHostIpFuture.c 2/uriparser/src/UriSetHostIpFuture.c
index c53be31..c5044c4 100644
--- 1/uriparser.old/src/UriSetHostIpFuture.c
+++ 2/uriparser/src/UriSetHostIpFuture.c
@@ -89,7 +89,6 @@ int URI_FUNC(IsWellFormedHostIpFutureMm)(const URI_CHAR * first,
    }

    /* Are we dealing with IPvFuture input? */
[-    {-]
    /* Assemble "//[..]" input wrap for upcoming parse as a URI
     * NOTE: If the input contains closing "]" on its own, the resulting
     *       string will not be valid URI syntax, and hence there is
@@ -102,7 +101,6 @@ int URI_FUNC(IsWellFormedHostIpFutureMm)(const URI_CHAR * first,
        return URI_ERROR_MALLOC;
    }

[-        {-]
    const size_t candidateLenChars = 3 + inputLenChars + 1;

    /* Detect overflow */
@@ -110,7 +108,6 @@ int URI_FUNC(IsWellFormedHostIpFutureMm)(const URI_CHAR * first,
        return URI_ERROR_MALLOC;
    }

[-            {-]
    URI_CHAR * const candidate =
        memory->malloc(memory, (candidateLenChars + 1) * sizeof(URI_CHAR));

@@ -124,7 +121,6 @@ int URI_FUNC(IsWellFormedHostIpFutureMm)(const URI_CHAR * first,
           2 * sizeof(URI_CHAR)); /* includes zero terminator */

    /* Parse as an RFC 3986 URI */
[-                {-]
    URI_TYPE(Uri) uri;
    const int res = URI_FUNC(ParseSingleUriExMm)(
        &uri, candidate, candidate + candidateLenChars, NULL, memory);
@@ -141,10 +137,6 @@ int URI_FUNC(IsWellFormedHostIpFutureMm)(const URI_CHAR * first,

    return res;
}
[-            }-]
[-        }-]
[-    }-]
[-}-]

int URI_FUNC(IsWellFormedHostIpFuture)(const URI_CHAR * first,
                                       const URI_CHAR * afterLast) {
diff --git 1/uriparser.old/src/UriSetPath.c 2/uriparser/src/UriSetPath.c
index 8e12ca3..d9e8bec 100644
--- 1/uriparser.old/src/UriSetPath.c
+++ 2/uriparser/src/UriSetPath.c
@@ -248,7 +248,6 @@ static void URI_FUNC(DropEmptyFirstPathSegment)(URI_TYPE(Uri) * uri,
    assert(uri->pathHead != NULL);
    assert(uri->pathHead->text.first == uri->pathHead->text.afterLast);

[-    {-]
    URI_TYPE(PathSegment) * const originalHead = uri->pathHead;

    uri->pathHead = uri->pathHead->next;
@@ -257,7 +256,6 @@ static void URI_FUNC(DropEmptyFirstPathSegment)(URI_TYPE(Uri) * uri,
    originalHead->text.afterLast = NULL;
    memory->free(memory, originalHead);
}
[-}-]

/* URIs without a host encode a leading slash in the path as .absolutePath == URI_TRUE.
 * This function checks for a leading empty path segment (that would have the "visual
@@ -305,7 +303,6 @@ static int URI_FUNC(InternalSetPath)(URI_TYPE(Uri) * destUri, const URI_CHAR * f
    }

    /* Assemble "///.." input wrap for upcoming parse as a URI */
[-    {-]
    const size_t inputLenChars = (afterLast - first);
    const size_t MAX_SIZE_T = (size_t)-1;

@@ -314,7 +311,6 @@ static int URI_FUNC(InternalSetPath)(URI_TYPE(Uri) * destUri, const URI_CHAR * f
        return URI_ERROR_MALLOC;
    }

[-        {-]
    const size_t candidateLenChars = 3 + inputLenChars;

    /* Detect overflow */
@@ -322,7 +318,6 @@ static int URI_FUNC(InternalSetPath)(URI_TYPE(Uri) * destUri, const URI_CHAR * f
        return URI_ERROR_MALLOC;
    }

[-            {-]
    URI_CHAR * const candidate =
        memory->malloc(memory, (candidateLenChars + 1) * sizeof(URI_CHAR));

@@ -335,10 +330,9 @@ static int URI_FUNC(InternalSetPath)(URI_TYPE(Uri) * destUri, const URI_CHAR * f
    candidate[3 + inputLenChars] = _UT('\0');

    /* Parse as an RFC 3986 URI */
[-                {-]
    URI_TYPE(Uri) tempUri;
[-const-]    int res = [-URI_FUNC(ParseSingleUriExMm)(-]
[-                        &tempUri,-]{+URI_FUNC(ParseSingleUriExMm)(&tempUri,+} candidate,
                                           candidate + candidateLenChars, NULL, memory);
    assert((res == URI_SUCCESS) || (res == URI_ERROR_SYNTAX)
           || (res == URI_ERROR_MALLOC));
    if (res != URI_SUCCESS) {
@@ -355,8 +349,7 @@ static int URI_FUNC(InternalSetPath)(URI_TYPE(Uri) * destUri, const URI_CHAR * f
     * `tempUri` because we want to (1) rip out and keep the full path
     * list further down and (2) be able to free the parsed string
     * (`candidate`) also. */
[-{-]
[-                        const int-]    res = URI_FUNC(MakeOwnerMm)(&tempUri, memory);
    assert((res == URI_SUCCESS) || (res == URI_ERROR_MALLOC));
    if (res != URI_SUCCESS) {
        URI_FUNC(FreeUriMembersMm)(&tempUri, memory);
@@ -364,11 +357,9 @@ static int URI_FUNC(InternalSetPath)(URI_TYPE(Uri) * destUri, const URI_CHAR * f
        return res;
    }
    assert(tempUri.owner == URI_TRUE);
[-                    }-]

    /* Move path to destination URI */
    assert(tempUri.absolutePath == URI_FALSE); /* always URI_FALSE for URIs with host */
    destUri->pathHead = tempUri.pathHead;
    destUri->pathTail = tempUri.pathTail;
    destUri->absolutePath = URI_FALSE;
@@ -384,24 +375,15 @@ static int URI_FUNC(InternalSetPath)(URI_TYPE(Uri) * destUri, const URI_CHAR * f
    URI_FUNC(TransformEmptyLeadPathSegments)(destUri, memory);

    /* Disambiguate as needed */
[-{-]
[-                        const-]    UriBool success = URI_FUNC(FixPathNoScheme)(destUri, memory);
    if (success == URI_FALSE) {
        return URI_ERROR_MALLOC;
    }
[-}-]
[-                    {-]
[-                        const UriBool-]
    success = URI_FUNC(EnsureThatPathIsNotMistakenForHost)(destUri, memory);
    if (success == URI_FALSE) {
        return URI_ERROR_MALLOC;
    }
[-                    }-]
[-                }-]
[-            }-]
[-        }-]
[-    }-]

    return URI_SUCCESS;
}
@@ -422,13 +404,11 @@ int URI_FUNC(SetPathMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
    }

    /* Clear old value */
[-{-]
[-        const-]    int res = URI_FUNC(FreeUriPath)(uri, memory);
    if (res != URI_SUCCESS) {
        return res;
    }
    uri->absolutePath = URI_FALSE;
[-    }-]

    /* Already done? */
    if (first == NULL) {
@@ -439,7 +419,7 @@ int URI_FUNC(SetPathMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,

    /* Ensure owned */
    if (uri->owner == URI_FALSE) {
[-const int-]        res = URI_FUNC(MakeOwnerMm)(uri, memory);
        if (res != URI_SUCCESS) {
            return res;
        }
@@ -448,13 +428,11 @@ int URI_FUNC(SetPathMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
    assert(uri->owner == URI_TRUE);

    /* Apply new value */
[-{-]
[-        const int-]    res = URI_FUNC(InternalSetPath)(uri, first, afterLast, memory);
    assert((res == URI_SUCCESS) || (res == URI_ERROR_SYNTAX)
           || (res == URI_ERROR_MALLOC));
    return res;
}
[-}-]

int URI_FUNC(SetPath)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
                      const URI_CHAR * afterLast) {
diff --git 1/uriparser.old/src/UriSetPort.c 2/uriparser/src/UriSetPort.c
index 24ceb95..1c37301 100644
--- 1/uriparser.old/src/UriSetPort.c
+++ 2/uriparser/src/UriSetPort.c
@@ -140,16 +140,13 @@ int URI_FUNC(SetPortTextMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
    assert(uri->owner == URI_TRUE);

    /* Apply new value */
[-    {-]
    URI_TYPE(TextRange) sourceRange;
    sourceRange.first = first;
    sourceRange.afterLast = afterLast;

    if (URI_FUNC(CopyRangeAsNeeded)(&uri->portText, &sourceRange, memory) == URI_FALSE) {
        return URI_ERROR_MALLOC;
    }
[-    }-]

    return URI_SUCCESS;
}
diff --git 1/uriparser.old/src/UriSetQuery.c 2/uriparser/src/UriSetQuery.c
index 8cd862d..a189c14 100644
--- 1/uriparser.old/src/UriSetQuery.c
+++ 2/uriparser/src/UriSetQuery.c
@@ -252,7 +252,6 @@ int URI_FUNC(SetQueryMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
    assert(uri->owner == URI_TRUE);

    /* Apply new value */
[-    {-]
    URI_TYPE(TextRange) sourceRange;
    sourceRange.first = first;
    sourceRange.afterLast = afterLast;
@@ -260,7 +259,6 @@ int URI_FUNC(SetQueryMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
    if (URI_FUNC(CopyRangeAsNeeded)(&uri->query, &sourceRange, memory) == URI_FALSE) {
        return URI_ERROR_MALLOC;
    }
[-    }-]

    return URI_SUCCESS;
}
diff --git 1/uriparser.old/src/UriSetScheme.c 2/uriparser/src/UriSetScheme.c
index 48e6d54..9a21d45 100644
--- 1/uriparser.old/src/UriSetScheme.c
+++ 2/uriparser/src/UriSetScheme.c
@@ -222,16 +222,13 @@ int URI_FUNC(SetSchemeMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
    assert(uri->owner == URI_TRUE);

    /* Apply new value */
[-    {-]
    URI_TYPE(TextRange) sourceRange;
    sourceRange.first = first;
    sourceRange.afterLast = afterLast;

    if (URI_FUNC(CopyRangeAsNeeded)(&uri->scheme, &sourceRange, memory) == URI_FALSE) {
        return URI_ERROR_MALLOC;
    }
[-    }-]

    return URI_SUCCESS;
}
diff --git 1/uriparser.old/src/UriSetUserInfo.c 2/uriparser/src/UriSetUserInfo.c
index 9fb3e5f..af1ec41 100644
--- 1/uriparser.old/src/UriSetUserInfo.c
+++ 2/uriparser/src/UriSetUserInfo.c
@@ -254,16 +254,13 @@ int URI_FUNC(SetUserInfoMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
    assert(uri->owner == URI_TRUE);

    /* Apply new value */
[-    {-]
    URI_TYPE(TextRange) sourceRange;
    sourceRange.first = first;
    sourceRange.afterLast = afterLast;

    if (URI_FUNC(CopyRangeAsNeeded)(&uri->userInfo, &sourceRange, memory) == URI_FALSE) {
        return URI_ERROR_MALLOC;
    }
[-    }-]

    return URI_SUCCESS;
}
diff --git 1/uriparser.old/src/UriShorten.c 2/uriparser/src/UriShorten.c
index b241c3c..548b0b4 100644
--- 1/uriparser.old/src/UriShorten.c
+++ 2/uriparser/src/UriShorten.c
@@ -145,47 +145,85 @@ static int URI_FUNC(RemoveBaseUriImpl)(URI_TYPE(Uri) * dest,
        return URI_ERROR_REMOVEBASE_REL_SOURCE;
    }

    {+/* NOTE: The curly brackets here force deeper indent (and that's all) */+}
{+    {+}
{+        {+}
{+            {+}
{+                /* clang-format off */+}
    /* [01/50] if (A.scheme != Base.scheme) then */
                {+/* clang-format on */+}
                if (URI_FUNC(CompareRange)(&absSource->scheme, &absBase->scheme)) {
                    {+/* clang-format off */+}
    /* [02/50]    T.scheme    = A.scheme; */
                    {+/* clang-format on */+}
                    dest->scheme = absSource->scheme;
                    {+/* clang-format off */+}
    /* [03/50]    T.authority = A.authority; */
                    {+/* clang-format on */+}
                    if (!URI_FUNC(CopyAuthority)(dest, absSource, memory)) {
                        return URI_ERROR_MALLOC;
                    }
                    {+/* clang-format off */+}
    /* [04/50]    T.path      = A.path; */
                    {+/* clang-format on */+}
                    if (!URI_FUNC(CopyPath)(dest, absSource, memory)) {
                        return URI_ERROR_MALLOC;
                    }
                    {+/* clang-format off */+}
    /* [05/50] else */
                    {+/* clang-format on */+}
                } else {
                    {+/* clang-format off */+}
    /* [06/50]    undef(T.scheme); */
                    {+/* clang-format on */+}
                    /* NOOP */
                    {+/* clang-format off */+}
    /* [07/50]    if (A.authority != Base.authority) then */
                    {+/* clang-format on */+}
                    if (!URI_FUNC(EqualsAuthority)(absSource, absBase)) {
                        {+/* clang-format off */+}
    /* [08/50]       T.authority = A.authority; */
                        {+/* clang-format on */+}
                        if (!URI_FUNC(CopyAuthority)(dest, absSource, memory)) {
                            return URI_ERROR_MALLOC;
                        }
                        {+/* clang-format off */+}
    /* [09/50]       T.path      = A.path; */
                        {+/* clang-format on */+}
                        if (!URI_FUNC(CopyPath)(dest, absSource, memory)) {
                            return URI_ERROR_MALLOC;
                        }
                        {+/* clang-format off */+}
    /* [10/50]    else */
                        {+/* clang-format on */+}
                    } else {
                        {+/* clang-format off */+}
    /* [11/50]       if domainRootMode then */
                        {+/* clang-format on */+}
                        if (domainRootMode == URI_TRUE) {
                            {+/* clang-format off */+}
    /* [12/50]          undef(T.authority); */
                            {+/* clang-format on */+}
                            /* NOOP */
                            {+/* clang-format off */+}
    /* [13/50]          if (first(A.path) == "") then */
                            {+/* clang-format on */+}
                            /* GROUPED */
                            {+/* clang-format off */+}
    /* [14/50]             T.path   = "/." + A.path; */
                            {+/* clang-format on */+}
                            /* GROUPED */
                            {+/* clang-format off */+}
    /* [15/50]          else */
                            {+/* clang-format on */+}
                            /* GROUPED */
                            {+/* clang-format off */+}
    /* [16/50]             T.path   = A.path; */
                            {+/* clang-format on */+}
                            /* GROUPED */
                            {+/* clang-format off */+}
    /* [17/50]          endif; */
                            {+/* clang-format on */+}
                            if (!URI_FUNC(CopyPath)(dest, absSource, memory)) {
                                return URI_ERROR_MALLOC;
                            }
@@ -194,46 +232,81 @@ static int URI_FUNC(RemoveBaseUriImpl)(URI_TYPE(Uri) * dest,
                            if (!URI_FUNC(FixAmbiguity)(dest, memory)) {
                                return URI_ERROR_MALLOC;
                            }
                            {+/* clang-format off */+}
    /* [18/50]       else */
                            {+/* clang-format on */+}
                        } else {
                            const URI_TYPE(PathSegment) * sourceSeg = absSource->pathHead;
                            const URI_TYPE(PathSegment) * baseSeg = absBase->pathHead;
                            {+/* clang-format off */+}
    /* [19/50]          bool pathNaked = true; */
                            {+/* clang-format on */+}
                            UriBool pathNaked = URI_TRUE;
                            {+/* clang-format off */+}
    /* [20/50]          undef(last(Base.path)); */
                            {+/* clang-format on */+}
                            /* NOOP */
                            {+/* clang-format off */+}
    /* [21/50]          T.path = ""; */
                            {+/* clang-format on */+}
                            dest->absolutePath = URI_FALSE;
                            {+/* clang-format off */+}
    /* [22/50]          while (first(A.path) == first(Base.path)) do */
                            {+/* clang-format on */+}
                            while [-((sourceSeg-]{+(+}
{+                                (sourceSeg+} != NULL) && (baseSeg != NULL)
                                && !URI_FUNC(CompareRange)(&sourceSeg->text,
                                                           &baseSeg->text)
                                && !((sourceSeg->text.first == sourceSeg->text.afterLast)
                                     && ((sourceSeg->next == NULL)
                                         != (baseSeg->next == NULL)))) {
                                {+/* clang-format off */+}
    /* [23/50]             A.path++; */
                                {+/* clang-format on */+}
                                sourceSeg = sourceSeg->next;
                                {+/* clang-format off */+}
    /* [24/50]             Base.path++; */
                                {+/* clang-format on */+}
                                baseSeg = baseSeg->next;
                                {+/* clang-format off */+}
    /* [25/50]          endwhile; */
                                {+/* clang-format on */+}
                            }
                            {+/* clang-format off */+}
    /* [26/50]          while defined(first(Base.path)) do */
                            {+/* clang-format on */+}
                            while ((baseSeg != NULL) && (baseSeg->next != NULL)) {
                                {+/* clang-format off */+}
    /* [27/50]             Base.path++; */
                                {+/* clang-format on */+}
                                baseSeg = baseSeg->next;
                                {+/* clang-format off */+}
    /* [28/50]             T.path += "../"; */
                                {+/* clang-format on */+}
                                if (!URI_FUNC(AppendSegment)(dest, URI_FUNC(ConstParent),
                                                             URI_FUNC(ConstParent) + 2,
                                                             memory)) {
                                    return URI_ERROR_MALLOC;
                                }
                                {+/* clang-format off */+}
    /* [29/50]             pathNaked = false; */
                                {+/* clang-format on */+}
                                pathNaked = URI_FALSE;
                                {+/* clang-format off */+}
    /* [30/50]          endwhile; */
                                {+/* clang-format on */+}
                            }
                            {+/* clang-format off */+}
    /* [31/50]          while defined(first(A.path)) do */
                            {+/* clang-format on */+}
                            while (sourceSeg != NULL) {
                                {+/* clang-format off */+}
    /* [32/50]             if pathNaked then */
                                {+/* clang-format on */+}
                                if (pathNaked == URI_TRUE) {
                                    /* {+clang-format off */+}
{+    /*+} [33/50]                if (first(A.path) contains ":")[-*-] then */
                                    {+/* clang-format on */+}
                                    UriBool containsColon = URI_FALSE;
                                    const URI_CHAR * ch = sourceSeg->text.first;
                                    for (; ch < sourceSeg->text.afterLast; ch++) {
@@ -244,53 +317,90 @@ static int URI_FUNC(RemoveBaseUriImpl)(URI_TYPE(Uri) * dest,
                                    }

                                    if (containsColon) {
                                        {+/* clang-format off */+}
    /* [34/50]                   T.path += "./"; */
                                        {+/* clang-format on */+}
                                        if [-(!URI_FUNC(AppendSegment)(dest,-]{+(!URI_FUNC(AppendSegment)(+}
{+                                                dest,+} URI_FUNC(ConstPwd),
                                                URI_FUNC(ConstPwd) + 1, memory)) {
                                            return URI_ERROR_MALLOC;
                                        }
                                        /* {+clang-format off */+}
{+    /*+} [35/50]                elseif (first(A.path) == "") then */
                                        {+/* clang-format on */+}
                                    } else if (sourceSeg->text.first
                                               == sourceSeg->text.afterLast) {
                                        {+/* clang-format off */+}
    /* [36/50]                   T.path += "/."; */
                                        {+/* clang-format on */+}
                                        if [-(!URI_FUNC(AppendSegment)(dest,-]{+(!URI_FUNC(AppendSegment)(+}
{+                                                dest,+} URI_FUNC(ConstPwd),
                                                URI_FUNC(ConstPwd) + 1, memory)) {
                                            return URI_ERROR_MALLOC;
                                        }
                                        {+/* clang-format off */+}
    /* [37/50]                endif; */
                                        {+/* clang-format on */+}
                                    }
                                    {+/* clang-format off */+}
    /* [38/50]             endif; */
                                    {+/* clang-format on */+}
                                }
                                {+/* clang-format off */+}
    /* [39/50]             T.path += first(A.path); */
                                {+/* clang-format on */+}
                                if (!URI_FUNC(AppendSegment)(dest, sourceSeg->text.first,
                                                             sourceSeg->text.afterLast,
                                                             memory)) {
                                    return URI_ERROR_MALLOC;
                                }
                                {+/* clang-format off */+}
    /* [40/50]             pathNaked = false; */
                                {+/* clang-format on */+}
                                pathNaked = URI_FALSE;
                                {+/* clang-format off */+}
    /* [41/50]             A.path++; */
                                {+/* clang-format on */+}
                                sourceSeg = sourceSeg->next;
                                {+/* clang-format off */+}
    /* [42/50]             if defined(first(A.path)) then */
                                {+/* clang-format on */+}
                                /* NOOP */
                                {+/* clang-format off */+}
    /* [43/50]                T.path += + "/"; */
                                {+/* clang-format on */+}
                                /* NOOP */
                                {+/* clang-format off */+}
    /* [44/50]             endif; */
                                {+/* clang-format on */+}
                                /* NOOP */
                                {+/* clang-format off */+}
    /* [45/50]          endwhile; */
                                {+/* clang-format on */+}
                            }
                            {+/* clang-format off */+}
    /* [46/50]       endif; */
                            {+/* clang-format on */+}
                        }
                        {+/* clang-format off */+}
    /* [47/50]    endif; */
                        {+/* clang-format on */+}
                    }
                    {+/* clang-format off */+}
    /* [48/50] endif; */
                    {+/* clang-format on */+}
                }
                {+/* clang-format off */+}
    /* [49/50] T.query     = A.query; */
                {+/* clang-format on */+}
                dest->query = absSource->query;
                {+/* clang-format off */+}
    /* [50/50] T.fragment  = A.fragment; */
                {+/* clang-format on */+}
                dest->fragment = absSource->fragment;
            {+}+}
{+        }+}
{+    }+}
    return URI_SUCCESS;
}

Copy link
Member

@ndossche ndossche left a comment

Choose a reason for hiding this comment

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

I checked by copying the uriparser sources into PHP and seeing that the diff is empty.
Also ran all tests locally and seems fine.
Changelog seems fine too.

@TimWolla
Copy link
Member Author

TimWolla commented Nov 9, 2025

the git log seems to agree:

Could even simplify this further by filtering it to src/ and include/:

$ git shortlog 08df3b2..c3b4956 -- src/ include/
Sebastian Pipping (5):
      Join two long lines back together
      Exclude parts of the code from auto-formatting
      Make "clang-format off" code blend in better
      Use artificial indent to restore original visual
      Remove artificial C89 support scopes

Tim Düsterhus (3):
      src/UriMemory.c: Exclude `uriTestMemoryManagerEx()` from mutation testing
      src/UriMemory.c: Exclude mutant without consequence in `uriDecorateRealloc()`
      src/UriSetHostCommon.c: Do not set `absolutePath` for empty paths when removing host

clang-format 21.1.3 (2):
      Mass-apply clang-format 21.1.3
      Mass-apply clang-format 21.1.3

* OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#if !defined(URI_CONFIG_H)
Copy link
Contributor

Choose a reason for hiding this comment

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

ext/uri/uriparser/src/UriConfig.h.in should be deleted as it is stored as ext/uri/uriparser/src/UriConfig.h

I found this when coding the download script for #19802.

Copy link
Contributor

Choose a reason for hiding this comment

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

and also mvorisek@72097ba

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants