1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00
Files
archived-php-src/ext/uri/uriparser/src/UriCopy.c
2025-09-04 23:58:08 +02:00

240 lines
7.2 KiB
C

/*
* uriparser - RFC 3986 URI parsing library
*
* Copyright (C) 2007, Weijia Song <songweijia@gmail.com>
* Copyright (C) 2007, Sebastian Pipping <sebastian@pipping.org>
* Copyright (C) 2025, Máté Kocsis <kocsismate@php.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* 2. 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.
*
* 3. Neither the name of the copyright holder 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 HOLDER 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 UriCopy.c
* Holds the RFC 3986 %URI normalization implementation.
* NOTE: This source file includes itself twice.
*/
/* What encodings are enabled? */
#include <uriparser/UriDefsConfig.h>
#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
/* Include SELF twice */
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriCopy.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriCopy.c"
# undef URI_PASS_UNICODE
# endif
#else
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# include <wchar.h>
# endif
#ifndef URI_DOXYGEN
# include <uriparser/Uri.h>
# include "UriCommon.h"
# include "UriMemory.h"
# include "UriNormalize.h"
# include "UriCopy.h"
#endif
static void URI_FUNC(PreventLeakageAfterCopy)(URI_TYPE(Uri) * uri,
unsigned int revertMask, UriMemoryManager * memory) {
URI_FUNC(PreventLeakage)(uri, revertMask, memory);
if (uri->hostData.ip4 != NULL) {
memory->free(memory, uri->hostData.ip4);
uri->hostData.ip4 = NULL;
} else if (uri->hostData.ip6 != NULL) {
memory->free(memory, uri->hostData.ip6);
uri->hostData.ip6 = NULL;
}
if (revertMask & URI_NORMALIZE_PORT) {
if (uri->portText.first != uri->portText.afterLast) {
memory->free(memory, (URI_CHAR *)uri->portText.first);
}
uri->portText.first = NULL;
uri->portText.afterLast = NULL;
}
}
int URI_FUNC(CopyUriMm)(URI_TYPE(Uri) * destUri,
const URI_TYPE(Uri) * sourceUri, UriMemoryManager * memory) {
unsigned int revertMask = URI_NORMALIZED;
if (sourceUri == NULL || destUri == NULL) {
return URI_ERROR_NULL;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
URI_FUNC(ResetUri)(destUri);
if (URI_FUNC(CopyRangeAsNeeded)(&destUri->scheme, &sourceUri->scheme, memory) == URI_FALSE) {
return URI_ERROR_MALLOC;
}
revertMask |= URI_NORMALIZE_SCHEME;
if (URI_FUNC(CopyRangeAsNeeded)(&destUri->userInfo, &sourceUri->userInfo, memory) == URI_FALSE) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
revertMask |= URI_NORMALIZE_USER_INFO;
if (URI_FUNC(CopyRangeAsNeeded)(&destUri->hostText, &sourceUri->hostText, memory) == URI_FALSE) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
revertMask |= URI_NORMALIZE_HOST;
if (sourceUri->hostData.ip4 == NULL) {
destUri->hostData.ip4 = NULL;
} else {
destUri->hostData.ip4 = memory->malloc(memory, sizeof(UriIp4));
if (destUri->hostData.ip4 == NULL) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
*(destUri->hostData.ip4) = *(sourceUri->hostData.ip4);
}
if (sourceUri->hostData.ip6 == NULL) {
destUri->hostData.ip6 = NULL;
} else {
destUri->hostData.ip6 = memory->malloc(memory, sizeof(UriIp6));
if (destUri->hostData.ip6 == NULL) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
*(destUri->hostData.ip6) = *(sourceUri->hostData.ip6);
}
if (sourceUri->hostData.ipFuture.first != NULL) {
destUri->hostData.ipFuture.first = destUri->hostText.first;
destUri->hostData.ipFuture.afterLast = destUri->hostText.afterLast;
} else if (URI_FUNC(CopyRangeAsNeeded)(&destUri->hostData.ipFuture, &sourceUri->hostData.ipFuture, memory) == URI_FALSE) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
if (URI_FUNC(CopyRangeAsNeeded)(&destUri->portText, &sourceUri->portText, memory) == URI_FALSE) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
revertMask |= URI_NORMALIZE_PORT;
destUri->pathHead = NULL;
destUri->pathTail = NULL;
if (sourceUri->pathHead != NULL) {
URI_TYPE(PathSegment) * sourceWalker = sourceUri->pathHead;
URI_TYPE(PathSegment) * destPrev = NULL;
while (sourceWalker != NULL) {
URI_TYPE(PathSegment) * destWalker = memory->malloc(memory, sizeof(URI_TYPE(PathSegment)));
if (destWalker == NULL) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
destWalker->text.first = NULL;
destWalker->text.afterLast = NULL;
destWalker->next = NULL;
destWalker->reserved = NULL;
if (destUri->pathHead == NULL) {
destUri->pathHead = destWalker;
revertMask |= URI_NORMALIZE_PATH;
}
if (URI_FUNC(CopyRangeAsNeeded)(&destWalker->text, &sourceWalker->text, memory) == URI_FALSE) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
if (destPrev != NULL) {
destPrev->next = destWalker;
}
destPrev = destWalker;
sourceWalker = sourceWalker->next;
destUri->pathTail = destWalker;
}
}
if (URI_FUNC(CopyRangeAsNeeded)(&destUri->query, &sourceUri->query, memory) == URI_FALSE) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
revertMask |= URI_NORMALIZE_QUERY;
if (URI_FUNC(CopyRangeAsNeeded)(&destUri->fragment, &sourceUri->fragment, memory) == URI_FALSE) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
destUri->absolutePath = sourceUri->absolutePath;
destUri->owner = URI_TRUE;
destUri->reserved = NULL;
return URI_SUCCESS;
}
int URI_FUNC(CopyUri)(URI_TYPE(Uri) * destUri,
const URI_TYPE(Uri) * sourceUri) {
return URI_FUNC(CopyUriMm)(destUri, sourceUri, NULL);
}
#endif