mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Merge branch 'PHP-8.5'
* PHP-8.5: uri: Update to uriparser-0.9.9-21-g08df3b2 (#19992)
This commit is contained in:
@@ -33,7 +33,7 @@ if test "$PHP_EXTERNAL_URIPARSER" = "no"; then
|
||||
$URIPARSER_DIR/src/UriSetScheme.c $URIPARSER_DIR/src/UriSetUserInfo.c $URIPARSER_DIR/src/UriShorten.c $URIPARSER_DIR/src/UriVersion.c"
|
||||
URI_CFLAGS="-DURI_STATIC_BUILD"
|
||||
else
|
||||
PKG_CHECK_MODULES([LIBURIPARSER], [liburiparser >= 0.9.9])
|
||||
PKG_CHECK_MODULES([LIBURIPARSER], [liburiparser >= 0.9.10])
|
||||
PHP_EVAL_LIBLINE([$LIBURIPARSER_LIBS], [URI_SHARED_LIBADD])
|
||||
PHP_EVAL_INCLINE([$LIBURIPARSER_CFLAGS])
|
||||
fi
|
||||
|
||||
@@ -137,7 +137,7 @@ typedef struct URI_TYPE(HostDataStruct) {
|
||||
URI_TYPE(TextRange) ipFuture; /**< IPvFuture address
|
||||
@note
|
||||
With non-<c>NULL</c> members in UriUriStructA.hostData context,
|
||||
this text range's pointers must be <em>idential</em> to those
|
||||
this text range's pointers must be <em>identical</em> to those
|
||||
of UriUriStructA.hostText at all times. */
|
||||
} URI_TYPE(HostData); /**< @copydoc UriHostDataStructA */
|
||||
|
||||
@@ -1420,7 +1420,7 @@ URI_PUBLIC UriBool URI_FUNC(IsWellFormedHostRegName)(const URI_CHAR * first, con
|
||||
*
|
||||
* @param first <b>IN</b>: Pointer to first character
|
||||
* @param afterLast <b>IN</b>: Pointer to character after the last one still in
|
||||
* @param hasHost <b>IN</b>: Wether the target %URI has a non-<c>NULL</c> host set or not
|
||||
* @param hasHost <b>IN</b>: Whether the target %URI has a non-<c>NULL</c> host set or not
|
||||
* @return <c>URI_TRUE</c> if non-<c>NULL</c> and well-formed, else <c>URI_FALSE</c>
|
||||
*
|
||||
* @see uriIsWellFormedFragmentA
|
||||
@@ -2415,7 +2415,7 @@ URI_PUBLIC int URI_FUNC(SetUserInfoMm)(URI_TYPE(Uri) * uri,
|
||||
* or even fully custom patches. As a result, the version string
|
||||
* returned serves as nothing more than "based on that version",
|
||||
* it does not guarantee equivalence to vanilla upstream releases
|
||||
* or absence of additinal downstream patches.
|
||||
* or absence of additional downstream patches.
|
||||
* It is nothing more than "a hint" and MUST NEVER be used to
|
||||
* make decisions on in application code at runtime.
|
||||
*
|
||||
|
||||
@@ -187,7 +187,7 @@ typedef struct UriIp6Struct {
|
||||
} UriIp6; /**< @copydoc UriIp6Struct */
|
||||
|
||||
|
||||
struct UriMemoryManagerStruct; /* foward declaration to break loop */
|
||||
struct UriMemoryManagerStruct; /* forward declaration to break loop */
|
||||
|
||||
|
||||
/**
|
||||
@@ -287,28 +287,34 @@ typedef enum UriResolutionOptionsEnum {
|
||||
|
||||
|
||||
/**
|
||||
* Wraps a memory manager backend that only provides malloc and free
|
||||
* to make a complete memory manager ready to be used.
|
||||
* Wraps a memory manager backend that only provides <c>malloc(3)</c> and
|
||||
* <c>free(3)</c> to make a complete memory manager ready to be used.
|
||||
*
|
||||
* The core feature of this wrapper is that you don't need to implement
|
||||
* realloc if you don't want to. The wrapped memory manager uses
|
||||
* backend->malloc, memcpy, and backend->free and soieof(size_t) extra
|
||||
* bytes per allocation to emulate fallback realloc for you.
|
||||
* <c>realloc(3)</c> if you don't want to. The wrapped memory manager uses
|
||||
* <c>backend->malloc</c>, <c>memcpy(3)</c>, and <c>backend->free</c> and
|
||||
* (at least) <c>sizeof(size_t)</c> extra bytes per allocation to emulate
|
||||
* fallback <c>realloc(3)</c> for you.
|
||||
*
|
||||
* memory->calloc is uriEmulateCalloc.
|
||||
* memory->free uses backend->free and handles the size header.
|
||||
* memory->malloc uses backend->malloc and adds a size header.
|
||||
* memory->realloc uses memory->malloc, memcpy, and memory->free and reads
|
||||
* the size header.
|
||||
* memory->reallocarray is uriEmulateReallocarray.
|
||||
* <ul>
|
||||
* <li><c>memory->calloc</c> is <c>uriEmulateCalloc</c>.</li>
|
||||
* <li><c>memory->free</c> uses <c>backend->free</c>,
|
||||
* and handles the size header.</li>
|
||||
* <li><c>memory->malloc</c> uses <c>backend->malloc</c>,
|
||||
* and adds a size header.</li>
|
||||
* <li><c>memory->realloc</c> uses <c>memory->malloc</c>,
|
||||
* <c>memcpy(3)</c> and <c>memory->free</c>,
|
||||
* and reads the size header.</li>
|
||||
* <li><c>memory->reallocarray</c> is <c>uriEmulateReallocarray</c>.</li>
|
||||
* </ul>
|
||||
*
|
||||
* The internal workings behind memory->free, memory->malloc, and
|
||||
* memory->realloc may change so the functions exposed by these function
|
||||
* pointer sshould be consided internal and not public API.
|
||||
* The internal workings behind <c>memory->free</c>, <c>memory->malloc</c>,
|
||||
* and <c>memory->realloc</c> may change, and the functions exposed by these
|
||||
* function pointers should be considered internal and not public API.
|
||||
*
|
||||
* @param memory <b>OUT</b>: Where to write the wrapped memory manager to
|
||||
* @param backend <b>IN</b>: Memory manager to use as a backend
|
||||
* @return Error code or 0 on success
|
||||
* @return Error code or 0 on success
|
||||
*
|
||||
* @see uriEmulateCalloc
|
||||
* @see uriEmulateReallocarray
|
||||
@@ -321,7 +327,7 @@ URI_PUBLIC int uriCompleteMemoryManager(UriMemoryManager * memory,
|
||||
|
||||
|
||||
/**
|
||||
* Offers emulation of calloc(3) based on memory->malloc and memset.
|
||||
* Offers emulation of calloc(3) based on memory->malloc and memset.
|
||||
* See "man 3 calloc" as well.
|
||||
*
|
||||
* @param memory <b>IN</b>: Memory manager to use, should not be NULL
|
||||
@@ -340,11 +346,11 @@ URI_PUBLIC void * uriEmulateCalloc(UriMemoryManager * memory,
|
||||
|
||||
|
||||
/**
|
||||
* Offers emulation of reallocarray(3) based on memory->realloc.
|
||||
* Offers emulation of reallocarray(3) based on memory->realloc.
|
||||
* See "man 3 reallocarray" as well.
|
||||
*
|
||||
* @param memory <b>IN</b>: Memory manager to use, should not be NULL
|
||||
* @param ptr <b>IN</b>: Pointer allocated using memory->malloc/... or NULL
|
||||
* @param ptr <b>IN</b>: Pointer allocated using memory->malloc/... or NULL
|
||||
* @param nmemb <b>IN</b>: Number of elements to allocate
|
||||
* @param size <b>IN</b>: Size in bytes per element
|
||||
* @return Pointer to allocated memory or NULL
|
||||
@@ -369,7 +375,11 @@ URI_PUBLIC void * uriEmulateReallocarray(UriMemoryManager * memory,
|
||||
* 5. and frees that memory.
|
||||
*
|
||||
* It is recommended to compile with AddressSanitizer enabled
|
||||
* to take full advantage of uriTestMemoryManager.
|
||||
* to take full advantage of <c>uriTestMemoryManager</c>.
|
||||
*
|
||||
* For backwards-compatibility, <c>uriTestMemoryManager</c>
|
||||
* does not challenge pointer alignment; please see
|
||||
* <c>uriTestMemoryManagerEx</c> for that feature.
|
||||
*
|
||||
* @param memory <b>IN</b>: Memory manager to use, should not be NULL
|
||||
* @return Error code or 0 on success
|
||||
@@ -377,10 +387,40 @@ URI_PUBLIC void * uriEmulateReallocarray(UriMemoryManager * memory,
|
||||
* @see uriEmulateCalloc
|
||||
* @see uriEmulateReallocarray
|
||||
* @see UriMemoryManager
|
||||
* @see uriTestMemoryManagerEx
|
||||
* @since 0.9.0
|
||||
*/
|
||||
URI_PUBLIC int uriTestMemoryManager(UriMemoryManager * memory);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Run multiple tests against a given memory manager.
|
||||
* For example, one test
|
||||
* 1. allocates a small amount of memory,
|
||||
* 2. writes some magic bytes to it,
|
||||
* 3. reallocates it,
|
||||
* 4. checks that previous values are still present,
|
||||
* 5. and frees that memory.
|
||||
*
|
||||
* It is recommended to compile with both AddressSanitizer and
|
||||
* UndefinedBehaviorSanitizer enabled to take full advantage of
|
||||
* <c>uriTestMemoryManagerEx</c>. Note that environment variable
|
||||
* <c>UBSAN_OPTIONS</c> may need adjustment to make UndefinedBehaviorSanitizer
|
||||
* fatal (which by default it is not).
|
||||
*
|
||||
* @param memory <b>IN</b>: Memory manager to use, should not be NULL
|
||||
* @param challengeAlignment <b>IN</b>: Whether to challenge pointer alignment
|
||||
* @return Error code or 0 on success
|
||||
*
|
||||
* @see uriEmulateCalloc
|
||||
* @see uriEmulateReallocarray
|
||||
* @see UriMemoryManager
|
||||
* @see uriTestMemoryManager
|
||||
* @since 0.9.10
|
||||
*/
|
||||
URI_PUBLIC int uriTestMemoryManagerEx(UriMemoryManager * memory, UriBool challengeAlignment);
|
||||
|
||||
|
||||
|
||||
#endif /* URI_BASE_H */
|
||||
|
||||
@@ -208,14 +208,25 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,
|
||||
*
|
||||
* For example, changing "./http://foo" into "http://foo" would change semantics
|
||||
* and hence the dot segment is essential to that case and cannot be removed.
|
||||
*
|
||||
* Other examples that would change semantics are:
|
||||
* - cutting "/.//" down to "//"
|
||||
* - cutting "scheme:/.//" down to "scheme://".
|
||||
*/
|
||||
removeSegment = URI_TRUE;
|
||||
if (relative && (walker == uri->pathHead) && (walker->next != NULL)) {
|
||||
const URI_CHAR * ch = walker->next->text.first;
|
||||
for (; ch < walker->next->text.afterLast; ch++) {
|
||||
if (*ch == _UT(':')) {
|
||||
removeSegment = URI_FALSE;
|
||||
break;
|
||||
if ((walker == uri->pathHead) && (walker->next != NULL)) {
|
||||
/* Detect case "/.//" (with or without scheme) */
|
||||
if ((walker->next->text.first == walker->next->text.afterLast)
|
||||
&& (URI_FUNC(HasHost)(uri) == URI_FALSE)) {
|
||||
removeSegment = URI_FALSE;
|
||||
/* Detect case "./withcolon:" */
|
||||
} else if (relative) {
|
||||
const URI_CHAR * ch = walker->next->text.first;
|
||||
for (; ch < walker->next->text.afterLast; ch++) {
|
||||
if (*ch == _UT(':')) {
|
||||
removeSegment = URI_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -358,7 +369,7 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,
|
||||
}
|
||||
memory->free(memory, walker);
|
||||
} else {
|
||||
/* Re-use segment for "" path segment to represent trailing slash, update tail */
|
||||
/* Reuse segment for "" path segment to represent trailing slash, update tail */
|
||||
URI_TYPE(PathSegment) * const segment = walker;
|
||||
if (pathOwned && (segment->text.first != segment->text.afterLast)) {
|
||||
memory->free(memory, (URI_CHAR *)segment->text.first);
|
||||
@@ -403,7 +414,7 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,
|
||||
* NEW: tail -> NULL */
|
||||
uri->pathTail = NULL;
|
||||
} else {
|
||||
/* Re-use segment for "" path segment to represent trailing slash,
|
||||
/* Reuse segment for "" path segment to represent trailing slash,
|
||||
* then update head and tail */
|
||||
if (pathOwned && (walker->text.first != walker->text.afterLast)) {
|
||||
memory->free(memory, (URI_CHAR *)walker->text.first);
|
||||
@@ -696,7 +707,7 @@ static UriBool URI_FUNC(PrependNewDotSegment)(URI_TYPE(Uri) * uri, UriMemoryMana
|
||||
/* When dropping a scheme from a URI without a host and with a colon (":")
|
||||
* in the first path segment, a consecutive reparse would rightfully
|
||||
* mis-classify the first path segment as a scheme due to the colon.
|
||||
* To protect against this case, we prepend an artifical "." segment
|
||||
* To protect against this case, we prepend an artificial "." segment
|
||||
* to the path in here; the function is called after the scheme has
|
||||
* just been dropped.
|
||||
*
|
||||
@@ -751,7 +762,7 @@ UriBool URI_FUNC(FixPathNoScheme)(URI_TYPE(Uri) * uri,
|
||||
/* When dropping a host from a URI without a scheme, an absolute path
|
||||
* and and empty first path segment, a consecutive reparse would rightfully
|
||||
* mis-classify the first path segment as a host marker due to the "//".
|
||||
* To protect against this case, we prepend an artifical "." segment
|
||||
* To protect against this case, we prepend an artificial "." segment
|
||||
* to the path in here; the function is called after the host has
|
||||
* just been dropped.
|
||||
*
|
||||
|
||||
@@ -64,6 +64,15 @@
|
||||
|
||||
|
||||
|
||||
#define URI_MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
/* NOTE: This intends to mimic MALLOC_ALIGNMENT of glibc */
|
||||
#define URI_MALLOC_ALIGNMENT URI_MAX(2 * sizeof(size_t), sizeof(long double))
|
||||
|
||||
#define URI_MALLOC_PADDING (URI_MALLOC_ALIGNMENT - sizeof(size_t))
|
||||
|
||||
|
||||
|
||||
#define URI_CHECK_ALLOC_OVERFLOW(total_size, nmemb, size) \
|
||||
do { \
|
||||
/* check for unsigned overflow */ \
|
||||
@@ -170,7 +179,7 @@ void * uriEmulateReallocarray(UriMemoryManager * memory,
|
||||
static void * uriDecorateMalloc(UriMemoryManager * memory,
|
||||
size_t size) {
|
||||
UriMemoryManager * backend;
|
||||
const size_t extraBytes = sizeof(size_t);
|
||||
const size_t extraBytes = sizeof(size_t) + URI_MALLOC_PADDING;
|
||||
void * buffer;
|
||||
|
||||
if (memory == NULL) {
|
||||
@@ -225,7 +234,7 @@ static void * uriDecorateRealloc(UriMemoryManager * memory,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prevSize = *((size_t *)((char *)ptr - sizeof(size_t)));
|
||||
prevSize = *((size_t *)((char *)ptr - sizeof(size_t) - URI_MALLOC_PADDING));
|
||||
|
||||
/* Anything to do? */
|
||||
if (size <= prevSize) {
|
||||
@@ -259,7 +268,7 @@ static void uriDecorateFree(UriMemoryManager * memory, void * ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
backend->free(backend, (char *)ptr - sizeof(size_t));
|
||||
backend->free(backend, (char *)ptr - sizeof(size_t) - URI_MALLOC_PADDING);
|
||||
}
|
||||
|
||||
|
||||
@@ -288,7 +297,7 @@ int uriCompleteMemoryManager(UriMemoryManager * memory,
|
||||
|
||||
|
||||
|
||||
int uriTestMemoryManager(UriMemoryManager * memory) {
|
||||
int uriTestMemoryManagerEx(UriMemoryManager * memory, UriBool challengeAlignment) {
|
||||
const size_t mallocSize = 7;
|
||||
const size_t callocNmemb = 3;
|
||||
const size_t callocSize = 5;
|
||||
@@ -456,11 +465,41 @@ int uriTestMemoryManager(UriMemoryManager * memory) {
|
||||
buffer = NULL;
|
||||
}
|
||||
|
||||
/* challenge pointer alignment */
|
||||
if (challengeAlignment == URI_TRUE) {
|
||||
long double * ptr = memory->malloc(memory, 4 * sizeof(long double));
|
||||
if (ptr != NULL) {
|
||||
ptr[0] = 0.0L;
|
||||
ptr[1] = 1.1L;
|
||||
ptr[2] = 2.2L;
|
||||
ptr[3] = 3.3L;
|
||||
|
||||
{
|
||||
long double * const ptrNew = memory->realloc(memory, ptr, 8 * sizeof(long double));
|
||||
if (ptrNew != NULL) {
|
||||
ptr = ptrNew;
|
||||
ptr[4] = 4.4L;
|
||||
ptr[5] = 5.5L;
|
||||
ptr[6] = 6.6L;
|
||||
ptr[7] = 7.7L;
|
||||
}
|
||||
}
|
||||
|
||||
memory->free(memory, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
return URI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int uriTestMemoryManager(UriMemoryManager * memory) {
|
||||
return uriTestMemoryManagerEx(memory, /*challengeAlignment=*/ URI_FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*extern*/ UriMemoryManager defaultMemoryManager = {
|
||||
uriDefaultMalloc,
|
||||
uriDefaultCalloc,
|
||||
|
||||
Reference in New Issue
Block a user