1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

uri: Update to uriparser-0.9.9-59-gc3b4956 (#20437)

This is specifically to backport uriparser/uriparser#276.

Fixes php/php-src#20431.
This commit is contained in:
Tim Düsterhus
2025-11-11 16:23:27 +01:00
committed by GitHub
parent 131eb9e723
commit 8a0c300d02
47 changed files with 8602 additions and 9164 deletions

View File

@@ -18,6 +18,6 @@ var_dump($uri2->toString());
--EXPECT--
string(11) "example.com"
NULL
string(7) "https:/"
string(6) "https:"
NULL
string(7) "https:/"
string(6) "https:"

File diff suppressed because it is too large Load Diff

View File

@@ -43,152 +43,136 @@
*/
#ifndef URI_BASE_H
#define URI_BASE_H 1
# define URI_BASE_H 1
/* Version helper macro */
#define URI_ANSI_TO_UNICODE_HELPER(x) L ## x
#define URI_ANSI_TO_UNICODE(x) URI_ANSI_TO_UNICODE_HELPER(x)
# define URI_ANSI_TO_UNICODE_HELPER(x) L##x
# define URI_ANSI_TO_UNICODE(x) URI_ANSI_TO_UNICODE_HELPER(x)
/* Version */
#define URI_VER_MAJOR 0
#define URI_VER_MINOR 9
#define URI_VER_RELEASE 9
#define URI_VER_SUFFIX_ANSI ""
#define URI_VER_SUFFIX_UNICODE URI_ANSI_TO_UNICODE(URI_VER_SUFFIX_ANSI)
# define URI_VER_MAJOR 0
# define URI_VER_MINOR 9
# define URI_VER_RELEASE 9
# define URI_VER_SUFFIX_ANSI ""
# define URI_VER_SUFFIX_UNICODE URI_ANSI_TO_UNICODE(URI_VER_SUFFIX_ANSI)
/* More version helper macros */
#define URI_INT_TO_ANSI_HELPER(x) #x
#define URI_INT_TO_ANSI(x) URI_INT_TO_ANSI_HELPER(x)
# define URI_INT_TO_ANSI_HELPER(x) #x
# define URI_INT_TO_ANSI(x) URI_INT_TO_ANSI_HELPER(x)
#define URI_INT_TO_UNICODE_HELPER(x) URI_ANSI_TO_UNICODE(#x)
#define URI_INT_TO_UNICODE(x) URI_INT_TO_UNICODE_HELPER(x)
#define URI_VER_ANSI_HELPER(ma, mi, r, s) \
URI_INT_TO_ANSI(ma) "." \
URI_INT_TO_ANSI(mi) "." \
URI_INT_TO_ANSI(r) \
s
#define URI_VER_UNICODE_HELPER(ma, mi, r, s) \
URI_INT_TO_UNICODE(ma) L"." \
URI_INT_TO_UNICODE(mi) L"." \
URI_INT_TO_UNICODE(r) \
s
# define URI_INT_TO_UNICODE_HELPER(x) URI_ANSI_TO_UNICODE(#x)
# define URI_INT_TO_UNICODE(x) URI_INT_TO_UNICODE_HELPER(x)
# define URI_VER_ANSI_HELPER(ma, mi, r, s) \
URI_INT_TO_ANSI(ma) "." URI_INT_TO_ANSI(mi) "." URI_INT_TO_ANSI(r) s
# define URI_VER_UNICODE_HELPER(ma, mi, r, s) \
URI_INT_TO_UNICODE(ma) L"." URI_INT_TO_UNICODE(mi) L"." URI_INT_TO_UNICODE(r) s
/* Full version strings */
#define URI_VER_ANSI URI_VER_ANSI_HELPER(URI_VER_MAJOR, URI_VER_MINOR, URI_VER_RELEASE, URI_VER_SUFFIX_ANSI)
#define URI_VER_UNICODE URI_VER_UNICODE_HELPER(URI_VER_MAJOR, URI_VER_MINOR, URI_VER_RELEASE, URI_VER_SUFFIX_UNICODE)
# define URI_VER_ANSI \
URI_VER_ANSI_HELPER(URI_VER_MAJOR, URI_VER_MINOR, URI_VER_RELEASE, \
URI_VER_SUFFIX_ANSI)
# define URI_VER_UNICODE \
URI_VER_UNICODE_HELPER(URI_VER_MAJOR, URI_VER_MINOR, URI_VER_RELEASE, \
URI_VER_SUFFIX_UNICODE)
/* Unused parameter macro */
#ifdef __GNUC__
# define URI_UNUSED(x) unused_##x __attribute__((unused))
#else
# define URI_UNUSED(x) x
#endif
# ifdef __GNUC__
# define URI_UNUSED(x) unused_##x __attribute__((unused))
# else
# define URI_UNUSED(x) x
# endif
/* Import/export decorator */
#if defined(_MSC_VER)
# if defined(URI_STATIC_BUILD)
# define URI_PUBLIC
# elif defined(URI_LIBRARY_BUILD)
# define URI_PUBLIC __declspec(dllexport)
# else
# define URI_PUBLIC __declspec(dllimport)
# endif
#else
# if ! defined(URI_LIBRARY_BUILD) || ! defined(URI_VISIBILITY)
# define URI_PUBLIC
# else
# define URI_PUBLIC __attribute__ ((visibility("default")))
# endif
#endif
# if defined(_MSC_VER)
# if defined(URI_STATIC_BUILD)
# define URI_PUBLIC
# elif defined(URI_LIBRARY_BUILD)
# define URI_PUBLIC __declspec(dllexport)
# else
# define URI_PUBLIC __declspec(dllimport)
# endif
# else
# if !defined(URI_LIBRARY_BUILD) || !defined(URI_VISIBILITY)
# define URI_PUBLIC
# else
# define URI_PUBLIC __attribute__((visibility("default")))
# endif
# endif
typedef int UriBool; /**< Boolean type */
#define URI_TRUE 1
#define URI_FALSE 0
# define URI_TRUE 1
# define URI_FALSE 0
/* Shared errors */
#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 */
#define URI_ERROR_NOT_IMPLEMENTED 8 /* The called function is not implemented yet */
#define URI_ERROR_RANGE_INVALID 9 /* The parameters passed contained invalid ranges */
#define URI_ERROR_MEMORY_MANAGER_INCOMPLETE 10 /* [>=0.9.0] The UriMemoryManager passed does not implement all needed functions */
# 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 */
# define URI_ERROR_NOT_IMPLEMENTED 8 /* The called function is not implemented yet */
# define URI_ERROR_RANGE_INVALID 9 /* The parameters passed contained invalid ranges */
# define URI_ERROR_MEMORY_MANAGER_INCOMPLETE \
10 /* [>=0.9.0] The UriMemoryManager passed does not implement all needed \
functions */
/* Errors specific to ToString */
#define URI_ERROR_TOSTRING_TOO_LONG URI_ERROR_OUTPUT_TOO_LARGE /* Deprecated, test for URI_ERROR_OUTPUT_TOO_LARGE instead */
# define URI_ERROR_TOSTRING_TOO_LONG \
URI_ERROR_OUTPUT_TOO_LARGE /* Deprecated, test for URI_ERROR_OUTPUT_TOO_LARGE \
instead */
/* Errors specific to AddBaseUri */
#define URI_ERROR_ADDBASE_REL_BASE 5 /* Given base is not absolute */
# define URI_ERROR_ADDBASE_REL_BASE 5 /* Given base is not absolute */
/* Errors specific to RemoveBaseUri */
#define URI_ERROR_REMOVEBASE_REL_BASE 6 /* Given base is not absolute */
#define URI_ERROR_REMOVEBASE_REL_SOURCE 7 /* Given base is not absolute */
# define URI_ERROR_REMOVEBASE_REL_BASE 6 /* Given base is not absolute */
# define URI_ERROR_REMOVEBASE_REL_SOURCE 7 /* Given base is not absolute */
/* Error specific to uriTestMemoryManager */
#define URI_ERROR_MEMORY_MANAGER_FAULTY 11 /* [>=0.9.0] The UriMemoryManager given did not pass the test suite */
# define URI_ERROR_MEMORY_MANAGER_FAULTY \
11 /* [>=0.9.0] The UriMemoryManager given did not pass the test suite */
/* Error specific to uriSetUserInfo */
#define URI_ERROR_SETUSERINFO_HOST_NOT_SET 12 /* [>=0.9.9] The %URI given does not have the host set */
# define URI_ERROR_SETUSERINFO_HOST_NOT_SET \
12 /* [>=0.9.9] The %URI given does not have the host set */
/* Error specific to uriSetPort */
#define URI_ERROR_SETPORT_HOST_NOT_SET 13 /* [>=0.9.9] The %URI given does not have the host set */
# define URI_ERROR_SETPORT_HOST_NOT_SET \
13 /* [>=0.9.9] The %URI given does not have the host set */
/* Error specific to uriSetHost* */
#define URI_ERROR_SETHOST_USERINFO_SET 14 /* [>=0.9.9] The %URI given does have user info set */
#define URI_ERROR_SETHOST_PORT_SET 15 /* [>=0.9.9] The %URI given does have a port set */
#ifndef URI_DOXYGEN
# include <stdio.h> /* For NULL, snprintf */
# include <ctype.h> /* For wchar_t */
# include <string.h> /* For strlen, memset, memcpy */
# include <stdlib.h> /* For malloc */
#endif /* URI_DOXYGEN */
# define URI_ERROR_SETHOST_USERINFO_SET \
14 /* [>=0.9.9] The %URI given does have user info set */
# define URI_ERROR_SETHOST_PORT_SET \
15 /* [>=0.9.9] The %URI given does have a port set */
# ifndef URI_DOXYGEN
# include <stdio.h> /* For NULL, snprintf */
# include <ctype.h> /* For wchar_t */
# include <string.h> /* For strlen, memset, memcpy */
# include <stdlib.h> /* For malloc */
# endif /* URI_DOXYGEN */
/**
* Holds an IPv4 address.
*/
typedef struct UriIp4Struct {
unsigned char data[4]; /**< Each octet in one byte */
unsigned char data[4]; /**< Each octet in one byte */
} UriIp4; /**< @copydoc UriIp4Struct */
/**
* Holds an IPv6 address.
*/
typedef struct UriIp6Struct {
unsigned char data[16]; /**< Each quad in two bytes */
unsigned char data[16]; /**< Each quad in two bytes */
} UriIp6; /**< @copydoc UriIp6Struct */
struct UriMemoryManagerStruct; /* forward declaration to break loop */
struct UriMemoryManagerStruct; /* forward declaration to break loop */
/**
* Function signature that custom malloc(3) functions must conform to
@@ -216,7 +200,8 @@ typedef void * (*UriFuncRealloc)(struct UriMemoryManagerStruct *, void *, size_t
*
* @since 0.9.0
*/
typedef void * (*UriFuncReallocarray)(struct UriMemoryManagerStruct *, void *, size_t, size_t);
typedef void * (*UriFuncReallocarray)(struct UriMemoryManagerStruct *, void *, size_t,
size_t);
/**
* Function signature that custom free(3) functions must conform to
@@ -225,7 +210,6 @@ typedef void * (*UriFuncReallocarray)(struct UriMemoryManagerStruct *, void *, s
*/
typedef void (*UriFuncFree)(struct UriMemoryManagerStruct *, void *);
/**
* Class-like interface of custom memory managers
*
@@ -236,56 +220,58 @@ typedef void (*UriFuncFree)(struct UriMemoryManagerStruct *, void *);
* @since 0.9.0
*/
typedef struct UriMemoryManagerStruct {
UriFuncMalloc malloc; /**< Pointer to custom malloc(3) */
UriFuncCalloc calloc; /**< Pointer to custom calloc(3); to emulate using malloc and memset see uriEmulateCalloc */
UriFuncRealloc realloc; /**< Pointer to custom realloc(3) */
UriFuncReallocarray reallocarray; /**< Pointer to custom reallocarray(3); to emulate using realloc see uriEmulateReallocarray */
UriFuncFree free; /**< Pointer to custom free(3) */
void * userData; /**< Pointer to data that the other function members need access to */
UriFuncMalloc malloc; /**< Pointer to custom malloc(3) */
UriFuncCalloc calloc; /**< Pointer to custom calloc(3); to emulate using malloc and
memset see uriEmulateCalloc */
UriFuncRealloc realloc; /**< Pointer to custom realloc(3) */
UriFuncReallocarray reallocarray; /**< Pointer to custom reallocarray(3); to emulate
using realloc see uriEmulateReallocarray */
UriFuncFree free; /**< Pointer to custom free(3) */
void *
userData; /**< Pointer to data that the other function members need access to */
} UriMemoryManager; /**< @copydoc UriMemoryManagerStruct */
/**
* Specifies a line break conversion mode.
*/
typedef enum UriBreakConversionEnum {
URI_BR_TO_LF, /**< Convert to Unix line breaks ("\\x0a") */
URI_BR_TO_CRLF, /**< Convert to Windows line breaks ("\\x0d\\x0a") */
URI_BR_TO_CR, /**< Convert to Macintosh line breaks ("\\x0d") */
URI_BR_TO_UNIX = URI_BR_TO_LF, /**< @copydoc UriBreakConversionEnum::URI_BR_TO_LF */
URI_BR_TO_WINDOWS = URI_BR_TO_CRLF, /**< @copydoc UriBreakConversionEnum::URI_BR_TO_CRLF */
URI_BR_TO_MAC = URI_BR_TO_CR, /**< @copydoc UriBreakConversionEnum::URI_BR_TO_CR */
URI_BR_DONT_TOUCH /**< Copy line breaks unmodified */
URI_BR_TO_LF, /**< Convert to Unix line breaks ("\\x0a") */
URI_BR_TO_CRLF, /**< Convert to Windows line breaks ("\\x0d\\x0a") */
URI_BR_TO_CR, /**< Convert to Macintosh line breaks ("\\x0d") */
URI_BR_TO_UNIX = URI_BR_TO_LF, /**< @copydoc UriBreakConversionEnum::URI_BR_TO_LF */
URI_BR_TO_WINDOWS =
URI_BR_TO_CRLF, /**< @copydoc UriBreakConversionEnum::URI_BR_TO_CRLF */
URI_BR_TO_MAC = URI_BR_TO_CR, /**< @copydoc UriBreakConversionEnum::URI_BR_TO_CR */
URI_BR_DONT_TOUCH /**< Copy line breaks unmodified */
} UriBreakConversion; /**< @copydoc UriBreakConversionEnum */
/**
* Specifies which component of a %URI has to be normalized.
*/
typedef enum UriNormalizationMaskEnum {
URI_NORMALIZED = 0, /**< Do not normalize anything */
URI_NORMALIZE_SCHEME = 1 << 0, /**< Normalize scheme (fix uppercase letters) */
URI_NORMALIZE_USER_INFO = 1 << 1, /**< Normalize user info (fix uppercase percent-encodings) */
URI_NORMALIZE_HOST = 1 << 2, /**< Normalize host (fix uppercase letters) */
URI_NORMALIZE_PATH = 1 << 3, /**< Normalize path (fix uppercase percent-encodings and redundant dot segments) */
URI_NORMALIZE_QUERY = 1 << 4, /**< Normalize query (fix uppercase percent-encodings) */
URI_NORMALIZE_FRAGMENT = 1 << 5, /**< Normalize fragment (fix uppercase percent-encodings) */
URI_NORMALIZE_PORT = 1 << 6 /**< Normalize port (drop leading zeros) @since 0.9.9 */
URI_NORMALIZED = 0, /**< Do not normalize anything */
URI_NORMALIZE_SCHEME = 1 << 0, /**< Normalize scheme (fix uppercase letters) */
URI_NORMALIZE_USER_INFO =
1 << 1, /**< Normalize user info (fix uppercase percent-encodings) */
URI_NORMALIZE_HOST = 1 << 2, /**< Normalize host (fix uppercase letters) */
URI_NORMALIZE_PATH = 1 << 3, /**< Normalize path (fix uppercase percent-encodings and
redundant dot segments) */
URI_NORMALIZE_QUERY =
1 << 4, /**< Normalize query (fix uppercase percent-encodings) */
URI_NORMALIZE_FRAGMENT =
1 << 5, /**< Normalize fragment (fix uppercase percent-encodings) */
URI_NORMALIZE_PORT = 1 << 6 /**< Normalize port (drop leading zeros) @since 0.9.9 */
} UriNormalizationMask; /**< @copydoc UriNormalizationMaskEnum */
/**
* Specifies how to resolve %URI references.
*/
typedef enum UriResolutionOptionsEnum {
URI_RESOLVE_STRICTLY = 0, /**< Full RFC conformance */
URI_RESOLVE_IDENTICAL_SCHEME_COMPAT = 1 << 0 /**< Treat %URI to resolve with identical scheme as having no scheme */
URI_RESOLVE_STRICTLY = 0, /**< Full RFC conformance */
URI_RESOLVE_IDENTICAL_SCHEME_COMPAT =
1 << 0 /**< Treat %URI to resolve with identical scheme as having no scheme */
} UriResolutionOptions; /**< @copydoc UriResolutionOptionsEnum */
/**
* 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.
@@ -322,9 +308,7 @@ typedef enum UriResolutionOptionsEnum {
* @since 0.9.0
*/
URI_PUBLIC int uriCompleteMemoryManager(UriMemoryManager * memory,
UriMemoryManager * backend);
UriMemoryManager * backend);
/**
* Offers emulation of calloc(3) based on memory-&gt;malloc and memset.
@@ -340,10 +324,7 @@ URI_PUBLIC int uriCompleteMemoryManager(UriMemoryManager * memory,
* @see UriMemoryManager
* @since 0.9.0
*/
URI_PUBLIC void * uriEmulateCalloc(UriMemoryManager * memory,
size_t nmemb, size_t size);
URI_PUBLIC void * uriEmulateCalloc(UriMemoryManager * memory, size_t nmemb, size_t size);
/**
* Offers emulation of reallocarray(3) based on memory-&gt;realloc.
@@ -360,10 +341,8 @@ URI_PUBLIC void * uriEmulateCalloc(UriMemoryManager * memory,
* @see UriMemoryManager
* @since 0.9.0
*/
URI_PUBLIC void * uriEmulateReallocarray(UriMemoryManager * memory,
void * ptr, size_t nmemb, size_t size);
URI_PUBLIC void * uriEmulateReallocarray(UriMemoryManager * memory, void * ptr,
size_t nmemb, size_t size);
/**
* Run multiple tests against a given memory manager.
@@ -392,8 +371,6 @@ URI_PUBLIC void * uriEmulateReallocarray(UriMemoryManager * memory,
*/
URI_PUBLIC int uriTestMemoryManager(UriMemoryManager * memory);
/**
* Run multiple tests against a given memory manager.
* For example, one test
@@ -419,8 +396,7 @@ URI_PUBLIC int uriTestMemoryManager(UriMemoryManager * memory);
* @see uriTestMemoryManager
* @since 0.9.10
*/
URI_PUBLIC int uriTestMemoryManagerEx(UriMemoryManager * memory, UriBool challengeAlignment);
URI_PUBLIC int uriTestMemoryManagerEx(UriMemoryManager * memory,
UriBool challengeAlignment);
#endif /* URI_BASE_H */

View File

@@ -46,24 +46,18 @@
/* Allow multi inclusion */
#include "UriDefsConfig.h"
#undef URI_CHAR
#define URI_CHAR char
#undef _UT
#define _UT(x) x
#undef URI_FUNC
#define URI_FUNC(x) uri##x##A
#undef URI_TYPE
#define URI_TYPE(x) Uri##x##A
#undef URI_STRLEN
#define URI_STRLEN strlen
#undef URI_STRCPY
@@ -76,7 +70,7 @@
/* TODO Remove on next source-compatibility break */
#undef URI_SNPRINTF
#if (defined(__WIN32__) || defined(_WIN32) || defined(WIN32))
# define URI_SNPRINTF _snprintf
# define URI_SNPRINTF _snprintf
#else
# define URI_SNPRINTF snprintf
# define URI_SNPRINTF snprintf
#endif

View File

@@ -43,59 +43,51 @@
*/
#ifndef URI_DEFS_CONFIG_H
#define URI_DEFS_CONFIG_H 1
# define URI_DEFS_CONFIG_H 1
/* Deny external overriding */
#undef URI_ENABLE_ANSI /* Internal for !URI_NO_ANSI */
#undef URI_ENABLE_UNICODE /* Internal for !URI_NO_UNICODE */
# undef URI_ENABLE_ANSI /* Internal for !URI_NO_ANSI */
# undef URI_ENABLE_UNICODE /* Internal for !URI_NO_UNICODE */
/* Encoding */
#ifdef URI_NO_ANSI
# ifdef URI_NO_UNICODE
# ifdef URI_NO_ANSI
# ifdef URI_NO_UNICODE
/* No encoding at all */
# error URI_NO_ANSI and URI_NO_UNICODE cannot go together.
# else
# error URI_NO_ANSI and URI_NO_UNICODE cannot go together.
# else
/* Wide strings only */
# define URI_ENABLE_UNICODE 1
# endif
#else
# ifdef URI_NO_UNICODE
# define URI_ENABLE_UNICODE 1
# endif
# else
# ifdef URI_NO_UNICODE
/* Narrow strings only */
# define URI_ENABLE_ANSI 1
# else
# define URI_ENABLE_ANSI 1
# else
/* Both narrow and wide strings */
# define URI_ENABLE_ANSI 1
# define URI_ENABLE_UNICODE 1
# endif
#endif
# define URI_ENABLE_ANSI 1
# define URI_ENABLE_UNICODE 1
# endif
# endif
/* Function inlining, not ANSI/ISO C! */
#if defined(URI_DOXYGEN)
# define URI_INLINE
#elif defined(__INTEL_COMPILER)
# if defined(URI_DOXYGEN)
# define URI_INLINE
# elif defined(__INTEL_COMPILER)
/* Intel C/C++ */
/* http://predef.sourceforge.net/precomp.html#sec20 */
/* http://www.intel.com/support/performancetools/c/windows/sb/CS-007751.htm#2 */
# define URI_INLINE __forceinline
#elif defined(_MSC_VER)
# define URI_INLINE __forceinline
# elif defined(_MSC_VER)
/* Microsoft Visual C++ */
/* http://predef.sourceforge.net/precomp.html#sec32 */
/* http://msdn2.microsoft.com/en-us/library/ms882281.aspx */
# define URI_INLINE __forceinline
#elif (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))
# define URI_INLINE __forceinline
# elif (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))
/* C99, "inline" is a keyword */
# define URI_INLINE inline
#else
# define URI_INLINE inline
# else
/* No inlining */
# define URI_INLINE
#endif
# define URI_INLINE
# endif
#endif /* URI_DEFS_CONFIG_H */

View File

@@ -46,24 +46,18 @@
/* Allow multi inclusion */
#include "UriDefsConfig.h"
#undef URI_CHAR
#define URI_CHAR wchar_t
#undef _UT
#define _UT(x) L##x
#undef URI_FUNC
#define URI_FUNC(x) uri##x##W
#undef URI_TYPE
#define URI_TYPE(x) Uri##x##W
#undef URI_STRLEN
#define URI_STRLEN wcslen
#undef URI_STRCPY
@@ -76,7 +70,7 @@
/* TODO Remove on next source-compatibility break */
#undef URI_SNPRINTF
#if (defined(__WIN32__) || defined(_WIN32) || defined(WIN32))
# define URI_SNPRINTF _snwprintf
# define URI_SNPRINTF _snwprintf
#else
# define URI_SNPRINTF swprintf
# define URI_SNPRINTF swprintf
#endif

View File

@@ -44,48 +44,43 @@
*/
#if (defined(URI_PASS_ANSI) && !defined(URI_IP4_TWICE_H_ANSI)) \
|| (defined(URI_PASS_UNICODE) && !defined(URI_IP4_TWICE_H_UNICODE)) \
|| (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
|| (defined(URI_PASS_UNICODE) && !defined(URI_IP4_TWICE_H_UNICODE)) \
|| (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
/* What encodings are enabled? */
#include "UriDefsConfig.h"
#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
# include "UriDefsConfig.h"
# if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
/* Include SELF twice */
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriIp4.h"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriIp4.h"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriIp4.h"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriIp4.h"
# undef URI_PASS_UNICODE
# endif
/* Only one pass for each encoding */
#elif (defined(URI_PASS_ANSI) && !defined(URI_IP4_TWICE_H_ANSI) \
&& defined(URI_ENABLE_ANSI)) || (defined(URI_PASS_UNICODE) \
&& !defined(URI_IP4_TWICE_H_UNICODE) && defined(URI_ENABLE_UNICODE))
# ifdef URI_PASS_ANSI
# define URI_IP4_TWICE_H_ANSI 1
# include "UriDefsAnsi.h"
# else
# define URI_IP4_TWICE_H_UNICODE 1
# include "UriDefsUnicode.h"
# include <wchar.h>
# endif
# elif (defined(URI_PASS_ANSI) && !defined(URI_IP4_TWICE_H_ANSI) \
&& defined(URI_ENABLE_ANSI)) \
|| (defined(URI_PASS_UNICODE) && !defined(URI_IP4_TWICE_H_UNICODE) \
&& defined(URI_ENABLE_UNICODE))
# ifdef URI_PASS_ANSI
# define URI_IP4_TWICE_H_ANSI 1
# include "UriDefsAnsi.h"
# else
# define URI_IP4_TWICE_H_UNICODE 1
# include "UriDefsUnicode.h"
# include <wchar.h>
# endif
#ifdef __cplusplus
# ifdef __cplusplus
extern "C" {
#endif
#ifndef URI_DOXYGEN
# include "UriBase.h"
#endif
# endif
# ifndef URI_DOXYGEN
# include "UriBase.h"
# endif
/**
* Converts an IPv4 text representation into four bytes.
@@ -99,15 +94,12 @@ extern "C" {
* @see uriParseIpSixAddressMmA
*/
URI_PUBLIC int URI_FUNC(ParseIpFourAddress)(unsigned char * octetOutput,
const URI_CHAR * first, const URI_CHAR * afterLast);
const URI_CHAR * first,
const URI_CHAR * afterLast);
#ifdef __cplusplus
# ifdef __cplusplus
}
#endif
# endif
#endif
# endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -38,35 +38,34 @@
*/
#if (defined(URI_PASS_ANSI) && !defined(URI_COMMON_H_ANSI)) \
|| (defined(URI_PASS_UNICODE) && !defined(URI_COMMON_H_UNICODE)) \
|| (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
|| (defined(URI_PASS_UNICODE) && !defined(URI_COMMON_H_UNICODE)) \
|| (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
/* What encodings are enabled? */
#include <uriparser/UriDefsConfig.h>
#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
# 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 "UriCommon.h"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriCommon.h"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriCommon.h"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriCommon.h"
# undef URI_PASS_UNICODE
# endif
/* Only one pass for each encoding */
#elif (defined(URI_PASS_ANSI) && !defined(URI_COMMON_H_ANSI) \
&& defined(URI_ENABLE_ANSI)) || (defined(URI_PASS_UNICODE) \
&& !defined(URI_COMMON_H_UNICODE) && defined(URI_ENABLE_UNICODE))
# ifdef URI_PASS_ANSI
# define URI_COMMON_H_ANSI 1
# include <uriparser/UriDefsAnsi.h>
# else
# define URI_COMMON_H_UNICODE 1
# include <uriparser/UriDefsUnicode.h>
# endif
# elif (defined(URI_PASS_ANSI) && !defined(URI_COMMON_H_ANSI) \
&& defined(URI_ENABLE_ANSI)) \
|| (defined(URI_PASS_UNICODE) && !defined(URI_COMMON_H_UNICODE) \
&& defined(URI_ENABLE_UNICODE))
# ifdef URI_PASS_ANSI
# define URI_COMMON_H_ANSI 1
# include <uriparser/UriDefsAnsi.h>
# else
# define URI_COMMON_H_UNICODE 1
# include <uriparser/UriDefsUnicode.h>
# endif
/* Used to point to from empty path segments.
* X.first and X.afterLast must be the same non-NULL value then. */
@@ -74,40 +73,37 @@ extern const URI_CHAR * const URI_FUNC(SafeToPointTo);
extern const URI_CHAR * const URI_FUNC(ConstPwd);
extern const URI_CHAR * const URI_FUNC(ConstParent);
void URI_FUNC(ResetUri)(URI_TYPE(Uri) * uri);
int URI_FUNC(FreeUriPath)(URI_TYPE(Uri) * uri, UriMemoryManager * memory);
int URI_FUNC(CompareRange)(
const URI_TYPE(TextRange) * a,
const URI_TYPE(TextRange) * b);
int URI_FUNC(CompareRange)(const URI_TYPE(TextRange) * a, const URI_TYPE(TextRange) * b);
UriBool URI_FUNC(CopyRange)(URI_TYPE(TextRange) * destRange,
const URI_TYPE(TextRange) * sourceRange, UriMemoryManager * memory);
const URI_TYPE(TextRange) * sourceRange,
UriMemoryManager * memory);
UriBool URI_FUNC(CopyRangeAsNeeded)(URI_TYPE(TextRange) * destRange,
const URI_TYPE(TextRange) * sourceRange, UriMemoryManager * memory);
const URI_TYPE(TextRange) * sourceRange,
UriMemoryManager * memory);
UriBool URI_FUNC(RemoveDotSegmentsAbsolute)(URI_TYPE(Uri) * uri,
UriMemoryManager * memory);
UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,
UriBool relative, UriBool pathOwned, UriMemoryManager * memory);
UriMemoryManager * memory);
UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri, UriBool relative,
UriBool pathOwned, UriMemoryManager * memory);
unsigned char URI_FUNC(HexdigToInt)(URI_CHAR hexdig);
URI_CHAR URI_FUNC(HexToLetterEx)(unsigned int value, UriBool uppercase);
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);
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, UriMemoryManager * memory);
UriBool URI_FUNC(FixPathNoScheme)(URI_TYPE(Uri) * uri, UriMemoryManager * memory);
UriBool URI_FUNC(EnsureThatPathIsNotMistakenForHost)(URI_TYPE(Uri) * uri, UriMemoryManager * memory);
void URI_FUNC(FixEmptyTrailSegment)(URI_TYPE(Uri) * uri,
UriMemoryManager * memory);
UriBool URI_FUNC(EnsureThatPathIsNotMistakenForHost)(URI_TYPE(Uri) * uri,
UriMemoryManager * memory);
void URI_FUNC(FixEmptyTrailSegment)(URI_TYPE(Uri) * uri, UriMemoryManager * memory);
#endif
# endif
#endif

View File

@@ -41,128 +41,120 @@
#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 "UriCompare.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriCompare.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriCompare.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriCompare.c"
# undef URI_PASS_UNICODE
# endif
#else
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# include <wchar.h>
# endif
# 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 <uriparser/UriIp4.h>
# include "UriCommon.h"
# endif
UriBool URI_FUNC(EqualsUri)(const URI_TYPE(Uri) * a, const URI_TYPE(Uri) * b) {
/* NOTE: Both NULL means equal! */
if ((a == NULL) || (b == NULL)) {
return ((a == NULL) && (b == NULL)) ? URI_TRUE : URI_FALSE;
}
#ifndef URI_DOXYGEN
# include <uriparser/Uri.h>
# include <uriparser/UriIp4.h>
# include "UriCommon.h"
#endif
/* scheme */
if (URI_FUNC(CompareRange)(&(a->scheme), &(b->scheme))) {
return URI_FALSE;
}
/* absolutePath */
if ((a->scheme.first == NULL) && (a->absolutePath != b->absolutePath)) {
return URI_FALSE;
}
/* userInfo */
if (URI_FUNC(CompareRange)(&(a->userInfo), &(b->userInfo))) {
return URI_FALSE;
}
UriBool URI_FUNC(EqualsUri)(const URI_TYPE(Uri) * a,
const URI_TYPE(Uri) * b) {
/* NOTE: Both NULL means equal! */
if ((a == NULL) || (b == NULL)) {
return ((a == NULL) && (b == NULL)) ? URI_TRUE : URI_FALSE;
}
/* Host */
if (((a->hostData.ip4 == NULL) != (b->hostData.ip4 == NULL))
|| ((a->hostData.ip6 == NULL) != (b->hostData.ip6 == NULL))
|| ((a->hostData.ipFuture.first == NULL)
!= (b->hostData.ipFuture.first == NULL))) {
return URI_FALSE;
}
/* scheme */
if (URI_FUNC(CompareRange)(&(a->scheme), &(b->scheme))) {
return URI_FALSE;
}
if (a->hostData.ip4 != NULL) {
if (memcmp(a->hostData.ip4->data, b->hostData.ip4->data, 4)) {
return URI_FALSE;
}
}
/* absolutePath */
if ((a->scheme.first == NULL)&& (a->absolutePath != b->absolutePath)) {
return URI_FALSE;
}
if (a->hostData.ip6 != NULL) {
if (memcmp(a->hostData.ip6->data, b->hostData.ip6->data, 16)) {
return URI_FALSE;
}
}
/* userInfo */
if (URI_FUNC(CompareRange)(&(a->userInfo), &(b->userInfo))) {
return URI_FALSE;
}
if (a->hostData.ipFuture.first != NULL) {
if (URI_FUNC(CompareRange)(&(a->hostData.ipFuture), &(b->hostData.ipFuture))) {
return URI_FALSE;
}
}
/* Host */
if (((a->hostData.ip4 == NULL) != (b->hostData.ip4 == NULL))
|| ((a->hostData.ip6 == NULL) != (b->hostData.ip6 == NULL))
|| ((a->hostData.ipFuture.first == NULL)
!= (b->hostData.ipFuture.first == NULL))) {
return URI_FALSE;
}
if ((a->hostData.ip4 == NULL) && (a->hostData.ip6 == NULL)
&& (a->hostData.ipFuture.first == NULL)) {
if (URI_FUNC(CompareRange)(&(a->hostText), &(b->hostText))) {
return URI_FALSE;
}
}
if (a->hostData.ip4 != NULL) {
if (memcmp(a->hostData.ip4->data, b->hostData.ip4->data, 4)) {
return URI_FALSE;
}
}
/* portText */
if (URI_FUNC(CompareRange)(&(a->portText), &(b->portText))) {
return URI_FALSE;
}
if (a->hostData.ip6 != NULL) {
if (memcmp(a->hostData.ip6->data, b->hostData.ip6->data, 16)) {
return URI_FALSE;
}
}
/* Path */
if ((a->pathHead == NULL) != (b->pathHead == NULL)) {
return URI_FALSE;
}
if (a->hostData.ipFuture.first != NULL) {
if (URI_FUNC(CompareRange)(&(a->hostData.ipFuture), &(b->hostData.ipFuture))) {
return URI_FALSE;
}
}
if (a->pathHead != NULL) {
URI_TYPE(PathSegment) * walkA = a->pathHead;
URI_TYPE(PathSegment) * walkB = b->pathHead;
do {
if (URI_FUNC(CompareRange)(&(walkA->text), &(walkB->text))) {
return URI_FALSE;
}
if ((walkA->next == NULL) != (walkB->next == NULL)) {
return URI_FALSE;
}
walkA = walkA->next;
walkB = walkB->next;
} while (walkA != NULL);
}
if ((a->hostData.ip4 == NULL)
&& (a->hostData.ip6 == NULL)
&& (a->hostData.ipFuture.first == NULL)) {
if (URI_FUNC(CompareRange)(&(a->hostText), &(b->hostText))) {
return URI_FALSE;
}
}
/* query */
if (URI_FUNC(CompareRange)(&(a->query), &(b->query))) {
return URI_FALSE;
}
/* portText */
if (URI_FUNC(CompareRange)(&(a->portText), &(b->portText))) {
return URI_FALSE;
}
/* fragment */
if (URI_FUNC(CompareRange)(&(a->fragment), &(b->fragment))) {
return URI_FALSE;
}
/* Path */
if ((a->pathHead == NULL) != (b->pathHead == NULL)) {
return URI_FALSE;
}
if (a->pathHead != NULL) {
URI_TYPE(PathSegment) * walkA = a->pathHead;
URI_TYPE(PathSegment) * walkB = b->pathHead;
do {
if (URI_FUNC(CompareRange)(&(walkA->text), &(walkB->text))) {
return URI_FALSE;
}
if ((walkA->next == NULL) != (walkB->next == NULL)) {
return URI_FALSE;
}
walkA = walkA->next;
walkB = walkB->next;
} while (walkA != NULL);
}
/* query */
if (URI_FUNC(CompareRange)(&(a->query), &(b->query))) {
return URI_FALSE;
}
/* fragment */
if (URI_FUNC(CompareRange)(&(a->fragment), &(b->fragment))) {
return URI_FALSE;
}
return URI_TRUE; /* Equal*/
return URI_TRUE; /* Equal*/
}
#endif

View File

@@ -37,17 +37,13 @@
*/
#if !defined(URI_CONFIG_H)
# define URI_CONFIG_H 1
# define URI_CONFIG_H 1
#define PACKAGE_VERSION "@PROJECT_VERSION@"
# define PACKAGE_VERSION "@PROJECT_VERSION@"
/*
#define HAVE_WPRINTF*
#define HAVE_WPRINTF
#define HAVE_REALLOCARRAY
*/
#endif /* !defined(URI_CONFIG_H) */
#endif /* !defined(URI_CONFIG_H) */

View File

@@ -37,15 +37,11 @@
*/
#if !defined(URI_CONFIG_H)
# define URI_CONFIG_H 1
# define URI_CONFIG_H 1
#define PACKAGE_VERSION "@PROJECT_VERSION@"
# define PACKAGE_VERSION "@PROJECT_VERSION@"
#cmakedefine HAVE_WPRINTF
#cmakedefine HAVE_REALLOCARRAY
#endif /* !defined(URI_CONFIG_H) */
#endif /* !defined(URI_CONFIG_H) */

View File

@@ -48,192 +48,195 @@
#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
# 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
# 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);
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 (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;
}
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;
}
int URI_FUNC(CopyUriMm)(URI_TYPE(Uri) * destUri,
const URI_TYPE(Uri) * sourceUri, UriMemoryManager * memory) {
unsigned int revertMask = URI_NORMALIZED;
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
if (sourceUri == NULL || destUri == NULL) {
return URI_ERROR_NULL;
}
URI_FUNC(ResetUri)(destUri);
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
if (URI_FUNC(CopyRangeAsNeeded)(&destUri->scheme, &sourceUri->scheme, memory)
== URI_FALSE) {
return URI_ERROR_MALLOC;
}
URI_FUNC(ResetUri)(destUri);
revertMask |= URI_NORMALIZE_SCHEME;
if (URI_FUNC(CopyRangeAsNeeded)(&destUri->scheme, &sourceUri->scheme, memory) == URI_FALSE) {
return URI_ERROR_MALLOC;
}
if (URI_FUNC(CopyRangeAsNeeded)(&destUri->userInfo, &sourceUri->userInfo, memory)
== URI_FALSE) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
revertMask |= URI_NORMALIZE_SCHEME;
revertMask |= URI_NORMALIZE_USER_INFO;
if (URI_FUNC(CopyRangeAsNeeded)(&destUri->userInfo, &sourceUri->userInfo, memory) == URI_FALSE) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
if (URI_FUNC(CopyRangeAsNeeded)(&destUri->hostText, &sourceUri->hostText, memory)
== URI_FALSE) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
revertMask |= URI_NORMALIZE_USER_INFO;
revertMask |= URI_NORMALIZE_HOST;
if (URI_FUNC(CopyRangeAsNeeded)(&destUri->hostText, &sourceUri->hostText, memory) == URI_FALSE) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
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);
}
revertMask |= URI_NORMALIZE_HOST;
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.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.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 (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 (URI_FUNC(CopyRangeAsNeeded)(&destUri->portText, &sourceUri->portText, memory)
== URI_FALSE) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
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;
}
revertMask |= URI_NORMALIZE_PORT;
if (URI_FUNC(CopyRangeAsNeeded)(&destUri->portText, &sourceUri->portText, memory) == URI_FALSE) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
destUri->pathHead = NULL;
destUri->pathTail = NULL;
revertMask |= URI_NORMALIZE_PORT;
if (sourceUri->pathHead != NULL) {
URI_TYPE(PathSegment) * sourceWalker = sourceUri->pathHead;
URI_TYPE(PathSegment) * destPrev = NULL;
destUri->pathHead = NULL;
destUri->pathTail = 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;
}
if (sourceUri->pathHead != NULL) {
URI_TYPE(PathSegment) * sourceWalker = sourceUri->pathHead;
URI_TYPE(PathSegment) * destPrev = NULL;
destWalker->text.first = NULL;
destWalker->text.afterLast = NULL;
destWalker->next = NULL;
destWalker->reserved = 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;
}
if (destUri->pathHead == NULL) {
destUri->pathHead = destWalker;
revertMask |= URI_NORMALIZE_PATH;
}
destWalker->text.first = NULL;
destWalker->text.afterLast = NULL;
destWalker->next = NULL;
destWalker->reserved = NULL;
if (URI_FUNC(CopyRangeAsNeeded)(&destWalker->text, &sourceWalker->text,
memory)
== URI_FALSE) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
if (destUri->pathHead == NULL) {
destUri->pathHead = destWalker;
revertMask |= URI_NORMALIZE_PATH;
}
if (destPrev != NULL) {
destPrev->next = destWalker;
}
if (URI_FUNC(CopyRangeAsNeeded)(&destWalker->text, &sourceWalker->text, memory) == URI_FALSE) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
destPrev = destWalker;
sourceWalker = sourceWalker->next;
if (destPrev != NULL) {
destPrev->next = destWalker;
}
destUri->pathTail = destWalker;
}
}
destPrev = destWalker;
sourceWalker = sourceWalker->next;
if (URI_FUNC(CopyRangeAsNeeded)(&destUri->query, &sourceUri->query, memory)
== URI_FALSE) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
destUri->pathTail = destWalker;
}
}
revertMask |= URI_NORMALIZE_QUERY;
if (URI_FUNC(CopyRangeAsNeeded)(&destUri->query, &sourceUri->query, memory) == URI_FALSE) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
if (URI_FUNC(CopyRangeAsNeeded)(&destUri->fragment, &sourceUri->fragment, memory)
== URI_FALSE) {
URI_FUNC(PreventLeakageAfterCopy)(destUri, revertMask, memory);
return URI_ERROR_MALLOC;
}
revertMask |= URI_NORMALIZE_QUERY;
destUri->absolutePath = sourceUri->absolutePath;
destUri->owner = URI_TRUE;
destUri->reserved = NULL;
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;
return URI_SUCCESS;
}
int URI_FUNC(CopyUri)(URI_TYPE(Uri) * destUri,
const URI_TYPE(Uri) * sourceUri) {
return URI_FUNC(CopyUriMm)(destUri, sourceUri, NULL);
int URI_FUNC(CopyUri)(URI_TYPE(Uri) * destUri, const URI_TYPE(Uri) * sourceUri) {
return URI_FUNC(CopyUriMm)(destUri, sourceUri, NULL);
}
#endif

View File

@@ -39,40 +39,38 @@
*/
#if (defined(URI_PASS_ANSI) && !defined(URI_COPY_H_ANSI)) \
|| (defined(URI_PASS_UNICODE) && !defined(URI_COPY_H_UNICODE)) \
|| (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
|| (defined(URI_PASS_UNICODE) && !defined(URI_COPY_H_UNICODE)) \
|| (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
/* What encodings are enabled? */
#include <uriparser/UriDefsConfig.h>
#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
# 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.h"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriCopy.h"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriCopy.h"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriCopy.h"
# undef URI_PASS_UNICODE
# endif
/* Only one pass for each encoding */
#elif (defined(URI_PASS_ANSI) && !defined(URI_COPY_H_ANSI) \
&& defined(URI_ENABLE_ANSI)) || (defined(URI_PASS_UNICODE) \
&& !defined(URI_COPY_H_UNICODE) && defined(URI_ENABLE_UNICODE))
# ifdef URI_PASS_ANSI
# define URI_COPY_H_ANSI 1
# include <uriparser/UriDefsAnsi.h>
# else
# define URI_COPY_H_UNICODE 1
# include <uriparser/UriDefsUnicode.h>
# endif
# elif (defined(URI_PASS_ANSI) && !defined(URI_COPY_H_ANSI) \
&& defined(URI_ENABLE_ANSI)) \
|| (defined(URI_PASS_UNICODE) && !defined(URI_COPY_H_UNICODE) \
&& defined(URI_ENABLE_UNICODE))
# ifdef URI_PASS_ANSI
# define URI_COPY_H_ANSI 1
# include <uriparser/UriDefsAnsi.h>
# else
# define URI_COPY_H_UNICODE 1
# include <uriparser/UriDefsUnicode.h>
# endif
int URI_FUNC(CopyUriMm)(URI_TYPE(Uri) * destUri, const URI_TYPE(Uri) * sourceUri,
UriMemoryManager * memory);
int URI_FUNC(CopyUri)(URI_TYPE(Uri) * destUri, const URI_TYPE(Uri) * sourceUri);
int URI_FUNC(CopyUriMm)(URI_TYPE(Uri) * destUri,
const URI_TYPE(Uri) * sourceUri, UriMemoryManager * memory);
int URI_FUNC(CopyUri)(URI_TYPE(Uri) * destUri,
const URI_TYPE(Uri) * sourceUri);
#endif
# endif
#endif

View File

@@ -41,416 +41,399 @@
#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 "UriEscape.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriEscape.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriEscape.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriEscape.c"
# undef URI_PASS_UNICODE
# endif
#else
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# include <wchar.h>
# endif
# 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"
# endif
#ifndef URI_DOXYGEN
# include <uriparser/Uri.h>
# include "UriCommon.h"
#endif
URI_CHAR * URI_FUNC(Escape)(const URI_CHAR * in, URI_CHAR * out,
UriBool spaceToPlus, UriBool normalizeBreaks) {
return URI_FUNC(EscapeEx)(in, NULL, out, spaceToPlus, normalizeBreaks);
URI_CHAR * URI_FUNC(Escape)(const URI_CHAR * in, URI_CHAR * out, UriBool spaceToPlus,
UriBool normalizeBreaks) {
return URI_FUNC(EscapeEx)(in, NULL, out, spaceToPlus, normalizeBreaks);
}
URI_CHAR * URI_FUNC(EscapeEx)(const URI_CHAR * inFirst, const URI_CHAR * inAfterLast,
URI_CHAR * out, UriBool spaceToPlus,
UriBool normalizeBreaks) {
const URI_CHAR * read = inFirst;
URI_CHAR * write = out;
UriBool prevWasCr = URI_FALSE;
if ((out == NULL) || (inFirst == out)) {
return NULL;
} else if (inFirst == NULL) {
if (out != NULL) {
out[0] = _UT('\0');
}
return out;
}
for (;;) {
if ((inAfterLast != NULL) && (read >= inAfterLast)) {
write[0] = _UT('\0');
return write;
}
URI_CHAR * URI_FUNC(EscapeEx)(const URI_CHAR * inFirst,
const URI_CHAR * inAfterLast, URI_CHAR * out,
UriBool spaceToPlus, UriBool normalizeBreaks) {
const URI_CHAR * read = inFirst;
URI_CHAR * write = out;
UriBool prevWasCr = URI_FALSE;
if ((out == NULL) || (inFirst == out)) {
return NULL;
} else if (inFirst == NULL) {
if (out != NULL) {
out[0] = _UT('\0');
}
return out;
}
switch (read[0]) {
case _UT('\0'):
write[0] = _UT('\0');
return write;
for (;;) {
if ((inAfterLast != NULL) && (read >= inAfterLast)) {
write[0] = _UT('\0');
return write;
}
case _UT(' '):
if (spaceToPlus) {
write[0] = _UT('+');
write++;
} else {
write[0] = _UT('%');
write[1] = _UT('2');
write[2] = _UT('0');
write += 3;
}
prevWasCr = URI_FALSE;
break;
switch (read[0]) {
case _UT('\0'):
write[0] = _UT('\0');
return write;
case _UT('a'): /* ALPHA */
case _UT('A'):
case _UT('b'):
case _UT('B'):
case _UT('c'):
case _UT('C'):
case _UT('d'):
case _UT('D'):
case _UT('e'):
case _UT('E'):
case _UT('f'):
case _UT('F'):
case _UT('g'):
case _UT('G'):
case _UT('h'):
case _UT('H'):
case _UT('i'):
case _UT('I'):
case _UT('j'):
case _UT('J'):
case _UT('k'):
case _UT('K'):
case _UT('l'):
case _UT('L'):
case _UT('m'):
case _UT('M'):
case _UT('n'):
case _UT('N'):
case _UT('o'):
case _UT('O'):
case _UT('p'):
case _UT('P'):
case _UT('q'):
case _UT('Q'):
case _UT('r'):
case _UT('R'):
case _UT('s'):
case _UT('S'):
case _UT('t'):
case _UT('T'):
case _UT('u'):
case _UT('U'):
case _UT('v'):
case _UT('V'):
case _UT('w'):
case _UT('W'):
case _UT('x'):
case _UT('X'):
case _UT('y'):
case _UT('Y'):
case _UT('z'):
case _UT('Z'):
case _UT('0'): /* DIGIT */
case _UT('1'):
case _UT('2'):
case _UT('3'):
case _UT('4'):
case _UT('5'):
case _UT('6'):
case _UT('7'):
case _UT('8'):
case _UT('9'):
case _UT('-'): /* "-" / "." / "_" / "~" */
case _UT('.'):
case _UT('_'):
case _UT('~'):
/* Copy unmodified */
write[0] = read[0];
write++;
case _UT(' '):
if (spaceToPlus) {
write[0] = _UT('+');
write++;
} else {
write[0] = _UT('%');
write[1] = _UT('2');
write[2] = _UT('0');
write += 3;
}
prevWasCr = URI_FALSE;
break;
prevWasCr = URI_FALSE;
break;
case _UT('a'): /* ALPHA */
case _UT('A'):
case _UT('b'):
case _UT('B'):
case _UT('c'):
case _UT('C'):
case _UT('d'):
case _UT('D'):
case _UT('e'):
case _UT('E'):
case _UT('f'):
case _UT('F'):
case _UT('g'):
case _UT('G'):
case _UT('h'):
case _UT('H'):
case _UT('i'):
case _UT('I'):
case _UT('j'):
case _UT('J'):
case _UT('k'):
case _UT('K'):
case _UT('l'):
case _UT('L'):
case _UT('m'):
case _UT('M'):
case _UT('n'):
case _UT('N'):
case _UT('o'):
case _UT('O'):
case _UT('p'):
case _UT('P'):
case _UT('q'):
case _UT('Q'):
case _UT('r'):
case _UT('R'):
case _UT('s'):
case _UT('S'):
case _UT('t'):
case _UT('T'):
case _UT('u'):
case _UT('U'):
case _UT('v'):
case _UT('V'):
case _UT('w'):
case _UT('W'):
case _UT('x'):
case _UT('X'):
case _UT('y'):
case _UT('Y'):
case _UT('z'):
case _UT('Z'):
case _UT('0'): /* DIGIT */
case _UT('1'):
case _UT('2'):
case _UT('3'):
case _UT('4'):
case _UT('5'):
case _UT('6'):
case _UT('7'):
case _UT('8'):
case _UT('9'):
case _UT('-'): /* "-" / "." / "_" / "~" */
case _UT('.'):
case _UT('_'):
case _UT('~'):
/* Copy unmodified */
write[0] = read[0];
write++;
case _UT('\x0a'):
if (normalizeBreaks) {
if (!prevWasCr) {
write[0] = _UT('%');
write[1] = _UT('0');
write[2] = _UT('D');
write[3] = _UT('%');
write[4] = _UT('0');
write[5] = _UT('A');
write += 6;
}
} else {
write[0] = _UT('%');
write[1] = _UT('0');
write[2] = _UT('A');
write += 3;
}
prevWasCr = URI_FALSE;
break;
prevWasCr = URI_FALSE;
break;
case _UT('\x0d'):
if (normalizeBreaks) {
write[0] = _UT('%');
write[1] = _UT('0');
write[2] = _UT('D');
write[3] = _UT('%');
write[4] = _UT('0');
write[5] = _UT('A');
write += 6;
} else {
write[0] = _UT('%');
write[1] = _UT('0');
write[2] = _UT('D');
write += 3;
}
prevWasCr = URI_TRUE;
break;
case _UT('\x0a'):
if (normalizeBreaks) {
if (!prevWasCr) {
write[0] = _UT('%');
write[1] = _UT('0');
write[2] = _UT('D');
write[3] = _UT('%');
write[4] = _UT('0');
write[5] = _UT('A');
write += 6;
}
} else {
write[0] = _UT('%');
write[1] = _UT('0');
write[2] = _UT('A');
write += 3;
}
prevWasCr = URI_FALSE;
break;
default:
/* Percent encode */
{
const unsigned char code = (unsigned char)read[0];
/* Uppercase recommended in (last sentence of) section 2.1 *
* of RFC 3986: *
* https://datatracker.ietf.org/doc/html/rfc3986#section-2.1 */
write[0] = _UT('%');
write[1] = URI_FUNC(HexToLetterEx)(code >> 4, URI_TRUE);
write[2] = URI_FUNC(HexToLetterEx)(code & 0x0f, URI_TRUE);
write += 3;
}
prevWasCr = URI_FALSE;
break;
}
case _UT('\x0d'):
if (normalizeBreaks) {
write[0] = _UT('%');
write[1] = _UT('0');
write[2] = _UT('D');
write[3] = _UT('%');
write[4] = _UT('0');
write[5] = _UT('A');
write += 6;
} else {
write[0] = _UT('%');
write[1] = _UT('0');
write[2] = _UT('D');
write += 3;
}
prevWasCr = URI_TRUE;
break;
default:
/* Percent encode */
{
const unsigned char code = (unsigned char)read[0];
/* Uppercase recommended in (last sentence of) section 2.1 *
* of RFC 3986: *
* https://datatracker.ietf.org/doc/html/rfc3986#section-2.1 */
write[0] = _UT('%');
write[1] = URI_FUNC(HexToLetterEx)(code >> 4, URI_TRUE);
write[2] = URI_FUNC(HexToLetterEx)(code & 0x0f, URI_TRUE);
write += 3;
}
prevWasCr = URI_FALSE;
break;
}
read++;
}
read++;
}
}
const URI_CHAR * URI_FUNC(UnescapeInPlace)(URI_CHAR * inout) {
return URI_FUNC(UnescapeInPlaceEx)(inout, URI_FALSE, URI_BR_DONT_TOUCH);
return URI_FUNC(UnescapeInPlaceEx)(inout, URI_FALSE, URI_BR_DONT_TOUCH);
}
const URI_CHAR * URI_FUNC(UnescapeInPlaceEx)(URI_CHAR * inout, UriBool plusToSpace,
UriBreakConversion breakConversion) {
URI_CHAR * read = inout;
URI_CHAR * write = inout;
UriBool prevWasCr = URI_FALSE;
if (inout == NULL) {
return NULL;
}
const URI_CHAR * URI_FUNC(UnescapeInPlaceEx)(URI_CHAR * inout,
UriBool plusToSpace, UriBreakConversion breakConversion) {
URI_CHAR * read = inout;
URI_CHAR * write = inout;
UriBool prevWasCr = URI_FALSE;
for (;;) {
switch (read[0]) {
case _UT('\0'):
if (read > write) {
write[0] = _UT('\0');
}
return write;
if (inout == NULL) {
return NULL;
}
case _UT('%'):
switch (read[1]) {
case _UT('0'):
case _UT('1'):
case _UT('2'):
case _UT('3'):
case _UT('4'):
case _UT('5'):
case _UT('6'):
case _UT('7'):
case _UT('8'):
case _UT('9'):
case _UT('a'):
case _UT('b'):
case _UT('c'):
case _UT('d'):
case _UT('e'):
case _UT('f'):
case _UT('A'):
case _UT('B'):
case _UT('C'):
case _UT('D'):
case _UT('E'):
case _UT('F'):
switch (read[2]) {
case _UT('0'):
case _UT('1'):
case _UT('2'):
case _UT('3'):
case _UT('4'):
case _UT('5'):
case _UT('6'):
case _UT('7'):
case _UT('8'):
case _UT('9'):
case _UT('a'):
case _UT('b'):
case _UT('c'):
case _UT('d'):
case _UT('e'):
case _UT('f'):
case _UT('A'):
case _UT('B'):
case _UT('C'):
case _UT('D'):
case _UT('E'):
case _UT('F'): {
/* Percent group found */
const unsigned char left = URI_FUNC(HexdigToInt)(read[1]);
const unsigned char right = URI_FUNC(HexdigToInt)(read[2]);
const int code = 16 * left + right;
switch (code) {
case 10:
switch (breakConversion) {
case URI_BR_TO_LF:
if (!prevWasCr) {
write[0] = (URI_CHAR)10;
write++;
}
break;
for (;;) {
switch (read[0]) {
case _UT('\0'):
if (read > write) {
write[0] = _UT('\0');
}
return write;
case URI_BR_TO_CRLF:
if (!prevWasCr) {
write[0] = (URI_CHAR)13;
write[1] = (URI_CHAR)10;
write += 2;
}
break;
case _UT('%'):
switch (read[1]) {
case _UT('0'):
case _UT('1'):
case _UT('2'):
case _UT('3'):
case _UT('4'):
case _UT('5'):
case _UT('6'):
case _UT('7'):
case _UT('8'):
case _UT('9'):
case _UT('a'):
case _UT('b'):
case _UT('c'):
case _UT('d'):
case _UT('e'):
case _UT('f'):
case _UT('A'):
case _UT('B'):
case _UT('C'):
case _UT('D'):
case _UT('E'):
case _UT('F'):
switch (read[2]) {
case _UT('0'):
case _UT('1'):
case _UT('2'):
case _UT('3'):
case _UT('4'):
case _UT('5'):
case _UT('6'):
case _UT('7'):
case _UT('8'):
case _UT('9'):
case _UT('a'):
case _UT('b'):
case _UT('c'):
case _UT('d'):
case _UT('e'):
case _UT('f'):
case _UT('A'):
case _UT('B'):
case _UT('C'):
case _UT('D'):
case _UT('E'):
case _UT('F'):
{
/* Percent group found */
const unsigned char left = URI_FUNC(HexdigToInt)(read[1]);
const unsigned char right = URI_FUNC(HexdigToInt)(read[2]);
const int code = 16 * left + right;
switch (code) {
case 10:
switch (breakConversion) {
case URI_BR_TO_LF:
if (!prevWasCr) {
write[0] = (URI_CHAR)10;
write++;
}
break;
case URI_BR_TO_CR:
if (!prevWasCr) {
write[0] = (URI_CHAR)13;
write++;
}
break;
case URI_BR_TO_CRLF:
if (!prevWasCr) {
write[0] = (URI_CHAR)13;
write[1] = (URI_CHAR)10;
write += 2;
}
break;
case URI_BR_DONT_TOUCH:
default:
write[0] = (URI_CHAR)10;
write++;
}
prevWasCr = URI_FALSE;
break;
case URI_BR_TO_CR:
if (!prevWasCr) {
write[0] = (URI_CHAR)13;
write++;
}
break;
case 13:
switch (breakConversion) {
case URI_BR_TO_LF:
write[0] = (URI_CHAR)10;
write++;
break;
case URI_BR_DONT_TOUCH:
default:
write[0] = (URI_CHAR)10;
write++;
case URI_BR_TO_CRLF:
write[0] = (URI_CHAR)13;
write[1] = (URI_CHAR)10;
write += 2;
break;
}
prevWasCr = URI_FALSE;
break;
case URI_BR_TO_CR:
write[0] = (URI_CHAR)13;
write++;
break;
case 13:
switch (breakConversion) {
case URI_BR_TO_LF:
write[0] = (URI_CHAR)10;
write++;
break;
case URI_BR_DONT_TOUCH:
default:
write[0] = (URI_CHAR)13;
write++;
}
prevWasCr = URI_TRUE;
break;
case URI_BR_TO_CRLF:
write[0] = (URI_CHAR)13;
write[1] = (URI_CHAR)10;
write += 2;
break;
default:
write[0] = (URI_CHAR)(code);
write++;
case URI_BR_TO_CR:
write[0] = (URI_CHAR)13;
write++;
break;
prevWasCr = URI_FALSE;
}
read += 3;
} break;
case URI_BR_DONT_TOUCH:
default:
write[0] = (URI_CHAR)13;
write++;
default:
/* Copy two chars unmodified and */
/* look at this char again */
if (read > write) {
write[0] = read[0];
write[1] = read[1];
}
read += 2;
write += 2;
}
prevWasCr = URI_TRUE;
break;
prevWasCr = URI_FALSE;
}
break;
default:
write[0] = (URI_CHAR)(code);
write++;
default:
/* Copy one char unmodified and */
/* look at this char again */
if (read > write) {
write[0] = read[0];
}
read++;
write++;
prevWasCr = URI_FALSE;
prevWasCr = URI_FALSE;
}
break;
}
read += 3;
}
break;
case _UT('+'):
if (plusToSpace) {
/* Convert '+' to ' ' */
write[0] = _UT(' ');
} else {
/* Copy one char unmodified */
if (read > write) {
write[0] = read[0];
}
}
read++;
write++;
default:
/* Copy two chars unmodified and */
/* look at this char again */
if (read > write) {
write[0] = read[0];
write[1] = read[1];
}
read += 2;
write += 2;
prevWasCr = URI_FALSE;
break;
prevWasCr = URI_FALSE;
}
break;
default:
/* Copy one char unmodified */
if (read > write) {
write[0] = read[0];
}
read++;
write++;
default:
/* Copy one char unmodified and */
/* look at this char again */
if (read > write) {
write[0] = read[0];
}
read++;
write++;
prevWasCr = URI_FALSE;
}
break;
case _UT('+'):
if (plusToSpace) {
/* Convert '+' to ' ' */
write[0] = _UT(' ');
} else {
/* Copy one char unmodified */
if (read > write) {
write[0] = read[0];
}
}
read++;
write++;
prevWasCr = URI_FALSE;
break;
default:
/* Copy one char unmodified */
if (read > write) {
write[0] = read[0];
}
read++;
write++;
prevWasCr = URI_FALSE;
}
}
prevWasCr = URI_FALSE;
}
}
}
#endif

View File

@@ -41,202 +41,181 @@
#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 "UriFile.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriFile.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriFile.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriFile.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>
#endif
#include <stdlib.h> /* for size_t, avoiding stddef.h for older MSVCs */
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# include <wchar.h>
# endif
# ifndef URI_DOXYGEN
# include <uriparser/Uri.h>
# endif
# include <stdlib.h> /* for size_t, avoiding stddef.h for older MSVCs */
static URI_INLINE int URI_FUNC(FilenameToUriString)(const URI_CHAR * filename,
URI_CHAR * uriString, UriBool fromUnix) {
const URI_CHAR * input = filename;
const URI_CHAR * lastSep = input - 1;
UriBool firstSegment = URI_TRUE;
URI_CHAR * output = uriString;
UriBool absolute;
UriBool is_windows_network;
URI_CHAR * uriString,
UriBool fromUnix) {
const URI_CHAR * input = filename;
const URI_CHAR * lastSep = input - 1;
UriBool firstSegment = URI_TRUE;
URI_CHAR * output = uriString;
UriBool absolute;
UriBool is_windows_network;
if ((filename == NULL) || (uriString == NULL)) {
return URI_ERROR_NULL;
}
if ((filename == NULL) || (uriString == NULL)) {
return URI_ERROR_NULL;
}
is_windows_network = (filename[0] == _UT('\\')) && (filename[1] == _UT('\\'));
absolute = fromUnix
? (filename[0] == _UT('/'))
: (((filename[0] != _UT('\0')) && (filename[1] == _UT(':')))
|| is_windows_network);
is_windows_network = (filename[0] == _UT('\\')) && (filename[1] == _UT('\\'));
absolute = fromUnix ? (filename[0] == _UT('/'))
: (((filename[0] != _UT('\0')) && (filename[1] == _UT(':')))
|| is_windows_network);
if (absolute) {
const URI_CHAR * const prefix = fromUnix
? _UT("file://")
: is_windows_network
? _UT("file:")
: _UT("file:///");
const size_t prefixLen = URI_STRLEN(prefix);
if (absolute) {
const URI_CHAR * const prefix = fromUnix ? _UT("file://")
: is_windows_network ? _UT("file:")
: _UT("file:///");
const size_t prefixLen = URI_STRLEN(prefix);
/* Copy prefix */
memcpy(uriString, prefix, prefixLen * sizeof(URI_CHAR));
output += prefixLen;
}
/* Copy prefix */
memcpy(uriString, prefix, prefixLen * sizeof(URI_CHAR));
output += prefixLen;
}
/* Copy and escape on the fly */
for (;;) {
if ((input[0] == _UT('\0'))
|| (fromUnix && input[0] == _UT('/'))
|| (!fromUnix && input[0] == _UT('\\'))) {
/* Copy text after last separator */
if (lastSep + 1 < input) {
if (!fromUnix && absolute && (firstSegment == URI_TRUE)) {
/* Quick hack to not convert "C:" to "C%3A" */
const int charsToCopy = (int)(input - (lastSep + 1));
memcpy(output, lastSep + 1, charsToCopy * sizeof(URI_CHAR));
output += charsToCopy;
} else {
output = URI_FUNC(EscapeEx)(lastSep + 1, input, output,
URI_FALSE, URI_FALSE);
}
}
firstSegment = URI_FALSE;
}
/* Copy and escape on the fly */
for (;;) {
if ((input[0] == _UT('\0')) || (fromUnix && input[0] == _UT('/'))
|| (!fromUnix && input[0] == _UT('\\'))) {
/* Copy text after last separator */
if (lastSep + 1 < input) {
if (!fromUnix && absolute && (firstSegment == URI_TRUE)) {
/* Quick hack to not convert "C:" to "C%3A" */
const int charsToCopy = (int)(input - (lastSep + 1));
memcpy(output, lastSep + 1, charsToCopy * sizeof(URI_CHAR));
output += charsToCopy;
} else {
output = URI_FUNC(EscapeEx)(lastSep + 1, input, output, URI_FALSE,
URI_FALSE);
}
}
firstSegment = URI_FALSE;
}
if (input[0] == _UT('\0')) {
output[0] = _UT('\0');
break;
} else if (fromUnix && (input[0] == _UT('/'))) {
/* Copy separators unmodified */
output[0] = _UT('/');
output++;
lastSep = input;
} else if (!fromUnix && (input[0] == _UT('\\'))) {
/* Convert backslashes to forward slashes */
output[0] = _UT('/');
output++;
lastSep = input;
}
input++;
}
if (input[0] == _UT('\0')) {
output[0] = _UT('\0');
break;
} else if (fromUnix && (input[0] == _UT('/'))) {
/* Copy separators unmodified */
output[0] = _UT('/');
output++;
lastSep = input;
} else if (!fromUnix && (input[0] == _UT('\\'))) {
/* Convert backslashes to forward slashes */
output[0] = _UT('/');
output++;
lastSep = input;
}
input++;
}
return URI_SUCCESS;
return URI_SUCCESS;
}
static URI_INLINE int URI_FUNC(UriStringToFilename)(const URI_CHAR * uriString,
URI_CHAR * filename, UriBool toUnix) {
if ((uriString == NULL) || (filename == NULL)) {
return URI_ERROR_NULL;
}
URI_CHAR * filename, UriBool toUnix) {
if ((uriString == NULL) || (filename == NULL)) {
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 = file_unknown_slashes
&& (URI_STRNCMP(uriString, _UT("file:/"), URI_STRLEN(_UT("file:/"))) == 0);
const UriBool file_two_or_more_slashes = file_one_or_more_slashes
&& (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 UriBool file_unknown_slashes =
URI_STRNCMP(uriString, _UT("file:"), URI_STRLEN(_UT("file:"))) == 0;
const UriBool file_one_or_more_slashes =
file_unknown_slashes
&& (URI_STRNCMP(uriString, _UT("file:/"), URI_STRLEN(_UT("file:/"))) == 0);
const UriBool file_two_or_more_slashes =
file_one_or_more_slashes
&& (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 */
: URI_STRLEN(_UT("file:///"))
/* file://Server01/Letter.txt */
: URI_STRLEN(_UT("file://"))
: ((file_one_or_more_slashes && toUnix)
/* file:/bin/bash */
/* https://tools.ietf.org/html/rfc8089#appendix-B */
? URI_STRLEN(_UT("file:"))
: ((! toUnix && file_unknown_slashes && ! file_one_or_more_slashes)
/* file:c:/path/to/file */
/* https://tools.ietf.org/html/rfc8089#appendix-E.2 */
? URI_STRLEN(_UT("file:"))
: 0));
const size_t charsToCopy = URI_STRLEN(uriString + charsToSkip) + 1;
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 */
: URI_STRLEN(_UT("file:///"))
/* file://Server01/Letter.txt */
: URI_STRLEN(_UT("file://"))
: ((file_one_or_more_slashes && toUnix)
/* file:/bin/bash */
/* https://tools.ietf.org/html/rfc8089#appendix-B */
? URI_STRLEN(_UT("file:"))
: ((!toUnix && file_unknown_slashes && !file_one_or_more_slashes)
/* file:c:/path/to/file */
/* https://tools.ietf.org/html/rfc8089#appendix-E.2 */
? URI_STRLEN(_UT("file:"))
: 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;
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;
URI_CHAR * const unescape_target =
is_windows_network_with_authority ? (filename + 2) : filename;
if (is_windows_network_with_authority) {
filename[0] = '\\';
filename[1] = '\\';
}
if (is_windows_network_with_authority) {
filename[0] = '\\';
filename[1] = '\\';
}
memcpy(unescape_target, uriString + charsToSkip, charsToCopy * sizeof(URI_CHAR));
URI_FUNC(UnescapeInPlaceEx)(filename, URI_FALSE, URI_BR_DONT_TOUCH);
}
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) {
URI_CHAR * walker = filename;
while (walker[0] != _UT('\0')) {
if (walker[0] == _UT('/')) {
walker[0] = _UT('\\');
}
walker++;
}
}
/* Convert forward slashes to backslashes */
if (!toUnix) {
URI_CHAR * walker = filename;
while (walker[0] != _UT('\0')) {
if (walker[0] == _UT('/')) {
walker[0] = _UT('\\');
}
walker++;
}
}
return URI_SUCCESS;
return URI_SUCCESS;
}
int URI_FUNC(UnixFilenameToUriString)(const URI_CHAR * filename, URI_CHAR * uriString) {
return URI_FUNC(FilenameToUriString)(filename, uriString, URI_TRUE);
return URI_FUNC(FilenameToUriString)(filename, uriString, URI_TRUE);
}
int URI_FUNC(WindowsFilenameToUriString)(const URI_CHAR * filename, URI_CHAR * uriString) {
return URI_FUNC(FilenameToUriString)(filename, uriString, URI_FALSE);
int URI_FUNC(WindowsFilenameToUriString)(const URI_CHAR * filename,
URI_CHAR * uriString) {
return URI_FUNC(FilenameToUriString)(filename, uriString, URI_FALSE);
}
int URI_FUNC(UriStringToUnixFilename)(const URI_CHAR * uriString, URI_CHAR * filename) {
return URI_FUNC(UriStringToFilename)(uriString, filename, URI_TRUE);
return URI_FUNC(UriStringToFilename)(uriString, filename, URI_TRUE);
}
int URI_FUNC(UriStringToWindowsFilename)(const URI_CHAR * uriString, URI_CHAR * filename) {
return URI_FUNC(UriStringToFilename)(uriString, filename, URI_FALSE);
int URI_FUNC(UriStringToWindowsFilename)(const URI_CHAR * uriString,
URI_CHAR * filename) {
return URI_FUNC(UriStringToFilename)(uriString, filename, URI_FALSE);
}
#endif

View File

@@ -47,97 +47,93 @@
#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 "UriIp4.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriIp4.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriIp4.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriIp4.c"
# undef URI_PASS_UNICODE
# endif
#else
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# endif
#ifndef URI_DOXYGEN
# include <uriparser/UriIp4.h>
# include "UriIp4Base.h"
# include <uriparser/UriBase.h>
#endif
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# endif
# ifndef URI_DOXYGEN
# include <uriparser/UriIp4.h>
# include "UriIp4Base.h"
# include <uriparser/UriBase.h>
# endif
/* Prototypes */
static const URI_CHAR * URI_FUNC(ParseDecOctet)(UriIp4Parser * parser,
const URI_CHAR * first, const URI_CHAR * afterLast);
const URI_CHAR * first,
const URI_CHAR * afterLast);
static const URI_CHAR * URI_FUNC(ParseDecOctetOne)(UriIp4Parser * parser,
const URI_CHAR * first, const URI_CHAR * afterLast);
const URI_CHAR * first,
const URI_CHAR * afterLast);
static const URI_CHAR * URI_FUNC(ParseDecOctetTwo)(UriIp4Parser * parser,
const URI_CHAR * first, const URI_CHAR * afterLast);
const URI_CHAR * first,
const URI_CHAR * afterLast);
static const URI_CHAR * URI_FUNC(ParseDecOctetThree)(UriIp4Parser * parser,
const URI_CHAR * first, const URI_CHAR * afterLast);
const URI_CHAR * first,
const URI_CHAR * afterLast);
static const URI_CHAR * URI_FUNC(ParseDecOctetFour)(UriIp4Parser * parser,
const URI_CHAR * first, const URI_CHAR * afterLast);
const URI_CHAR * first,
const URI_CHAR * afterLast);
/*
* [ipFourAddress]->[decOctet]<.>[decOctet]<.>[decOctet]<.>[decOctet]
*/
int URI_FUNC(ParseIpFourAddress)(unsigned char * octetOutput,
const URI_CHAR * first, const URI_CHAR * afterLast) {
const URI_CHAR * after;
UriIp4Parser parser;
int URI_FUNC(ParseIpFourAddress)(unsigned char * octetOutput, const URI_CHAR * first,
const URI_CHAR * afterLast) {
const URI_CHAR * after;
UriIp4Parser parser;
/* Essential checks */
if ((octetOutput == NULL) || (first == NULL)
|| (afterLast <= first)) {
return URI_ERROR_SYNTAX;
}
/* Essential checks */
if ((octetOutput == NULL) || (first == NULL) || (afterLast <= first)) {
return URI_ERROR_SYNTAX;
}
/* Reset parser */
parser.stackCount = 0;
/* Reset parser */
parser.stackCount = 0;
/* Octet #1 */
after = URI_FUNC(ParseDecOctet)(&parser, first, afterLast);
if ((after == NULL) || (after >= afterLast) || (*after != _UT('.'))) {
return URI_ERROR_SYNTAX;
}
uriStackToOctet(&parser, octetOutput);
/* Octet #1 */
after = URI_FUNC(ParseDecOctet)(&parser, first, afterLast);
if ((after == NULL) || (after >= afterLast) || (*after != _UT('.'))) {
return URI_ERROR_SYNTAX;
}
uriStackToOctet(&parser, octetOutput);
/* Octet #2 */
after = URI_FUNC(ParseDecOctet)(&parser, after + 1, afterLast);
if ((after == NULL) || (after >= afterLast) || (*after != _UT('.'))) {
return URI_ERROR_SYNTAX;
}
uriStackToOctet(&parser, octetOutput + 1);
/* Octet #2 */
after = URI_FUNC(ParseDecOctet)(&parser, after + 1, afterLast);
if ((after == NULL) || (after >= afterLast) || (*after != _UT('.'))) {
return URI_ERROR_SYNTAX;
}
uriStackToOctet(&parser, octetOutput + 1);
/* Octet #3 */
after = URI_FUNC(ParseDecOctet)(&parser, after + 1, afterLast);
if ((after == NULL) || (after >= afterLast) || (*after != _UT('.'))) {
return URI_ERROR_SYNTAX;
}
uriStackToOctet(&parser, octetOutput + 2);
/* Octet #3 */
after = URI_FUNC(ParseDecOctet)(&parser, after + 1, afterLast);
if ((after == NULL) || (after >= afterLast) || (*after != _UT('.'))) {
return URI_ERROR_SYNTAX;
}
uriStackToOctet(&parser, octetOutput + 2);
/* Octet #4 */
after = URI_FUNC(ParseDecOctet)(&parser, after + 1, afterLast);
if (after != afterLast) {
return URI_ERROR_SYNTAX;
}
uriStackToOctet(&parser, octetOutput + 3);
/* Octet #4 */
after = URI_FUNC(ParseDecOctet)(&parser, after + 1, afterLast);
if (after != afterLast) {
return URI_ERROR_SYNTAX;
}
uriStackToOctet(&parser, octetOutput + 3);
return URI_SUCCESS;
return URI_SUCCESS;
}
/*
* [decOctet]-><0>
* [decOctet]-><1>[decOctetOne]
@@ -151,72 +147,72 @@ int URI_FUNC(ParseIpFourAddress)(unsigned char * octetOutput,
* [decOctet]-><9>[decOctetThree]
*/
static URI_INLINE const URI_CHAR * URI_FUNC(ParseDecOctet)(UriIp4Parser * parser,
const URI_CHAR * first, const URI_CHAR * afterLast) {
if (first >= afterLast) {
return NULL;
}
const URI_CHAR * first,
const URI_CHAR * afterLast) {
if (first >= afterLast) {
return NULL;
}
switch (*first) {
case _UT('0'):
uriPushToStack(parser, 0);
return first + 1;
switch (*first) {
case _UT('0'):
uriPushToStack(parser, 0);
return first + 1;
case _UT('1'):
uriPushToStack(parser, 1);
return (const URI_CHAR *)URI_FUNC(ParseDecOctetOne)(parser, first + 1, afterLast);
case _UT('1'):
uriPushToStack(parser, 1);
return (const URI_CHAR *)URI_FUNC(ParseDecOctetOne)(parser, first + 1, afterLast);
case _UT('2'):
uriPushToStack(parser, 2);
return (const URI_CHAR *)URI_FUNC(ParseDecOctetTwo)(parser, first + 1, afterLast);
case _UT('2'):
uriPushToStack(parser, 2);
return (const URI_CHAR *)URI_FUNC(ParseDecOctetTwo)(parser, first + 1, afterLast);
case _UT('3'):
case _UT('4'):
case _UT('5'):
case _UT('6'):
case _UT('7'):
case _UT('8'):
case _UT('9'):
uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
return (const URI_CHAR *)URI_FUNC(ParseDecOctetThree)(parser, first + 1, afterLast);
case _UT('3'):
case _UT('4'):
case _UT('5'):
case _UT('6'):
case _UT('7'):
case _UT('8'):
case _UT('9'):
uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
return (const URI_CHAR *)URI_FUNC(ParseDecOctetThree)(parser, first + 1,
afterLast);
default:
return NULL;
}
default:
return NULL;
}
}
/*
* [decOctetOne]-><NULL>
* [decOctetOne]->[DIGIT][decOctetThree]
*/
static URI_INLINE const URI_CHAR * URI_FUNC(ParseDecOctetOne)(UriIp4Parser * parser,
const URI_CHAR * first, const URI_CHAR * afterLast) {
if (first >= afterLast) {
return afterLast;
}
static URI_INLINE const URI_CHAR *
URI_FUNC(ParseDecOctetOne)(UriIp4Parser * parser, const URI_CHAR * first,
const URI_CHAR * afterLast) {
if (first >= afterLast) {
return afterLast;
}
switch (*first) {
case _UT('0'):
case _UT('1'):
case _UT('2'):
case _UT('3'):
case _UT('4'):
case _UT('5'):
case _UT('6'):
case _UT('7'):
case _UT('8'):
case _UT('9'):
uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
return (const URI_CHAR *)URI_FUNC(ParseDecOctetThree)(parser, first + 1, afterLast);
switch (*first) {
case _UT('0'):
case _UT('1'):
case _UT('2'):
case _UT('3'):
case _UT('4'):
case _UT('5'):
case _UT('6'):
case _UT('7'):
case _UT('8'):
case _UT('9'):
uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
return (const URI_CHAR *)URI_FUNC(ParseDecOctetThree)(parser, first + 1,
afterLast);
default:
return first;
}
default:
return first;
}
}
/*
* [decOctetTwo]-><NULL>
* [decOctetTwo]-><0>[decOctetThree]
@@ -229,71 +225,71 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseDecOctetOne)(UriIp4Parser * par
* [decOctetTwo]-><7>
* [decOctetTwo]-><8>
* [decOctetTwo]-><9>
*/
static URI_INLINE const URI_CHAR * URI_FUNC(ParseDecOctetTwo)(UriIp4Parser * parser,
const URI_CHAR * first, const URI_CHAR * afterLast) {
if (first >= afterLast) {
return afterLast;
}
*/
static URI_INLINE const URI_CHAR *
URI_FUNC(ParseDecOctetTwo)(UriIp4Parser * parser, const URI_CHAR * first,
const URI_CHAR * afterLast) {
if (first >= afterLast) {
return afterLast;
}
switch (*first) {
case _UT('0'):
case _UT('1'):
case _UT('2'):
case _UT('3'):
case _UT('4'):
uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
return (const URI_CHAR *)URI_FUNC(ParseDecOctetThree)(parser, first + 1, afterLast);
switch (*first) {
case _UT('0'):
case _UT('1'):
case _UT('2'):
case _UT('3'):
case _UT('4'):
uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
return (const URI_CHAR *)URI_FUNC(ParseDecOctetThree)(parser, first + 1,
afterLast);
case _UT('5'):
uriPushToStack(parser, 5);
return (const URI_CHAR *)URI_FUNC(ParseDecOctetFour)(parser, first + 1, afterLast);
case _UT('5'):
uriPushToStack(parser, 5);
return (const URI_CHAR *)URI_FUNC(ParseDecOctetFour)(parser, first + 1,
afterLast);
case _UT('6'):
case _UT('7'):
case _UT('8'):
case _UT('9'):
uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
return first + 1;
case _UT('6'):
case _UT('7'):
case _UT('8'):
case _UT('9'):
uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
return first + 1;
default:
return first;
}
default:
return first;
}
}
/*
* [decOctetThree]-><NULL>
* [decOctetThree]->[DIGIT]
*/
static URI_INLINE const URI_CHAR * URI_FUNC(ParseDecOctetThree)(UriIp4Parser * parser,
const URI_CHAR * first, const URI_CHAR * afterLast) {
if (first >= afterLast) {
return afterLast;
}
static URI_INLINE const URI_CHAR *
URI_FUNC(ParseDecOctetThree)(UriIp4Parser * parser, const URI_CHAR * first,
const URI_CHAR * afterLast) {
if (first >= afterLast) {
return afterLast;
}
switch (*first) {
case _UT('0'):
case _UT('1'):
case _UT('2'):
case _UT('3'):
case _UT('4'):
case _UT('5'):
case _UT('6'):
case _UT('7'):
case _UT('8'):
case _UT('9'):
uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
return first + 1;
switch (*first) {
case _UT('0'):
case _UT('1'):
case _UT('2'):
case _UT('3'):
case _UT('4'):
case _UT('5'):
case _UT('6'):
case _UT('7'):
case _UT('8'):
case _UT('9'):
uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
return first + 1;
default:
return first;
}
default:
return first;
}
}
/*
* [decOctetFour]-><NULL>
* [decOctetFour]-><0>
@@ -303,27 +299,26 @@ static URI_INLINE const URI_CHAR * URI_FUNC(ParseDecOctetThree)(UriIp4Parser * p
* [decOctetFour]-><4>
* [decOctetFour]-><5>
*/
static URI_INLINE const URI_CHAR * URI_FUNC(ParseDecOctetFour)(UriIp4Parser * parser,
const URI_CHAR * first, const URI_CHAR * afterLast) {
if (first >= afterLast) {
return afterLast;
}
static URI_INLINE const URI_CHAR *
URI_FUNC(ParseDecOctetFour)(UriIp4Parser * parser, const URI_CHAR * first,
const URI_CHAR * afterLast) {
if (first >= afterLast) {
return afterLast;
}
switch (*first) {
case _UT('0'):
case _UT('1'):
case _UT('2'):
case _UT('3'):
case _UT('4'):
case _UT('5'):
uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
return first + 1;
switch (*first) {
case _UT('0'):
case _UT('1'):
case _UT('2'):
case _UT('3'):
case _UT('4'):
case _UT('5'):
uriPushToStack(parser, (unsigned char)(9 + *first - _UT('9')));
return first + 1;
default:
return first;
}
default:
return first;
}
}
#endif

View File

@@ -43,54 +43,45 @@
*/
#ifndef URI_DOXYGEN
# include "UriIp4Base.h"
# include "UriIp4Base.h"
#endif
void uriStackToOctet(UriIp4Parser * parser, unsigned char * octet) {
switch (parser->stackCount) {
case 1:
*octet = parser->stackOne;
break;
switch (parser->stackCount) {
case 1:
*octet = parser->stackOne;
break;
case 2:
*octet = parser->stackOne * 10
+ parser->stackTwo;
break;
case 2:
*octet = parser->stackOne * 10 + parser->stackTwo;
break;
case 3:
*octet = parser->stackOne * 100
+ parser->stackTwo * 10
+ parser->stackThree;
break;
case 3:
*octet = parser->stackOne * 100 + parser->stackTwo * 10 + parser->stackThree;
break;
default:
;
}
parser->stackCount = 0;
default:;
}
parser->stackCount = 0;
}
void uriPushToStack(UriIp4Parser * parser, unsigned char digit) {
switch (parser->stackCount) {
case 0:
parser->stackOne = digit;
parser->stackCount = 1;
break;
switch (parser->stackCount) {
case 0:
parser->stackOne = digit;
parser->stackCount = 1;
break;
case 1:
parser->stackTwo = digit;
parser->stackCount = 2;
break;
case 1:
parser->stackTwo = digit;
parser->stackCount = 2;
break;
case 2:
parser->stackThree = digit;
parser->stackCount = 3;
break;
case 2:
parser->stackThree = digit;
parser->stackCount = 3;
break;
default:
;
}
default:;
}
}

View File

@@ -38,22 +38,16 @@
*/
#ifndef URI_IP4_BASE_H
#define URI_IP4_BASE_H 1
# define URI_IP4_BASE_H 1
typedef struct UriIp4ParserStruct {
unsigned char stackCount;
unsigned char stackOne;
unsigned char stackTwo;
unsigned char stackThree;
unsigned char stackCount;
unsigned char stackOne;
unsigned char stackTwo;
unsigned char stackThree;
} UriIp4Parser;
void uriPushToStack(UriIp4Parser * parser, unsigned char digit);
void uriStackToOctet(UriIp4Parser * parser, unsigned char * octet);
#endif /* URI_IP4_BASE_H */

View File

@@ -42,469 +42,423 @@
* Holds memory manager implementation.
*/
#include "UriConfig.h" /* for HAVE_REALLOCARRAY */
#include "UriConfig.h" /* for HAVE_REALLOCARRAY */
#ifdef HAVE_REALLOCARRAY
# ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
# endif
# ifdef __NetBSD__
# define _OPENBSD_SOURCE 1
# endif
# ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
# endif
# ifdef __NetBSD__
# define _OPENBSD_SOURCE 1
# endif
#endif
#include <errno.h>
#include <stdlib.h>
#ifndef URI_DOXYGEN
# include "UriMemory.h"
# include "UriMemory.h"
#endif
#define URI_MAX(a, b) (((a) > (b)) ? (a) : (b))
#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_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 */ \
if ((nmemb != 0) && (total_size / nmemb != size)) { \
errno = ENOMEM; \
return NULL; \
} \
} while (0)
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 * 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 * 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 * 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) {
static void * uriDefaultReallocarray(UriMemoryManager * URI_UNUSED(memory), void * ptr,
size_t nmemb, size_t size) {
#ifdef HAVE_REALLOCARRAY
return reallocarray(ptr, nmemb, size);
return reallocarray(ptr, nmemb, size);
#else
const size_t total_size = nmemb * size;
const size_t total_size = nmemb * size;
URI_CHECK_ALLOC_OVERFLOW(total_size, nmemb, size); /* may return */
URI_CHECK_ALLOC_OVERFLOW(total_size, nmemb, size); /* may return */
return realloc(ptr, total_size);
return realloc(ptr, total_size);
#endif
}
static void uriDefaultFree(UriMemoryManager * URI_UNUSED(memory),
void * ptr) {
free(ptr);
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;
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;
void * buffer;
const size_t total_size = nmemb * size;
if (memory == NULL) {
errno = EINVAL;
return NULL;
}
if (memory == NULL) {
errno = EINVAL;
return NULL;
}
URI_CHECK_ALLOC_OVERFLOW(total_size, nmemb, size); /* may return */
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;
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;
}
void * uriEmulateReallocarray(UriMemoryManager * memory,
void * ptr, size_t nmemb, size_t size) {
const size_t total_size = nmemb * size;
URI_CHECK_ALLOC_OVERFLOW(total_size, nmemb, size); /* may return */
if (memory == NULL) {
errno = EINVAL;
return NULL;
}
URI_CHECK_ALLOC_OVERFLOW(total_size, nmemb, size); /* may return */
return memory->realloc(memory, ptr, total_size);
return memory->realloc(memory, ptr, total_size);
}
static void * uriDecorateMalloc(UriMemoryManager * memory, size_t size) {
UriMemoryManager * backend;
const size_t extraBytes = sizeof(size_t) + URI_MALLOC_PADDING;
void * buffer;
if (memory == NULL) {
errno = EINVAL;
return NULL;
}
static void * uriDecorateMalloc(UriMemoryManager * memory,
size_t size) {
UriMemoryManager * backend;
const size_t extraBytes = sizeof(size_t) + URI_MALLOC_PADDING;
void * buffer;
/* check for unsigned overflow */
if (size > ((size_t)-1) - extraBytes) {
errno = ENOMEM;
return NULL;
}
if (memory == NULL) {
errno = EINVAL;
return NULL;
}
backend = (UriMemoryManager *)memory->userData;
if (backend == NULL) {
errno = EINVAL;
return NULL;
}
/* check for unsigned overflow */
if (size > ((size_t)-1) - extraBytes) {
errno = ENOMEM;
return NULL;
}
buffer = backend->malloc(backend, extraBytes + size);
if (buffer == NULL) {
return NULL;
}
backend = (UriMemoryManager *)memory->userData;
if (backend == NULL) {
errno = EINVAL;
return NULL;
}
*(size_t *)buffer = size;
buffer = backend->malloc(backend, extraBytes + size);
if (buffer == NULL) {
return NULL;
}
*(size_t *)buffer = size;
return (char *)buffer + extraBytes;
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;
}
static void * uriDecorateRealloc(UriMemoryManager * memory,
void * ptr, size_t size) {
void * newBuffer;
size_t prevSize;
/* 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);
}
if (memory == NULL) {
errno = EINVAL;
return NULL;
}
/* 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;
}
/* 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);
}
prevSize = *((size_t *)((char *)ptr - sizeof(size_t) - URI_MALLOC_PADDING));
/* 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;
}
/* Anything to do? */
/* mull-ignore-next cxx_le_to_lt */
if (size <= prevSize) {
return ptr;
}
prevSize = *((size_t *)((char *)ptr - sizeof(size_t) - URI_MALLOC_PADDING));
newBuffer = memory->malloc(memory, size);
if (newBuffer == NULL) {
/* errno set by malloc */
return NULL;
}
/* Anything to do? */
if (size <= prevSize) {
return ptr;
}
memcpy(newBuffer, ptr, prevSize);
newBuffer = memory->malloc(memory, size);
if (newBuffer == NULL) {
/* errno set by malloc */
return NULL;
}
memory->free(memory, ptr);
memcpy(newBuffer, ptr, prevSize);
memory->free(memory, ptr);
return newBuffer;
return newBuffer;
}
static void uriDecorateFree(UriMemoryManager * memory, void * ptr) {
UriMemoryManager * backend;
UriMemoryManager * backend;
if ((ptr == NULL) || (memory == NULL)) {
return;
}
if ((ptr == NULL) || (memory == NULL)) {
return;
}
backend = (UriMemoryManager *)memory->userData;
if (backend == NULL) {
return;
}
backend = (UriMemoryManager *)memory->userData;
if (backend == NULL) {
return;
}
backend->free(backend, (char *)ptr - sizeof(size_t) - URI_MALLOC_PADDING);
backend->free(backend, (char *)ptr - sizeof(size_t) - URI_MALLOC_PADDING);
}
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;
}
int uriCompleteMemoryManager(UriMemoryManager * memory,
UriMemoryManager * backend) {
if ((memory == NULL) || (backend == NULL)) {
return URI_ERROR_NULL;
}
memory->calloc = uriEmulateCalloc;
memory->reallocarray = uriEmulateReallocarray;
if ((backend->malloc == NULL) || (backend->free == NULL)) {
return URI_ERROR_MEMORY_MANAGER_INCOMPLETE;
}
memory->malloc = uriDecorateMalloc;
memory->realloc = uriDecorateRealloc;
memory->free = uriDecorateFree;
memory->calloc = uriEmulateCalloc;
memory->reallocarray = uriEmulateReallocarray;
memory->userData = backend;
memory->malloc = uriDecorateMalloc;
memory->realloc = uriDecorateRealloc;
memory->free = uriDecorateFree;
memory->userData = backend;
return URI_SUCCESS;
return URI_SUCCESS;
}
/* mull-off */
int uriTestMemoryManagerEx(UriMemoryManager * memory, UriBool challengeAlignment) {
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;
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 (memory == NULL) {
return URI_ERROR_NULL;
}
if (uriMemoryManagerIsComplete(memory) != URI_TRUE) {
return URI_ERROR_MEMORY_MANAGER_INCOMPLETE;
}
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;
/* 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;
/* 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 + 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;
/* 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, 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;
}
/* 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 + 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] = '\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] = '\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;
/* 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, 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, 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, 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;
}
/* 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;
}
/* 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;
/* 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;
}
}
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);
}
}
memory->free(memory, ptr);
}
}
return URI_SUCCESS;
return URI_SUCCESS;
}
/* mull-on */
int uriTestMemoryManager(UriMemoryManager * memory) {
return uriTestMemoryManagerEx(memory, /*challengeAlignment=*/ URI_FALSE);
return uriTestMemoryManagerEx(memory, /*challengeAlignment=*/URI_FALSE);
}
/*extern*/ UriMemoryManager defaultMemoryManager = {
uriDefaultMalloc,
uriDefaultCalloc,
uriDefaultRealloc,
uriDefaultReallocarray,
uriDefaultFree,
NULL /* userData */
uriDefaultMalloc, uriDefaultCalloc, uriDefaultRealloc,
uriDefaultReallocarray, uriDefaultFree, NULL /* userData */
};

View File

@@ -38,41 +38,31 @@
*/
#ifndef URI_MEMORY_H
#define URI_MEMORY_H 1
# define URI_MEMORY_H 1
# 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)
#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)
#ifdef __cplusplus
# define URIPARSER_EXTERN extern "C"
#else
# define URIPARSER_EXTERN extern
#endif
# ifdef __cplusplus
# define URIPARSER_EXTERN extern "C"
# else
# define URIPARSER_EXTERN extern
# endif
URIPARSER_EXTERN UriMemoryManager defaultMemoryManager;
#undef URIPARSER_EXTERN
# undef URIPARSER_EXTERN
UriBool uriMemoryManagerIsComplete(const UriMemoryManager * memory);
#endif /* URI_MEMORY_H */

File diff suppressed because it is too large Load Diff

View File

@@ -39,38 +39,37 @@
*/
#if (defined(URI_PASS_ANSI) && !defined(URI_NORMALIZE_H_ANSI)) \
|| (defined(URI_PASS_UNICODE) && !defined(URI_NORMALIZE_H_UNICODE)) \
|| (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
|| (defined(URI_PASS_UNICODE) && !defined(URI_NORMALIZE_H_UNICODE)) \
|| (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
/* What encodings are enabled? */
#include <uriparser/UriDefsConfig.h>
#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
# 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 "UriNormalize.h"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriNormalize.h"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriNormalize.h"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriNormalize.h"
# undef URI_PASS_UNICODE
# endif
/* Only one pass for each encoding */
#elif (defined(URI_PASS_ANSI) && !defined(URI_NORMALIZE_H_ANSI) \
&& defined(URI_ENABLE_ANSI)) || (defined(URI_PASS_UNICODE) \
&& !defined(URI_NORMALIZE_H_UNICODE) && defined(URI_ENABLE_UNICODE))
# ifdef URI_PASS_ANSI
# define URI_NORMALIZE_H_ANSI 1
# include <uriparser/UriDefsAnsi.h>
# else
# define URI_NORMALIZE_H_UNICODE 1
# include <uriparser/UriDefsUnicode.h>
# endif
# elif (defined(URI_PASS_ANSI) && !defined(URI_NORMALIZE_H_ANSI) \
&& defined(URI_ENABLE_ANSI)) \
|| (defined(URI_PASS_UNICODE) && !defined(URI_NORMALIZE_H_UNICODE) \
&& defined(URI_ENABLE_UNICODE))
# ifdef URI_PASS_ANSI
# define URI_NORMALIZE_H_ANSI 1
# include <uriparser/UriDefsAnsi.h>
# else
# define URI_NORMALIZE_H_UNICODE 1
# include <uriparser/UriDefsUnicode.h>
# endif
void URI_FUNC(PreventLeakage)(URI_TYPE(Uri) * uri, unsigned int revertMask,
UriMemoryManager * memory);
void URI_FUNC(PreventLeakage)(URI_TYPE(Uri) * uri,
unsigned int revertMask, UriMemoryManager * memory);
#endif
# endif
#endif

View File

@@ -38,82 +38,80 @@
*/
#ifndef URI_DOXYGEN
# include "UriNormalizeBase.h"
# include "UriNormalizeBase.h"
#endif
UriBool uriIsUnreserved(int code) {
switch (code) {
case L'a': /* ALPHA */
case L'A':
case L'b':
case L'B':
case L'c':
case L'C':
case L'd':
case L'D':
case L'e':
case L'E':
case L'f':
case L'F':
case L'g':
case L'G':
case L'h':
case L'H':
case L'i':
case L'I':
case L'j':
case L'J':
case L'k':
case L'K':
case L'l':
case L'L':
case L'm':
case L'M':
case L'n':
case L'N':
case L'o':
case L'O':
case L'p':
case L'P':
case L'q':
case L'Q':
case L'r':
case L'R':
case L's':
case L'S':
case L't':
case L'T':
case L'u':
case L'U':
case L'v':
case L'V':
case L'w':
case L'W':
case L'x':
case L'X':
case L'y':
case L'Y':
case L'z':
case L'Z':
case L'0': /* DIGIT */
case L'1':
case L'2':
case L'3':
case L'4':
case L'5':
case L'6':
case L'7':
case L'8':
case L'9':
case L'-': /* "-" / "." / "_" / "~" */
case L'.':
case L'_':
case L'~':
return URI_TRUE;
switch (code) {
case L'a': /* ALPHA */
case L'A':
case L'b':
case L'B':
case L'c':
case L'C':
case L'd':
case L'D':
case L'e':
case L'E':
case L'f':
case L'F':
case L'g':
case L'G':
case L'h':
case L'H':
case L'i':
case L'I':
case L'j':
case L'J':
case L'k':
case L'K':
case L'l':
case L'L':
case L'm':
case L'M':
case L'n':
case L'N':
case L'o':
case L'O':
case L'p':
case L'P':
case L'q':
case L'Q':
case L'r':
case L'R':
case L's':
case L'S':
case L't':
case L'T':
case L'u':
case L'U':
case L'v':
case L'V':
case L'w':
case L'W':
case L'x':
case L'X':
case L'y':
case L'Y':
case L'z':
case L'Z':
case L'0': /* DIGIT */
case L'1':
case L'2':
case L'3':
case L'4':
case L'5':
case L'6':
case L'7':
case L'8':
case L'9':
case L'-': /* "-" / "." / "_" / "~" */
case L'.':
case L'_':
case L'~':
return URI_TRUE;
default:
return URI_FALSE;
}
default:
return URI_FALSE;
}
}

View File

@@ -38,16 +38,10 @@
*/
#ifndef URI_NORMALIZE_BASE_H
#define URI_NORMALIZE_BASE_H 1
#include <uriparser/UriBase.h>
# define URI_NORMALIZE_BASE_H 1
# include <uriparser/UriBase.h>
UriBool uriIsUnreserved(int code);
#endif /* URI_NORMALIZE_BASE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -38,53 +38,48 @@
*/
#ifndef URI_DOXYGEN
# include "UriParseBase.h"
# include "UriParseBase.h"
#endif
void uriWriteQuadToDoubleByte(const unsigned char * hexDigits, int digitCount,
unsigned char * output) {
switch (digitCount) {
case 1:
/* 0x___? -> \x00 \x0? */
output[0] = 0;
output[1] = hexDigits[0];
break;
case 2:
/* 0x__?? -> \0xx \x?? */
output[0] = 0;
output[1] = 16 * hexDigits[0] + hexDigits[1];
break;
void uriWriteQuadToDoubleByte(const unsigned char * hexDigits, int digitCount, unsigned char * output) {
switch (digitCount) {
case 1:
/* 0x___? -> \x00 \x0? */
output[0] = 0;
output[1] = hexDigits[0];
break;
case 3:
/* 0x_??? -> \0x? \x?? */
output[0] = hexDigits[0];
output[1] = 16 * hexDigits[1] + hexDigits[2];
break;
case 2:
/* 0x__?? -> \0xx \x?? */
output[0] = 0;
output[1] = 16 * hexDigits[0] + hexDigits[1];
break;
case 3:
/* 0x_??? -> \0x? \x?? */
output[0] = hexDigits[0];
output[1] = 16 * hexDigits[1] + hexDigits[2];
break;
case 4:
/* 0x???? -> \0?? \x?? */
output[0] = 16 * hexDigits[0] + hexDigits[1];
output[1] = 16 * hexDigits[2] + hexDigits[3];
break;
}
case 4:
/* 0x???? -> \0?? \x?? */
output[0] = 16 * hexDigits[0] + hexDigits[1];
output[1] = 16 * hexDigits[2] + hexDigits[3];
break;
}
}
unsigned char uriGetOctetValue(const unsigned char * digits, int digitCount) {
switch (digitCount) {
case 1:
return digits[0];
switch (digitCount) {
case 1:
return digits[0];
case 2:
return 10 * digits[0] + digits[1];
case 2:
return 10 * digits[0] + digits[1];
case 3:
default:
return 100 * digits[0] + 10 * digits[1] + digits[2];
}
case 3:
default:
return 100 * digits[0] + 10 * digits[1] + digits[2];
}
}

View File

@@ -38,18 +38,12 @@
*/
#ifndef URI_PARSE_BASE_H
#define URI_PARSE_BASE_H 1
#include <uriparser/UriBase.h>
# define URI_PARSE_BASE_H 1
# include <uriparser/UriBase.h>
void uriWriteQuadToDoubleByte(const unsigned char * hexDigits, int digitCount,
unsigned char * output);
unsigned char * output);
unsigned char uriGetOctetValue(const unsigned char * digits, int digitCount);
#endif /* URI_PARSE_BASE_H */

View File

@@ -41,465 +41,427 @@
#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 "UriQuery.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriQuery.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriQuery.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriQuery.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"
#endif
#include <limits.h>
#include <stddef.h> /* size_t */
# 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"
# endif
# include <limits.h>
# include <stddef.h> /* size_t */
static int URI_FUNC(ComposeQueryEngine)(URI_CHAR * dest,
const URI_TYPE(QueryList) * queryList,
int maxChars, int * charsWritten, int * charsRequired,
UriBool spaceToPlus, UriBool normalizeBreaks);
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,
UriMemoryManager * memory);
const URI_TYPE(QueryList) * queryList,
int maxChars, int * charsWritten,
int * charsRequired, UriBool spaceToPlus,
UriBool normalizeBreaks);
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, UriMemoryManager * memory);
int URI_FUNC(ComposeQueryCharsRequired)(const URI_TYPE(QueryList) * queryList,
int * charsRequired) {
const UriBool spaceToPlus = URI_TRUE;
const UriBool normalizeBreaks = URI_TRUE;
int * charsRequired) {
const UriBool spaceToPlus = URI_TRUE;
const UriBool normalizeBreaks = URI_TRUE;
return URI_FUNC(ComposeQueryCharsRequiredEx)(queryList, charsRequired,
spaceToPlus, normalizeBreaks);
return URI_FUNC(ComposeQueryCharsRequiredEx)(queryList, charsRequired, spaceToPlus,
normalizeBreaks);
}
int URI_FUNC(ComposeQueryCharsRequiredEx)(const URI_TYPE(QueryList) * queryList,
int * charsRequired, UriBool spaceToPlus, UriBool normalizeBreaks) {
if ((queryList == NULL) || (charsRequired == NULL)) {
return URI_ERROR_NULL;
}
int * charsRequired, UriBool spaceToPlus,
UriBool normalizeBreaks) {
if ((queryList == NULL) || (charsRequired == NULL)) {
return URI_ERROR_NULL;
}
return URI_FUNC(ComposeQueryEngine)(NULL, queryList, 0, NULL,
charsRequired, spaceToPlus, normalizeBreaks);
return URI_FUNC(ComposeQueryEngine)(NULL, queryList, 0, NULL, charsRequired,
spaceToPlus, normalizeBreaks);
}
int URI_FUNC(ComposeQuery)(URI_CHAR * dest, const URI_TYPE(QueryList) * queryList,
int maxChars, int * charsWritten) {
const UriBool spaceToPlus = URI_TRUE;
const UriBool normalizeBreaks = URI_TRUE;
int URI_FUNC(ComposeQuery)(URI_CHAR * dest,
const URI_TYPE(QueryList) * queryList, int maxChars, int * charsWritten) {
const UriBool spaceToPlus = URI_TRUE;
const UriBool normalizeBreaks = URI_TRUE;
return URI_FUNC(ComposeQueryEx)(dest, queryList, maxChars, charsWritten,
spaceToPlus, normalizeBreaks);
return URI_FUNC(ComposeQueryEx)(dest, queryList, maxChars, charsWritten, spaceToPlus,
normalizeBreaks);
}
int URI_FUNC(ComposeQueryEx)(URI_CHAR * dest, const URI_TYPE(QueryList) * queryList,
int maxChars, int * charsWritten, UriBool spaceToPlus,
UriBool normalizeBreaks) {
if ((dest == NULL) || (queryList == NULL)) {
return URI_ERROR_NULL;
}
if (maxChars < 1) {
return URI_ERROR_OUTPUT_TOO_LARGE;
}
int URI_FUNC(ComposeQueryEx)(URI_CHAR * dest,
const URI_TYPE(QueryList) * queryList, int maxChars, int * charsWritten,
UriBool spaceToPlus, UriBool normalizeBreaks) {
if ((dest == NULL) || (queryList == NULL)) {
return URI_ERROR_NULL;
}
if (maxChars < 1) {
return URI_ERROR_OUTPUT_TOO_LARGE;
}
return URI_FUNC(ComposeQueryEngine)(dest, queryList, maxChars,
charsWritten, NULL, spaceToPlus, normalizeBreaks);
return URI_FUNC(ComposeQueryEngine)(dest, queryList, maxChars, charsWritten, NULL,
spaceToPlus, normalizeBreaks);
}
int URI_FUNC(ComposeQueryMalloc)(URI_CHAR ** dest,
const URI_TYPE(QueryList) * queryList) {
const UriBool spaceToPlus = URI_TRUE;
const UriBool normalizeBreaks = URI_TRUE;
const URI_TYPE(QueryList) * queryList) {
const UriBool spaceToPlus = URI_TRUE;
const UriBool normalizeBreaks = URI_TRUE;
return URI_FUNC(ComposeQueryMallocEx)(dest, queryList,
spaceToPlus, normalizeBreaks);
return URI_FUNC(ComposeQueryMallocEx)(dest, queryList, spaceToPlus, normalizeBreaks);
}
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);
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;
const URI_TYPE(QueryList) * queryList,
UriBool spaceToPlus, UriBool normalizeBreaks,
UriMemoryManager * memory) {
int charsRequired;
int res;
URI_CHAR * queryString;
if (dest == NULL) {
return URI_ERROR_NULL;
}
if (dest == NULL) {
return URI_ERROR_NULL;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
/* Calculate space */
res = URI_FUNC(ComposeQueryCharsRequiredEx)(queryList, &charsRequired,
spaceToPlus, normalizeBreaks);
if (res != URI_SUCCESS) {
return res;
}
if (charsRequired == INT_MAX) {
return URI_ERROR_MALLOC;
}
charsRequired++;
/* Calculate space */
res = URI_FUNC(ComposeQueryCharsRequiredEx)(queryList, &charsRequired, spaceToPlus,
normalizeBreaks);
if (res != URI_SUCCESS) {
return res;
}
if (charsRequired == INT_MAX) {
return URI_ERROR_MALLOC;
}
charsRequired++;
/* Allocate space */
queryString = memory->calloc(memory, charsRequired, sizeof(URI_CHAR));
if (queryString == NULL) {
return URI_ERROR_MALLOC;
}
/* Allocate space */
queryString = memory->calloc(memory, charsRequired, sizeof(URI_CHAR));
if (queryString == NULL) {
return URI_ERROR_MALLOC;
}
/* Put query in */
res = URI_FUNC(ComposeQueryEx)(queryString, queryList, charsRequired,
NULL, spaceToPlus, normalizeBreaks);
if (res != URI_SUCCESS) {
memory->free(memory, queryString);
return res;
}
/* Put query in */
res = URI_FUNC(ComposeQueryEx)(queryString, queryList, charsRequired, NULL,
spaceToPlus, normalizeBreaks);
if (res != URI_SUCCESS) {
memory->free(memory, queryString);
return res;
}
*dest = queryString;
return URI_SUCCESS;
*dest = queryString;
return URI_SUCCESS;
}
int URI_FUNC(ComposeQueryEngine)(URI_CHAR * dest, const URI_TYPE(QueryList) * queryList,
int maxChars, int * charsWritten, int * charsRequired,
UriBool spaceToPlus, UriBool normalizeBreaks) {
UriBool firstItem = URI_TRUE;
int ampersandLen = 0; /* increased to 1 from second item on */
URI_CHAR * write = dest;
/* Subtract terminator */
if (dest == NULL) {
*charsRequired = 0;
} else {
maxChars--;
}
int URI_FUNC(ComposeQueryEngine)(URI_CHAR * dest,
const URI_TYPE(QueryList) * queryList,
int maxChars, int * charsWritten, int * charsRequired,
UriBool spaceToPlus, UriBool normalizeBreaks) {
UriBool firstItem = URI_TRUE;
int ampersandLen = 0; /* increased to 1 from second item on */
URI_CHAR * write = dest;
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 size_t keyLen = (key == NULL) ? 0 : URI_STRLEN(key);
int keyRequiredChars;
const size_t valueLen = (value == NULL) ? 0 : URI_STRLEN(value);
int valueRequiredChars;
/* Subtract terminator */
if (dest == NULL) {
*charsRequired = 0;
} else {
maxChars--;
}
if ((keyLen >= (size_t)INT_MAX / worstCase)
|| (valueLen >= (size_t)INT_MAX / worstCase)) {
return URI_ERROR_OUTPUT_TOO_LARGE;
}
keyRequiredChars = worstCase * (int)keyLen;
valueRequiredChars = worstCase * (int)valueLen;
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 size_t keyLen = (key == NULL) ? 0 : URI_STRLEN(key);
int keyRequiredChars;
const size_t valueLen = (value == NULL) ? 0 : URI_STRLEN(value);
int valueRequiredChars;
if (dest == NULL) {
(*charsRequired) += ampersandLen + keyRequiredChars
+ ((value == NULL) ? 0 : 1 + valueRequiredChars);
if ((keyLen >= (size_t)INT_MAX / worstCase) || (valueLen >= (size_t)INT_MAX / worstCase)) {
return URI_ERROR_OUTPUT_TOO_LARGE;
}
keyRequiredChars = worstCase * (int)keyLen;
valueRequiredChars = worstCase * (int)valueLen;
if (firstItem == URI_TRUE) {
ampersandLen = 1;
firstItem = URI_FALSE;
}
} else {
if ((write - dest) + ampersandLen + keyRequiredChars > maxChars) {
return URI_ERROR_OUTPUT_TOO_LARGE;
}
if (dest == NULL) {
(*charsRequired) += ampersandLen + keyRequiredChars + ((value == NULL)
? 0
: 1 + valueRequiredChars);
/* Copy key */
if (firstItem == URI_TRUE) {
ampersandLen = 1;
firstItem = URI_FALSE;
} else {
write[0] = _UT('&');
write++;
}
write = URI_FUNC(EscapeEx)(key, key + keyLen, write, spaceToPlus,
normalizeBreaks);
if (firstItem == URI_TRUE) {
ampersandLen = 1;
firstItem = URI_FALSE;
}
} else {
if ((write - dest) + ampersandLen + keyRequiredChars > maxChars) {
return URI_ERROR_OUTPUT_TOO_LARGE;
}
if (value != NULL) {
if ((write - dest) + 1 + valueRequiredChars > maxChars) {
return URI_ERROR_OUTPUT_TOO_LARGE;
}
/* Copy key */
if (firstItem == URI_TRUE) {
ampersandLen = 1;
firstItem = URI_FALSE;
} else {
write[0] = _UT('&');
write++;
}
write = URI_FUNC(EscapeEx)(key, key + keyLen,
write, spaceToPlus, normalizeBreaks);
/* Copy value */
write[0] = _UT('=');
write++;
write = URI_FUNC(EscapeEx)(value, value + valueLen, write, spaceToPlus,
normalizeBreaks);
}
}
if (value != NULL) {
if ((write - dest) + 1 + valueRequiredChars > maxChars) {
return URI_ERROR_OUTPUT_TOO_LARGE;
}
queryList = queryList->next;
}
/* Copy value */
write[0] = _UT('=');
write++;
write = URI_FUNC(EscapeEx)(value, value + valueLen,
write, spaceToPlus, normalizeBreaks);
}
}
if (dest != NULL) {
write[0] = _UT('\0');
if (charsWritten != NULL) {
*charsWritten = (int)(write - dest) + 1; /* .. for terminator */
}
}
queryList = queryList->next;
}
if (dest != NULL) {
write[0] = _UT('\0');
if (charsWritten != NULL) {
*charsWritten = (int)(write - dest) + 1; /* .. for terminator */
}
}
return URI_SUCCESS;
return URI_SUCCESS;
}
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,
UriMemoryManager * memory) {
const int keyLen = (int)(keyAfter - keyFirst);
const int valueLen = (int)(valueAfter - valueFirst);
URI_CHAR * key;
URI_CHAR * value;
if ((prevNext == NULL) || (itemCount == NULL) || (keyFirst == NULL)
|| (keyAfter == NULL) || (keyFirst > keyAfter) || (valueFirst > valueAfter)
|| ((keyFirst == keyAfter) && (valueFirst == NULL) && (valueAfter == NULL))) {
return URI_TRUE;
}
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,
UriMemoryManager * memory) {
const int keyLen = (int)(keyAfter - keyFirst);
const int valueLen = (int)(valueAfter - valueFirst);
URI_CHAR * key;
URI_CHAR * value;
/* Append new empty item */
*prevNext = memory->malloc(memory, 1 * sizeof(URI_TYPE(QueryList)));
if (*prevNext == NULL) {
return URI_FALSE; /* Raises malloc error */
}
(*prevNext)->next = NULL;
if ((prevNext == NULL) || (itemCount == NULL)
|| (keyFirst == NULL) || (keyAfter == NULL)
|| (keyFirst > keyAfter) || (valueFirst > valueAfter)
|| ((keyFirst == keyAfter)
&& (valueFirst == NULL) && (valueAfter == NULL))) {
return URI_TRUE;
}
/* Fill key */
key = memory->malloc(memory, (keyLen + 1) * sizeof(URI_CHAR));
if (key == NULL) {
memory->free(memory, *prevNext);
*prevNext = NULL;
return URI_FALSE; /* Raises malloc error */
}
/* Append new empty item */
*prevNext = memory->malloc(memory, 1 * sizeof(URI_TYPE(QueryList)));
if (*prevNext == NULL) {
return URI_FALSE; /* Raises malloc error */
}
(*prevNext)->next = NULL;
key[keyLen] = _UT('\0');
if (keyLen > 0) {
/* Copy 1:1 */
memcpy(key, keyFirst, keyLen * sizeof(URI_CHAR));
/* Unescape */
URI_FUNC(UnescapeInPlaceEx)(key, plusToSpace, breakConversion);
}
(*prevNext)->key = key;
/* Fill key */
key = memory->malloc(memory, (keyLen + 1) * sizeof(URI_CHAR));
if (key == NULL) {
memory->free(memory, *prevNext);
*prevNext = NULL;
return URI_FALSE; /* Raises malloc error */
}
/* Fill value */
if (valueFirst != NULL) {
value = memory->malloc(memory, (valueLen + 1) * sizeof(URI_CHAR));
if (value == NULL) {
memory->free(memory, key);
memory->free(memory, *prevNext);
*prevNext = NULL;
return URI_FALSE; /* Raises malloc error */
}
key[keyLen] = _UT('\0');
if (keyLen > 0) {
/* Copy 1:1 */
memcpy(key, keyFirst, keyLen * sizeof(URI_CHAR));
value[valueLen] = _UT('\0');
if (valueLen > 0) {
/* Copy 1:1 */
memcpy(value, valueFirst, valueLen * sizeof(URI_CHAR));
/* Unescape */
URI_FUNC(UnescapeInPlaceEx)(key, plusToSpace, breakConversion);
}
(*prevNext)->key = key;
/* Unescape */
URI_FUNC(UnescapeInPlaceEx)(value, plusToSpace, breakConversion);
}
(*prevNext)->value = value;
} else {
value = NULL;
}
(*prevNext)->value = value;
/* Fill value */
if (valueFirst != NULL) {
value = memory->malloc(memory, (valueLen + 1) * sizeof(URI_CHAR));
if (value == NULL) {
memory->free(memory, key);
memory->free(memory, *prevNext);
*prevNext = NULL;
return URI_FALSE; /* Raises malloc error */
}
value[valueLen] = _UT('\0');
if (valueLen > 0) {
/* Copy 1:1 */
memcpy(value, valueFirst, valueLen * sizeof(URI_CHAR));
/* Unescape */
URI_FUNC(UnescapeInPlaceEx)(value, plusToSpace, breakConversion);
}
(*prevNext)->value = value;
} else {
value = NULL;
}
(*prevNext)->value = value;
(*itemCount)++;
return URI_TRUE;
(*itemCount)++;
return URI_TRUE;
}
void URI_FUNC(FreeQueryList)(URI_TYPE(QueryList) * queryList) {
URI_FUNC(FreeQueryListMm)(queryList, NULL);
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;
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;
UriMemoryManager * memory) {
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
while (queryList != NULL) {
URI_TYPE(QueryList) * nextBackup = queryList->next;
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;
}
int URI_FUNC(DissectQueryMalloc)(URI_TYPE(QueryList) * *dest, int * itemCount,
const URI_CHAR * first, const URI_CHAR * afterLast) {
const UriBool plusToSpace = URI_TRUE;
const UriBreakConversion breakConversion = URI_BR_DONT_TOUCH;
int URI_FUNC(DissectQueryMalloc)(URI_TYPE(QueryList) ** dest, int * itemCount,
const URI_CHAR * first, const URI_CHAR * afterLast) {
const UriBool plusToSpace = URI_TRUE;
const UriBreakConversion breakConversion = URI_BR_DONT_TOUCH;
return URI_FUNC(DissectQueryMallocEx)(dest, itemCount, first, afterLast,
plusToSpace, breakConversion);
return URI_FUNC(DissectQueryMallocEx)(dest, itemCount, first, afterLast, plusToSpace,
breakConversion);
}
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(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;
const URI_CHAR * valueFirst = NULL;
const URI_CHAR * valueAfter = NULL;
URI_TYPE(QueryList) ** prevNext = dest;
int nullCounter;
int * itemsAppended = (itemCount == NULL) ? &nullCounter : itemCount;
if ((dest == NULL) || (first == NULL) || (afterLast == NULL)) {
return URI_ERROR_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;
const URI_CHAR * valueFirst = NULL;
const URI_CHAR * valueAfter = NULL;
URI_TYPE(QueryList) ** prevNext = dest;
int nullCounter;
int * itemsAppended = (itemCount == NULL) ? &nullCounter : itemCount;
if (first > afterLast) {
return URI_ERROR_RANGE_INVALID;
}
if ((dest == NULL) || (first == NULL) || (afterLast == NULL)) {
return URI_ERROR_NULL;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
if (first > afterLast) {
return URI_ERROR_RANGE_INVALID;
}
*dest = NULL;
*itemsAppended = 0;
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
/* Parse query string */
for (; walk < afterLast; walk++) {
switch (*walk) {
case _UT('&'):
if (valueFirst != NULL) {
valueAfter = walk;
} else {
keyAfter = walk;
}
*dest = NULL;
*itemsAppended = 0;
if (URI_FUNC(AppendQueryItem)(prevNext, itemsAppended, keyFirst, keyAfter,
valueFirst, valueAfter, plusToSpace,
breakConversion, memory)
== URI_FALSE) {
/* Free list we built */
*itemsAppended = 0;
URI_FUNC(FreeQueryListMm)(*dest, memory);
return URI_ERROR_MALLOC;
}
/* Parse query string */
for (; walk < afterLast; walk++) {
switch (*walk) {
case _UT('&'):
if (valueFirst != NULL) {
valueAfter = walk;
} else {
keyAfter = walk;
}
/* Make future items children of the current */
if ((prevNext != NULL) && (*prevNext != NULL)) {
prevNext = &((*prevNext)->next);
}
if (URI_FUNC(AppendQueryItem)(prevNext, itemsAppended,
keyFirst, keyAfter, valueFirst, valueAfter,
plusToSpace, breakConversion, memory)
== URI_FALSE) {
/* Free list we built */
*itemsAppended = 0;
URI_FUNC(FreeQueryListMm)(*dest, memory);
return URI_ERROR_MALLOC;
}
if (walk + 1 < afterLast) {
keyFirst = walk + 1;
} else {
keyFirst = NULL;
}
keyAfter = NULL;
valueFirst = NULL;
valueAfter = NULL;
break;
/* Make future items children of the current */
if ((prevNext != NULL) && (*prevNext != NULL)) {
prevNext = &((*prevNext)->next);
}
case _UT('='):
/* NOTE: WE treat the first '=' as a separator, */
/* all following go into the value part */
if (keyAfter == NULL) {
keyAfter = walk;
if (walk + 1 <= afterLast) {
valueFirst = walk + 1;
valueAfter = walk + 1;
}
}
break;
if (walk + 1 < afterLast) {
keyFirst = walk + 1;
} else {
keyFirst = NULL;
}
keyAfter = NULL;
valueFirst = NULL;
valueAfter = NULL;
break;
default:
break;
}
}
case _UT('='):
/* NOTE: WE treat the first '=' as a separator, */
/* all following go into the value part */
if (keyAfter == NULL) {
keyAfter = walk;
if (walk + 1 <= afterLast) {
valueFirst = walk + 1;
valueAfter = walk + 1;
}
}
break;
if (valueFirst != NULL) {
/* Must be key/value pair */
valueAfter = walk;
} else {
/* Must be key only */
keyAfter = walk;
}
default:
break;
}
}
if (URI_FUNC(AppendQueryItem)(prevNext, itemsAppended, keyFirst, keyAfter, valueFirst,
valueAfter, plusToSpace, breakConversion, memory)
== URI_FALSE) {
/* Free list we built */
*itemsAppended = 0;
URI_FUNC(FreeQueryListMm)(*dest, memory);
return URI_ERROR_MALLOC;
}
if (valueFirst != NULL) {
/* Must be key/value pair */
valueAfter = walk;
} else {
/* Must be key only */
keyAfter = walk;
}
if (URI_FUNC(AppendQueryItem)(prevNext, itemsAppended, keyFirst, keyAfter,
valueFirst, valueAfter, plusToSpace, breakConversion, memory)
== URI_FALSE) {
/* Free list we built */
*itemsAppended = 0;
URI_FUNC(FreeQueryListMm)(*dest, memory);
return URI_ERROR_MALLOC;
}
return URI_SUCCESS;
return URI_SUCCESS;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -41,289 +41,358 @@
#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 "UriResolve.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriResolve.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriResolve.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriResolve.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"
#endif
# 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"
# endif
/* 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, UriMemoryManager * memory) {
URI_TYPE(PathSegment) * sourceWalker;
URI_TYPE(PathSegment) * destPrev;
if (relAppend->pathHead == NULL) {
return URI_TRUE;
}
const URI_TYPE(Uri) * relAppend,
UriMemoryManager * memory) {
URI_TYPE(PathSegment) * sourceWalker;
URI_TYPE(PathSegment) * destPrev;
if (relAppend->pathHead == NULL) {
return URI_TRUE;
}
/* Replace last segment ("" if trailing slash) with first of append chain */
if (absWork->pathHead == NULL) {
URI_TYPE(PathSegment) * const dup = memory->malloc(memory, sizeof(URI_TYPE(PathSegment)));
if (dup == NULL) {
return URI_FALSE; /* Raises malloc error */
}
dup->next = NULL;
absWork->pathHead = dup;
absWork->pathTail = dup;
}
absWork->pathTail->text.first = relAppend->pathHead->text.first;
absWork->pathTail->text.afterLast = relAppend->pathHead->text.afterLast;
/* Replace last segment ("" if trailing slash) with first of append chain */
if (absWork->pathHead == NULL) {
URI_TYPE(PathSegment) * const dup =
memory->malloc(memory, sizeof(URI_TYPE(PathSegment)));
if (dup == NULL) {
return URI_FALSE; /* Raises malloc error */
}
dup->next = NULL;
absWork->pathHead = dup;
absWork->pathTail = dup;
}
absWork->pathTail->text.first = relAppend->pathHead->text.first;
absWork->pathTail->text.afterLast = relAppend->pathHead->text.afterLast;
/* Append all the others */
sourceWalker = relAppend->pathHead->next;
if (sourceWalker == NULL) {
return URI_TRUE;
}
destPrev = absWork->pathTail;
/* Append all the others */
sourceWalker = relAppend->pathHead->next;
if (sourceWalker == NULL) {
return URI_TRUE;
}
destPrev = absWork->pathTail;
for (;;) {
URI_TYPE(PathSegment) * const dup = memory->malloc(memory, sizeof(URI_TYPE(PathSegment)));
if (dup == NULL) {
destPrev->next = NULL;
absWork->pathTail = destPrev;
return URI_FALSE; /* Raises malloc error */
}
dup->text = sourceWalker->text;
destPrev->next = dup;
for (;;) {
URI_TYPE(PathSegment) * const dup =
memory->malloc(memory, sizeof(URI_TYPE(PathSegment)));
if (dup == NULL) {
destPrev->next = NULL;
absWork->pathTail = destPrev;
return URI_FALSE; /* Raises malloc error */
}
dup->text = sourceWalker->text;
destPrev->next = dup;
if (sourceWalker->next == NULL) {
absWork->pathTail = dup;
absWork->pathTail->next = NULL;
break;
}
destPrev = dup;
sourceWalker = sourceWalker->next;
}
if (sourceWalker->next == NULL) {
absWork->pathTail = dup;
absWork->pathTail->next = NULL;
break;
}
destPrev = dup;
sourceWalker = sourceWalker->next;
}
return URI_TRUE;
return URI_TRUE;
}
static int URI_FUNC(ResolveAbsolutePathFlag)(URI_TYPE(Uri) * absWork,
UriMemoryManager * memory) {
if (absWork == NULL) {
return URI_ERROR_NULL;
}
UriMemoryManager * memory) {
if (absWork == NULL) {
return URI_ERROR_NULL;
}
if (URI_FUNC(HasHost)(absWork) && absWork->absolutePath) {
/* Empty segment needed, instead? */
if (absWork->pathHead == NULL) {
URI_TYPE(PathSegment) * const segment = memory->malloc(memory, sizeof(URI_TYPE(PathSegment)));
if (segment == NULL) {
return URI_ERROR_MALLOC;
}
segment->text.first = URI_FUNC(SafeToPointTo);
segment->text.afterLast = URI_FUNC(SafeToPointTo);
segment->next = NULL;
if (URI_FUNC(HasHost)(absWork) && absWork->absolutePath) {
/* Empty segment needed, instead? */
if (absWork->pathHead == NULL) {
URI_TYPE(PathSegment) * const segment =
memory->malloc(memory, sizeof(URI_TYPE(PathSegment)));
if (segment == NULL) {
return URI_ERROR_MALLOC;
}
segment->text.first = URI_FUNC(SafeToPointTo);
segment->text.afterLast = URI_FUNC(SafeToPointTo);
segment->next = NULL;
absWork->pathHead = segment;
absWork->pathTail = segment;
}
absWork->pathHead = segment;
absWork->pathTail = segment;
}
absWork->absolutePath = URI_FALSE;
}
absWork->absolutePath = URI_FALSE;
}
return URI_SUCCESS;
return URI_SUCCESS;
}
static int URI_FUNC(AddBaseUriImpl)(URI_TYPE(Uri) * absDest,
const URI_TYPE(Uri) * relSource,
const URI_TYPE(Uri) * absBase,
UriResolutionOptions options, UriMemoryManager * memory) {
UriBool relSourceHasScheme;
const URI_TYPE(Uri) * relSource,
const URI_TYPE(Uri) * absBase,
UriResolutionOptions options,
UriMemoryManager * memory) {
UriBool relSourceHasScheme;
if (absDest == NULL) {
return URI_ERROR_NULL;
}
URI_FUNC(ResetUri)(absDest);
if (absDest == NULL) {
return URI_ERROR_NULL;
}
URI_FUNC(ResetUri)(absDest);
if ((relSource == NULL) || (absBase == NULL)) {
return URI_ERROR_NULL;
}
if ((relSource == NULL) || (absBase == NULL)) {
return URI_ERROR_NULL;
}
/* absBase absolute? */
if (absBase->scheme.first == NULL) {
return URI_ERROR_ADDBASE_REL_BASE;
}
/* absBase absolute? */
if (absBase->scheme.first == NULL) {
return URI_ERROR_ADDBASE_REL_BASE;
}
/* [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 */
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)))) {
/* [00/32] undefine(R.scheme); */
relSourceHasScheme = URI_FALSE;
/* [00/32] endif; */
}
/* 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 */
}
/* [01/32] if defined(R.scheme) then */
if (relSourceHasScheme) {
/* [02/32] T.scheme = R.scheme; */
absDest->scheme = relSource->scheme;
/* [03/32] T.authority = R.authority; */
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, memory)) {
return URI_ERROR_MALLOC;
}
if (!URI_FUNC(RemoveDotSegmentsAbsolute)(absDest, memory)) {
return URI_ERROR_MALLOC;
}
/* [05/32] T.query = R.query; */
absDest->query = relSource->query;
/* [06/32] else */
} else {
/* [07/32] if defined(R.authority) then */
if (URI_FUNC(HasHost)(relSource)) {
/* [08/32] T.authority = R.authority; */
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, memory)) {
return URI_ERROR_MALLOC;
}
if (!URI_FUNC(RemoveDotSegmentsAbsolute)(absDest, memory)) {
return URI_ERROR_MALLOC;
}
/* [10/32] T.query = R.query; */
absDest->query = relSource->query;
/* [11/32] else */
} else {
/* [28/32] T.authority = Base.authority; */
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, memory)) {
return URI_ERROR_MALLOC;
}
/* [14/32] if defined(R.query) then */
if (relSource->query.first != NULL) {
/* [15/32] T.query = R.query; */
absDest->query = relSource->query;
/* [16/32] else */
} else {
/* [17/32] T.query = Base.query; */
absDest->query = absBase->query;
/* [18/32] endif; */
}
/* [19/32] else */
} else {
/* [20/32] if (R.path starts-with "/") then */
if (relSource->absolutePath) {
int res;
/* [21/32] T.path = remove_dot_segments(R.path); */
if (!URI_FUNC(CopyPath)(absDest, relSource, memory)) {
return URI_ERROR_MALLOC;
}
res = URI_FUNC(ResolveAbsolutePathFlag)(absDest, memory);
if (res != URI_SUCCESS) {
return res;
}
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, memory)) {
return URI_ERROR_MALLOC;
}
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, memory)) {
return URI_ERROR_MALLOC;
}
if (!URI_FUNC(FixAmbiguity)(absDest, memory)) {
return URI_ERROR_MALLOC;
}
/* [25/32] endif; */
}
/* [26/32] T.query = R.query; */
absDest->query = relSource->query;
/* [27/32] endif; */
}
URI_FUNC(FixEmptyTrailSegment)(absDest, memory);
/* [29/32] endif; */
}
/* [30/32] T.scheme = Base.scheme; */
absDest->scheme = absBase->scheme;
/* [31/32] endif; */
}
/* [32/32] T.fragment = R.fragment; */
absDest->fragment = relSource->fragment;
return URI_SUCCESS;
/* 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;
}
res = URI_FUNC(ResolveAbsolutePathFlag)(absDest, memory);
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;
}
int URI_FUNC(AddBaseUri)(URI_TYPE(Uri) * absDest,
const URI_TYPE(Uri) * relSource, const URI_TYPE(Uri) * absBase) {
const UriResolutionOptions options = URI_RESOLVE_STRICTLY;
return URI_FUNC(AddBaseUriEx)(absDest, relSource, absBase, options);
int URI_FUNC(AddBaseUri)(URI_TYPE(Uri) * absDest, const URI_TYPE(Uri) * relSource,
const URI_TYPE(Uri) * absBase) {
const UriResolutionOptions options = URI_RESOLVE_STRICTLY;
return URI_FUNC(AddBaseUriEx)(absDest, relSource, absBase, options);
}
int URI_FUNC(AddBaseUriEx)(URI_TYPE(Uri) * absDest,
const URI_TYPE(Uri) * relSource, const URI_TYPE(Uri) * absBase,
UriResolutionOptions options) {
return URI_FUNC(AddBaseUriExMm)(absDest, relSource, absBase, options, NULL);
int URI_FUNC(AddBaseUriEx)(URI_TYPE(Uri) * absDest, const URI_TYPE(Uri) * relSource,
const URI_TYPE(Uri) * absBase, UriResolutionOptions 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 */
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(FreeUriMembersMm)(absDest, memory);
}
return res;
res = URI_FUNC(AddBaseUriImpl)(absDest, relSource, absBase, options, memory);
if ((res != URI_SUCCESS) && (absDest != NULL)) {
URI_FUNC(FreeUriMembersMm)(absDest, memory);
}
return res;
}
#endif

View File

@@ -40,267 +40,234 @@
#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 "UriSetFragment.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetFragment.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriSetFragment.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetFragment.c"
# undef URI_PASS_UNICODE
# endif
#else
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# include <wchar.h>
# endif
# 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"
# endif
# include <assert.h>
#ifndef URI_DOXYGEN
# include <uriparser/Uri.h>
# include "UriCommon.h"
# include "UriMemory.h"
#endif
# define URI_SET_DIGIT \
_UT('0') : case _UT('1'): \
case _UT('2'): \
case _UT('3'): \
case _UT('4'): \
case _UT('5'): \
case _UT('6'): \
case _UT('7'): \
case _UT('8'): \
case _UT('9')
# define URI_SET_HEX_LETTER_UPPER \
_UT('A') : case _UT('B'): \
case _UT('C'): \
case _UT('D'): \
case _UT('E'): \
case _UT('F')
# define URI_SET_HEX_LETTER_LOWER \
_UT('a') : case _UT('b'): \
case _UT('c'): \
case _UT('d'): \
case _UT('e'): \
case _UT('f')
#include <assert.h>
# define URI_SET_HEXDIG \
URI_SET_DIGIT: \
case URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER
# define URI_SET_ALPHA \
URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER: \
case _UT('g'): \
case _UT('G'): \
case _UT('h'): \
case _UT('H'): \
case _UT('i'): \
case _UT('I'): \
case _UT('j'): \
case _UT('J'): \
case _UT('k'): \
case _UT('K'): \
case _UT('l'): \
case _UT('L'): \
case _UT('m'): \
case _UT('M'): \
case _UT('n'): \
case _UT('N'): \
case _UT('o'): \
case _UT('O'): \
case _UT('p'): \
case _UT('P'): \
case _UT('q'): \
case _UT('Q'): \
case _UT('r'): \
case _UT('R'): \
case _UT('s'): \
case _UT('S'): \
case _UT('t'): \
case _UT('T'): \
case _UT('u'): \
case _UT('U'): \
case _UT('v'): \
case _UT('V'): \
case _UT('w'): \
case _UT('W'): \
case _UT('x'): \
case _UT('X'): \
case _UT('y'): \
case _UT('Y'): \
case _UT('z'): \
case _UT('Z')
# define URI_SET_SUB_DELIMS \
_UT('!') : case _UT('$'): \
case _UT('&'): \
case _UT('\''): \
case _UT('('): \
case _UT(')'): \
case _UT('*'): \
case _UT('+'): \
case _UT(','): \
case _UT(';'): \
case _UT('=')
#define URI_SET_DIGIT \
_UT('0'): \
case _UT('1'): \
case _UT('2'): \
case _UT('3'): \
case _UT('4'): \
case _UT('5'): \
case _UT('6'): \
case _UT('7'): \
case _UT('8'): \
case _UT('9')
# define URI_SET_UNRESERVED \
URI_SET_ALPHA: \
case URI_SET_DIGIT: \
case _UT('-'): \
case _UT('.'): \
case _UT('_'): \
case _UT('~')
UriBool URI_FUNC(IsWellFormedFragment)(const URI_CHAR * first,
const URI_CHAR * afterLast) {
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
}
/* The related part of the grammar in RFC 3986 reads:
*
* fragment = *( pchar / "/" / "?" )
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
*/
while (first < afterLast) {
switch (first[0]) {
case URI_SET_UNRESERVED:
break;
#define URI_SET_HEX_LETTER_UPPER \
_UT('A'): \
case _UT('B'): \
case _UT('C'): \
case _UT('D'): \
case _UT('E'): \
case _UT('F')
/* pct-encoded */
case _UT('%'):
if (afterLast - first < 3) {
return URI_FALSE;
}
switch (first[1]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
switch (first[2]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
first += 2;
break;
case URI_SET_SUB_DELIMS:
break;
/* ":" / "@" and "/" / "?" */
case _UT(':'):
case _UT('@'):
case _UT('/'):
case _UT('?'):
break;
#define URI_SET_HEX_LETTER_LOWER \
_UT('a'): \
case _UT('b'): \
case _UT('c'): \
case _UT('d'): \
case _UT('e'): \
case _UT('f')
default:
return URI_FALSE;
}
#define URI_SET_HEXDIG \
URI_SET_DIGIT: \
case URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER
#define URI_SET_ALPHA \
URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER: \
case _UT('g'): \
case _UT('G'): \
case _UT('h'): \
case _UT('H'): \
case _UT('i'): \
case _UT('I'): \
case _UT('j'): \
case _UT('J'): \
case _UT('k'): \
case _UT('K'): \
case _UT('l'): \
case _UT('L'): \
case _UT('m'): \
case _UT('M'): \
case _UT('n'): \
case _UT('N'): \
case _UT('o'): \
case _UT('O'): \
case _UT('p'): \
case _UT('P'): \
case _UT('q'): \
case _UT('Q'): \
case _UT('r'): \
case _UT('R'): \
case _UT('s'): \
case _UT('S'): \
case _UT('t'): \
case _UT('T'): \
case _UT('u'): \
case _UT('U'): \
case _UT('v'): \
case _UT('V'): \
case _UT('w'): \
case _UT('W'): \
case _UT('x'): \
case _UT('X'): \
case _UT('y'): \
case _UT('Y'): \
case _UT('z'): \
case _UT('Z')
#define URI_SET_SUB_DELIMS \
_UT('!'): \
case _UT('$'): \
case _UT('&'): \
case _UT('\''): \
case _UT('('): \
case _UT(')'): \
case _UT('*'): \
case _UT('+'): \
case _UT(','): \
case _UT(';'): \
case _UT('=')
#define URI_SET_UNRESERVED \
URI_SET_ALPHA: \
case URI_SET_DIGIT: \
case _UT('-'): \
case _UT('.'): \
case _UT('_'): \
case _UT('~')
UriBool URI_FUNC(IsWellFormedFragment)(const URI_CHAR * first, const URI_CHAR * afterLast) {
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
}
/* The related part of the grammar in RFC 3986 reads:
*
* fragment = *( pchar / "/" / "?" )
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
*/
while (first < afterLast) {
switch (first[0]) {
case URI_SET_UNRESERVED:
break;
/* pct-encoded */
case _UT('%'):
if (afterLast - first < 3) {
return URI_FALSE;
}
switch (first[1]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
switch (first[2]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
first += 2;
break;
case URI_SET_SUB_DELIMS:
break;
/* ":" / "@" and "/" / "?" */
case _UT(':'):
case _UT('@'):
case _UT('/'):
case _UT('?'):
break;
default:
return URI_FALSE;
}
first++;
}
return URI_TRUE;
first++;
}
return URI_TRUE;
}
int URI_FUNC(SetFragmentMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast, UriMemoryManager * memory) {
/* Input validation (before making any changes) */
if ((uri == NULL) || ((first == NULL) != (afterLast == NULL))) {
return URI_ERROR_NULL;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
int URI_FUNC(SetFragmentMm)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
/* Input validation (before making any changes) */
if ((uri == NULL) || ((first == NULL) != (afterLast == NULL))) {
return URI_ERROR_NULL;
}
if ((first != NULL)
&& (URI_FUNC(IsWellFormedFragment)(first, afterLast) == URI_FALSE)) {
return URI_ERROR_SYNTAX;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
/* Clear old value */
if ((uri->owner == URI_TRUE) && (uri->fragment.first != uri->fragment.afterLast)) {
memory->free(memory, (URI_CHAR *)uri->fragment.first);
}
uri->fragment.first = NULL;
uri->fragment.afterLast = NULL;
if ((first != NULL) && (URI_FUNC(IsWellFormedFragment)(first, afterLast) == URI_FALSE)) {
return URI_ERROR_SYNTAX;
}
/* Already done? */
if (first == NULL) {
return URI_SUCCESS;
}
/* Clear old value */
if ((uri->owner == URI_TRUE) && (uri->fragment.first != uri->fragment.afterLast)) {
memory->free(memory, (URI_CHAR *)uri->fragment.first);
}
uri->fragment.first = NULL;
uri->fragment.afterLast = NULL;
assert(first != NULL);
/* Already done? */
if (first == NULL) {
return URI_SUCCESS;
}
/* Ensure owned */
if (uri->owner == URI_FALSE) {
const int res = URI_FUNC(MakeOwnerMm)(uri, memory);
if (res != URI_SUCCESS) {
return res;
}
}
assert(first != NULL);
assert(uri->owner == URI_TRUE);
/* Ensure owned */
if (uri->owner == URI_FALSE) {
const int res = URI_FUNC(MakeOwnerMm)(uri, memory);
if (res != URI_SUCCESS) {
return res;
}
}
/* Apply new value */
URI_TYPE(TextRange) sourceRange;
sourceRange.first = first;
sourceRange.afterLast = afterLast;
assert(uri->owner == URI_TRUE);
if (URI_FUNC(CopyRangeAsNeeded)(&uri->fragment, &sourceRange, memory) == URI_FALSE) {
return URI_ERROR_MALLOC;
}
/* 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;
return URI_SUCCESS;
}
int URI_FUNC(SetFragment)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetFragmentMm)(uri, first, afterLast, NULL);
int URI_FUNC(SetFragment)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetFragmentMm)(uri, first, afterLast, NULL);
}
#endif

View File

@@ -40,100 +40,85 @@
#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 "UriSetHostAuto.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetHostAuto.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriSetHostAuto.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetHostAuto.c"
# undef URI_PASS_UNICODE
# endif
#else
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# include <wchar.h>
# endif
# 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 "UriSetHostBase.h"
# include "UriSetHostCommon.h"
# include "UriMemory.h"
# endif
# include <assert.h>
#ifndef URI_DOXYGEN
# include <uriparser/Uri.h>
# include "UriSetHostBase.h"
# include "UriSetHostCommon.h"
# include "UriMemory.h"
#endif
int URI_FUNC(SetHostAutoMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast, UriMemoryManager * memory) {
if ((uri == NULL) || ((first == NULL) != (afterLast == NULL))) {
return URI_ERROR_NULL;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
if ((first == NULL) || (first >= afterLast)) {
return URI_FUNC(SetHostRegNameMm)(uri, first, afterLast, memory);
}
#include <assert.h>
/* Auto-detect type and then apply */
UriHostType hostType;
/* IPv6 or IPvFuture? */
if (first[0] == _UT('[')) {
if ((afterLast - first < 2) || (afterLast[-1] != _UT(']'))) {
return URI_ERROR_SYNTAX;
}
/* Drop the bracket wrap (for InternalSetHostMm call below) */
first++;
afterLast--;
int URI_FUNC(SetHostAutoMm)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
if ((uri == NULL) || ((first == NULL) != (afterLast == NULL))) {
return URI_ERROR_NULL;
}
if (first >= afterLast) {
return URI_ERROR_SYNTAX;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
switch (first[0]) {
case _UT('v'):
case _UT('V'):
hostType = URI_HOST_TYPE_IPFUTURE;
break;
default:
hostType = URI_HOST_TYPE_IP6;
break;
}
/* IPv4? */
} else if (URI_FUNC(IsWellFormedHostIp4)(first, afterLast)) {
hostType = URI_HOST_TYPE_IP4;
} else {
/* RegName! */
hostType = URI_HOST_TYPE_REGNAME;
}
if ((first == NULL) || (first >= afterLast)) {
return URI_FUNC(SetHostRegNameMm)(uri, first, afterLast, memory);
}
/* Auto-detect type and then apply */
{
UriHostType hostType;
/* IPv6 or IPvFuture? */
if (first[0] == _UT('[')) {
if ((afterLast - first < 2) || (afterLast[-1] != _UT(']'))) {
return URI_ERROR_SYNTAX;
}
/* Drop the bracket wrap (for InternalSetHostMm call below) */
first++;
afterLast--;
if (first >= afterLast) {
return URI_ERROR_SYNTAX;
}
switch (first[0]) {
case _UT('v'):
case _UT('V'):
hostType = URI_HOST_TYPE_IPFUTURE;
break;
default:
hostType = URI_HOST_TYPE_IP6;
break;
}
/* IPv4? */
} else if (URI_FUNC(IsWellFormedHostIp4)(first, afterLast)) {
hostType = URI_HOST_TYPE_IP4;
} else {
/* RegName! */
hostType = URI_HOST_TYPE_REGNAME;
}
return URI_FUNC(InternalSetHostMm)(uri, hostType, first, afterLast, memory);
}
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) {
return URI_FUNC(SetHostAutoMm)(uri, first, afterLast, NULL);
int URI_FUNC(SetHostAuto)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetHostAutoMm)(uri, first, afterLast, NULL);
}
#endif

View File

@@ -37,9 +37,7 @@
*/
#ifndef URI_SET_HOST_BASE_H
#define URI_SET_HOST_BASE_H 1
# define URI_SET_HOST_BASE_H 1
typedef enum UriHostTypeEnum {
URI_HOST_TYPE_IP4,
@@ -48,6 +46,4 @@ typedef enum UriHostTypeEnum {
URI_HOST_TYPE_REGNAME
} UriHostType;
#endif /* URI_SET_HOST_BASE_H */

View File

@@ -46,221 +46,203 @@
#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 "UriSetHostCommon.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetHostCommon.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriSetHostCommon.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetHostCommon.c"
# undef URI_PASS_UNICODE
# endif
#else
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# include <wchar.h>
# endif
# 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 <uriparser/UriIp4.h>
# include "UriCommon.h"
# include "UriMemory.h"
# include "UriSetHostBase.h"
# include "UriSetHostCommon.h"
# endif
# include <assert.h>
#ifndef URI_DOXYGEN
# include <uriparser/Uri.h>
# include <uriparser/UriIp4.h>
# include "UriCommon.h"
# include "UriMemory.h"
# include "UriSetHostBase.h"
# include "UriSetHostCommon.h"
#endif
int URI_FUNC(InternalSetHostMm)(URI_TYPE(Uri) * uri, UriHostType hostType,
const URI_CHAR * first, const URI_CHAR * afterLast,
UriMemoryManager * memory) {
/* Superficial input validation (before making any changes) */
if ((uri == NULL) || ((first == NULL) != (afterLast == NULL))) {
return URI_ERROR_NULL;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
/* The RFC 3986 grammar reads:
* authority = [ userinfo "@" ] host [ ":" port ]
* So no user info or port without a host. */
if (first == NULL) {
if (uri->userInfo.first != NULL) {
return URI_ERROR_SETHOST_USERINFO_SET;
} else if (uri->portText.first != NULL) {
return URI_ERROR_SETHOST_PORT_SET;
}
}
#include <assert.h>
/* Syntax-check the new value */
if (first != NULL) {
switch (hostType) {
case URI_HOST_TYPE_IP4:
if (URI_FUNC(IsWellFormedHostIp4)(first, afterLast) == URI_FALSE) {
return URI_ERROR_SYNTAX;
}
break;
case URI_HOST_TYPE_IP6: {
const int res = URI_FUNC(IsWellFormedHostIp6Mm)(first, afterLast, memory);
assert((res == URI_SUCCESS) || (res == URI_ERROR_SYNTAX)
|| (res == URI_ERROR_MALLOC));
if (res != URI_SUCCESS) {
return res;
}
} break;
case URI_HOST_TYPE_IPFUTURE: {
const int res =
URI_FUNC(IsWellFormedHostIpFutureMm)(first, afterLast, memory);
assert((res == URI_SUCCESS) || (res == URI_ERROR_SYNTAX)
|| (res == URI_ERROR_MALLOC));
if (res != URI_SUCCESS) {
return res;
}
} break;
case URI_HOST_TYPE_REGNAME:
if (URI_FUNC(IsWellFormedHostRegName)(first, afterLast) == URI_FALSE) {
return URI_ERROR_SYNTAX;
}
break;
default:
assert(0 && "Unsupported URI host type");
}
}
/* Clear old value */
const UriBool hadHostBefore = URI_FUNC(HasHost)(uri);
if (uri->hostData.ipFuture.first != NULL) {
/* NOTE: .hostData.ipFuture holds the very same range pointers
* as .hostText; we must not free memory twice. */
uri->hostText.first = NULL;
uri->hostText.afterLast = NULL;
if ((uri->owner == URI_TRUE)
&& (uri->hostData.ipFuture.first != uri->hostData.ipFuture.afterLast)) {
memory->free(memory, (URI_CHAR *)uri->hostData.ipFuture.first);
}
uri->hostData.ipFuture.first = NULL;
uri->hostData.ipFuture.afterLast = NULL;
} else if (uri->hostText.first != NULL) {
if ((uri->owner == URI_TRUE)
&& (uri->hostText.first != uri->hostText.afterLast)) {
memory->free(memory, (URI_CHAR *)uri->hostText.first);
}
uri->hostText.first = NULL;
uri->hostText.afterLast = NULL;
}
int URI_FUNC(InternalSetHostMm)(URI_TYPE(Uri) * uri,
UriHostType hostType,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
/* Superficial input validation (before making any changes) */
if ((uri == NULL) || ((first == NULL) != (afterLast == NULL))) {
return URI_ERROR_NULL;
}
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;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
/* Already done setting? */
if (first == NULL) {
/* Yes, but disambiguate as needed */
if (hadHostBefore == URI_TRUE) {
if (uri->pathHead != NULL) {
uri->absolutePath = URI_TRUE;
}
/* The RFC 3986 grammar reads:
* authority = [ userinfo "@" ] host [ ":" port ]
* So no user info or port without a host. */
if (first == NULL) {
if (uri->userInfo.first != NULL) {
return URI_ERROR_SETHOST_USERINFO_SET;
} else if (uri->portText.first != NULL) {
return URI_ERROR_SETHOST_PORT_SET;
}
}
const UriBool success =
URI_FUNC(EnsureThatPathIsNotMistakenForHost)(uri, memory);
return (success == URI_TRUE) ? URI_SUCCESS : URI_ERROR_MALLOC;
}
/* Syntax-check the new value */
if (first != NULL) {
switch (hostType) {
case URI_HOST_TYPE_IP4:
if (URI_FUNC(IsWellFormedHostIp4)(first, afterLast) == URI_FALSE) {
return URI_ERROR_SYNTAX;
}
break;
case URI_HOST_TYPE_IP6:
{
const int res = URI_FUNC(IsWellFormedHostIp6Mm)(first, afterLast, memory);
assert((res == URI_SUCCESS) || (res == URI_ERROR_SYNTAX) || (res == URI_ERROR_MALLOC));
if (res != URI_SUCCESS) {
return res;
}
}
break;
case URI_HOST_TYPE_IPFUTURE:
{
const int res = URI_FUNC(IsWellFormedHostIpFutureMm)(first, afterLast, memory);
assert((res == URI_SUCCESS) || (res == URI_ERROR_SYNTAX) || (res == URI_ERROR_MALLOC));
if (res != URI_SUCCESS) {
return res;
}
}
break;
case URI_HOST_TYPE_REGNAME:
if (URI_FUNC(IsWellFormedHostRegName)(first, afterLast) == URI_FALSE) {
return URI_ERROR_SYNTAX;
}
break;
default:
assert(0 && "Unsupported URI host type");
}
}
return URI_SUCCESS;
}
{
/* Clear old value */
const UriBool hadHostBefore = URI_FUNC(HasHost)(uri);
if (uri->hostData.ipFuture.first != NULL) {
/* NOTE: .hostData.ipFuture holds the very same range pointers
* as .hostText; we must not free memory twice. */
uri->hostText.first = NULL;
uri->hostText.afterLast = NULL;
assert(first != NULL);
if ((uri->owner == URI_TRUE) && (uri->hostData.ipFuture.first != uri->hostData.ipFuture.afterLast)) {
memory->free(memory, (URI_CHAR *)uri->hostData.ipFuture.first);
}
uri->hostData.ipFuture.first = NULL;
uri->hostData.ipFuture.afterLast = NULL;
} else if (uri->hostText.first != NULL) {
if ((uri->owner == URI_TRUE) && (uri->hostText.first != uri->hostText.afterLast)) {
memory->free(memory, (URI_CHAR *)uri->hostText.first);
}
uri->hostText.first = NULL;
uri->hostText.afterLast = NULL;
}
/* Ensure owned */
if (uri->owner == URI_FALSE) {
const int res = URI_FUNC(MakeOwnerMm)(uri, memory);
if (res != URI_SUCCESS) {
return res;
}
}
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;
}
assert(uri->owner == URI_TRUE);
/* Already done setting? */
if (first == NULL) {
/* Yes, but disambiguate as needed */
if (hadHostBefore == URI_TRUE) {
uri->absolutePath = 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;
{
const UriBool success = URI_FUNC(EnsureThatPathIsNotMistakenForHost)(uri, memory);
return (success == URI_TRUE)
? URI_SUCCESS
: URI_ERROR_MALLOC;
}
}
if (URI_FUNC(CopyRangeAsNeeded)(&uri->hostText, &sourceRange, memory) == URI_FALSE) {
return URI_ERROR_MALLOC;
}
return URI_SUCCESS;
}
}
uri->absolutePath = URI_FALSE; /* always URI_FALSE for URIs with host */
assert(first != NULL);
/* Fill .hostData as needed */
switch (hostType) {
case URI_HOST_TYPE_IP4: {
uri->hostData.ip4 = memory->malloc(memory, sizeof(UriIp4));
if (uri->hostData.ip4 == NULL) {
return URI_ERROR_MALLOC;
}
/* Ensure owned */
if (uri->owner == URI_FALSE) {
const int res = URI_FUNC(MakeOwnerMm)(uri, memory);
if (res != URI_SUCCESS) {
return res;
}
}
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));
if (uri->hostData.ip6 == NULL) {
return URI_ERROR_MALLOC;
}
assert(uri->owner == URI_TRUE);
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;
uri->hostData.ipFuture.afterLast = uri->hostText.afterLast;
break;
case URI_HOST_TYPE_REGNAME:
break;
default:
assert(0 && "Unsupported URI host type");
}
/* 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;
}
uri->absolutePath = URI_FALSE; /* always URI_FALSE for URIs with host */
/* Fill .hostData as needed */
switch (hostType) {
case URI_HOST_TYPE_IP4:
{
uri->hostData.ip4 = memory->malloc(memory, sizeof(UriIp4));
if (uri->hostData.ip4 == NULL) {
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));
if (uri->hostData.ip6 == NULL) {
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;
uri->hostData.ipFuture.afterLast = uri->hostText.afterLast;
break;
case URI_HOST_TYPE_REGNAME:
break;
default:
assert(0 && "Unsupported URI host type");
}
}
return URI_SUCCESS;
return URI_SUCCESS;
}
#endif

View File

@@ -37,43 +37,38 @@
*/
#if (defined(URI_PASS_ANSI) && !defined(URI_SET_HOST_COMMON_H_ANSI)) \
|| (defined(URI_PASS_UNICODE) && !defined(URI_SET_HOST_COMMON_H_UNICODE)) \
|| (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
|| (defined(URI_PASS_UNICODE) && !defined(URI_SET_HOST_COMMON_H_UNICODE)) \
|| (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
/* What encodings are enabled? */
#include <uriparser/UriDefsConfig.h>
#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
# 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 "UriSetHostCommon.h"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetHostCommon.h"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriSetHostCommon.h"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetHostCommon.h"
# undef URI_PASS_UNICODE
# endif
/* Only one pass for each encoding */
#elif (defined(URI_PASS_ANSI) && !defined(URI_SET_HOST_COMMON_H_ANSI) \
&& defined(URI_ENABLE_ANSI)) || (defined(URI_PASS_UNICODE) \
&& !defined(URI_SET_HOST_COMMON_H_UNICODE) && defined(URI_ENABLE_UNICODE))
# ifdef URI_PASS_ANSI
# define URI_SET_HOST_COMMON_H_ANSI 1
# include <uriparser/UriDefsAnsi.h>
# else
# define URI_SET_HOST_COMMON_H_UNICODE 1
# include <uriparser/UriDefsUnicode.h>
# endif
int URI_FUNC(InternalSetHostMm)(URI_TYPE(Uri) * uri,
UriHostType hostType,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory);
# elif (defined(URI_PASS_ANSI) && !defined(URI_SET_HOST_COMMON_H_ANSI) \
&& defined(URI_ENABLE_ANSI)) \
|| (defined(URI_PASS_UNICODE) && !defined(URI_SET_HOST_COMMON_H_UNICODE) \
&& defined(URI_ENABLE_UNICODE))
# ifdef URI_PASS_ANSI
# define URI_SET_HOST_COMMON_H_ANSI 1
# include <uriparser/UriDefsAnsi.h>
# else
# define URI_SET_HOST_COMMON_H_UNICODE 1
# include <uriparser/UriDefsUnicode.h>
# endif
int URI_FUNC(InternalSetHostMm)(URI_TYPE(Uri) * uri, UriHostType hostType,
const URI_CHAR * first, const URI_CHAR * afterLast,
UriMemoryManager * memory);
#endif
# endif
#endif

View File

@@ -40,66 +40,52 @@
#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 "UriSetHostIp4.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetHostIp4.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriSetHostIp4.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetHostIp4.c"
# undef URI_PASS_UNICODE
# endif
#else
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# include <wchar.h>
# endif
# 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 <uriparser/UriIp4.h>
# include "UriMemory.h"
# include "UriSetHostBase.h"
# include "UriSetHostCommon.h"
# endif
UriBool URI_FUNC(IsWellFormedHostIp4)(const URI_CHAR * first,
const URI_CHAR * afterLast) {
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
}
#ifndef URI_DOXYGEN
# include <uriparser/Uri.h>
# include <uriparser/UriIp4.h>
# include "UriMemory.h"
# include "UriSetHostBase.h"
# include "UriSetHostCommon.h"
#endif
UriBool URI_FUNC(IsWellFormedHostIp4)(const URI_CHAR * first, const URI_CHAR * afterLast) {
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
}
{
unsigned char octetOutput[4];
return (URI_FUNC(ParseIpFourAddress)(octetOutput, first, afterLast) == URI_SUCCESS)
? URI_TRUE
: 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) {
return URI_FUNC(InternalSetHostMm)(uri, URI_HOST_TYPE_IP4, first, afterLast, memory);
int URI_FUNC(SetHostIp4Mm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast, UriMemoryManager * memory) {
return URI_FUNC(InternalSetHostMm)(uri, URI_HOST_TYPE_IP4, first, afterLast, memory);
}
int URI_FUNC(SetHostIp4)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetHostIp4Mm)(uri, first, afterLast, NULL);
int URI_FUNC(SetHostIp4)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetHostIp4Mm)(uri, first, afterLast, NULL);
}
#endif

View File

@@ -40,143 +40,119 @@
#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 "UriSetHostIp6.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetHostIp6.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriSetHostIp6.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetHostIp6.c"
# undef URI_PASS_UNICODE
# endif
#else
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# include <wchar.h>
# endif
# 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 "UriMemory.h"
# include "UriSetHostBase.h"
# include "UriSetHostCommon.h"
# endif
# include <assert.h>
# include <string.h> /* for memcpy */
#ifndef URI_DOXYGEN
# include <uriparser/Uri.h>
# include "UriMemory.h"
# include "UriSetHostBase.h"
# include "UriSetHostCommon.h"
#endif
# 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,
const URI_CHAR * afterLast, UriMemoryManager * memory) {
/* NOTE: output is allowed to be NULL */
if ((first == NULL) || (afterLast == NULL)) {
return URI_ERROR_NULL;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
#include <assert.h>
#include <string.h> /* for memcpy */
/* Are we dealing with potential IPvFuture input? */
if (first < afterLast) {
switch (first[0]) {
case _UT('v'):
case _UT('V'):
return URI_ERROR_SYNTAX;
default:
break;
}
}
/* 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
* no risk of false positives from "bracket injection". */
URI_CHAR candidate[3 + URI_MAX_IP6_LEN + 1 + 1] = _UT("//[");
const size_t inputLenChars = (afterLast - first);
/* Detect overflow */
if (inputLenChars > URI_MAX_IP6_LEN) {
return URI_ERROR_SYNTAX;
}
#define URI_MAX_IP6_LEN (8 * 4 + 7 * 1) /* i.e. 8 full quads plus 7 colon separators */
memcpy(candidate + 3, first, inputLenChars * sizeof(URI_CHAR));
memcpy(candidate + 3 + inputLenChars, _UT("]"),
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)(
&uri, candidate, candidate + candidateLenChars, NULL, memory);
assert((res == URI_SUCCESS) || (res == URI_ERROR_SYNTAX)
|| (res == URI_ERROR_MALLOC));
int URI_FUNC(ParseIpSixAddressMm)(UriIp6 * output,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
/* NOTE: output is allowed to be NULL */
if ((first == NULL) || (afterLast == NULL)) {
return URI_ERROR_NULL;
}
if (res == URI_SUCCESS) {
assert(uri.hostData.ip6 != NULL);
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
if (output != NULL) {
memcpy(output->data, uri.hostData.ip6->data, sizeof(output->data));
}
/* Are we dealing with potential IPvFuture input? */
if (first < afterLast) {
switch (first[0]) {
case _UT('v'):
case _UT('V'):
return URI_ERROR_SYNTAX;
default:
break;
}
}
URI_FUNC(FreeUriMembersMm)(&uri, memory);
}
/* 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
* no risk of false positives from "bracket injection". */
URI_CHAR candidate[3 + URI_MAX_IP6_LEN + 1 + 1] = _UT("//[");
const size_t inputLenChars = (afterLast - first);
/* Detect overflow */
if (inputLenChars > URI_MAX_IP6_LEN) {
return URI_ERROR_SYNTAX;
}
memcpy(candidate + 3, first, inputLenChars * sizeof(URI_CHAR));
memcpy(candidate + 3 + inputLenChars, _UT("]"), 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)(&uri, candidate, candidate + candidateLenChars, NULL, memory);
assert((res == URI_SUCCESS) || (res == URI_ERROR_SYNTAX) || (res == URI_ERROR_MALLOC));
if (res == URI_SUCCESS) {
assert(uri.hostData.ip6 != NULL);
if (output != NULL) {
memcpy(output->data, uri.hostData.ip6->data, sizeof(output->data));
}
URI_FUNC(FreeUriMembersMm)(&uri, memory);
}
return res;
}
}
return res;
}
int URI_FUNC(ParseIpSixAddress)(UriIp6 * output,
const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(ParseIpSixAddressMm)(output, first, afterLast, NULL);
int URI_FUNC(ParseIpSixAddress)(UriIp6 * output, const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(ParseIpSixAddressMm)(output, first, afterLast, NULL);
}
int URI_FUNC(IsWellFormedHostIp6Mm)(const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) {
int URI_FUNC(IsWellFormedHostIp6Mm)(const URI_CHAR * first, const URI_CHAR * afterLast,
UriMemoryManager * memory) {
return URI_FUNC(ParseIpSixAddressMm)(NULL, first, afterLast, memory);
}
int URI_FUNC(IsWellFormedHostIp6)(const URI_CHAR * first, const URI_CHAR * afterLast) {
return URI_FUNC(IsWellFormedHostIp6Mm)(first, afterLast, NULL);
return URI_FUNC(IsWellFormedHostIp6Mm)(first, afterLast, NULL);
}
int URI_FUNC(SetHostIp6Mm)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
return URI_FUNC(InternalSetHostMm)(uri, URI_HOST_TYPE_IP6, first, afterLast, memory);
int URI_FUNC(SetHostIp6Mm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast, UriMemoryManager * memory) {
return URI_FUNC(InternalSetHostMm)(uri, URI_HOST_TYPE_IP6, first, afterLast, memory);
}
int URI_FUNC(SetHostIp6)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetHostIp6Mm)(uri, first, afterLast, NULL);
int URI_FUNC(SetHostIp6)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetHostIp6Mm)(uri, first, afterLast, NULL);
}
#endif

View File

@@ -40,135 +40,118 @@
#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 "UriSetHostIpFuture.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetHostIpFuture.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriSetHostIpFuture.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetHostIpFuture.c"
# undef URI_PASS_UNICODE
# endif
#else
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# include <wchar.h>
# endif
# 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 "UriMemory.h"
# include "UriSetHostBase.h"
# include "UriSetHostCommon.h"
# endif
# include <assert.h>
# include <string.h> /* for memcpy */
#ifndef URI_DOXYGEN
# include <uriparser/Uri.h>
# include "UriMemory.h"
# include "UriSetHostBase.h"
# include "UriSetHostCommon.h"
#endif
int URI_FUNC(IsWellFormedHostIpFutureMm)(const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
if ((first == NULL) || (afterLast == NULL)) {
return URI_ERROR_NULL;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
/* Are we dealing with potential IPv6 input? */
if (first < afterLast) {
switch (first[0]) {
case _UT('v'):
case _UT('V'):
break;
default:
return URI_ERROR_SYNTAX;
}
}
#include <assert.h>
#include <string.h> /* for memcpy */
/* 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
* no risk of false positives from "bracket injection". */
const size_t inputLenChars = (afterLast - first);
const size_t MAX_SIZE_T = (size_t)-1;
/* Detect overflow */
if (MAX_SIZE_T - inputLenChars < 3 + 1 + 1) {
return URI_ERROR_MALLOC;
}
const size_t candidateLenChars = 3 + inputLenChars + 1;
int URI_FUNC(IsWellFormedHostIpFutureMm)(const URI_CHAR * first, const URI_CHAR * afterLast, UriMemoryManager * memory) {
if ((first == NULL) || (afterLast == NULL)) {
return URI_ERROR_NULL;
}
/* Detect overflow */
if (MAX_SIZE_T / sizeof(URI_CHAR) < candidateLenChars + 1) {
return URI_ERROR_MALLOC;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
URI_CHAR * const candidate =
memory->malloc(memory, (candidateLenChars + 1) * sizeof(URI_CHAR));
/* Are we dealing with potential IPv6 input? */
if (first < afterLast) {
switch (first[0]) {
case _UT('v'):
case _UT('V'):
break;
default:
return URI_ERROR_SYNTAX;
}
}
if (candidate == NULL) {
return URI_ERROR_MALLOC;
}
/* 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
* no risk of false positives from "bracket injection". */
const size_t inputLenChars = (afterLast - first);
const size_t MAX_SIZE_T = (size_t)-1;
memcpy(candidate, _UT("//["), 3 * sizeof(URI_CHAR));
memcpy(candidate + 3, first, inputLenChars * sizeof(URI_CHAR));
memcpy(candidate + 3 + inputLenChars, _UT("]"),
2 * sizeof(URI_CHAR)); /* includes zero terminator */
/* Detect overflow */
if (MAX_SIZE_T - inputLenChars < 3 + 1 + 1) {
return URI_ERROR_MALLOC;
}
/* Parse as an RFC 3986 URI */
URI_TYPE(Uri) uri;
const int res = URI_FUNC(ParseSingleUriExMm)(
&uri, candidate, candidate + candidateLenChars, NULL, memory);
{
const size_t candidateLenChars = 3 + inputLenChars + 1;
assert((res == URI_SUCCESS) || (res == URI_ERROR_SYNTAX)
|| (res == URI_ERROR_MALLOC));
/* Detect overflow */
if (MAX_SIZE_T / sizeof(URI_CHAR) < candidateLenChars + 1) {
return URI_ERROR_MALLOC;
}
if (res == URI_SUCCESS) {
assert(uri.hostData.ipFuture.first != NULL);
URI_FUNC(FreeUriMembersMm)(&uri, memory);
}
{
URI_CHAR * const candidate = memory->malloc(memory, (candidateLenChars + 1) * sizeof(URI_CHAR));
memory->free(memory, candidate);
if (candidate == NULL) {
return URI_ERROR_MALLOC;
}
memcpy(candidate, _UT("//["), 3 * sizeof(URI_CHAR));
memcpy(candidate + 3, first, inputLenChars * sizeof(URI_CHAR));
memcpy(candidate + 3 + inputLenChars, _UT("]"), 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);
assert((res == URI_SUCCESS) || (res == URI_ERROR_SYNTAX) || (res == URI_ERROR_MALLOC));
if (res == URI_SUCCESS) {
assert(uri.hostData.ipFuture.first != NULL);
URI_FUNC(FreeUriMembersMm)(&uri, memory);
}
memory->free(memory, candidate);
return res;
}
}
}
}
return res;
}
int URI_FUNC(IsWellFormedHostIpFuture)(const URI_CHAR * first, const URI_CHAR * afterLast) {
return URI_FUNC(IsWellFormedHostIpFutureMm)(first, afterLast, NULL);
int URI_FUNC(IsWellFormedHostIpFuture)(const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(IsWellFormedHostIpFutureMm)(first, afterLast, NULL);
}
int URI_FUNC(SetHostIpFutureMm)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
return URI_FUNC(InternalSetHostMm)(uri, URI_HOST_TYPE_IPFUTURE, first, afterLast, memory);
int URI_FUNC(SetHostIpFutureMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast, UriMemoryManager * memory) {
return URI_FUNC(InternalSetHostMm)(uri, URI_HOST_TYPE_IPFUTURE, first, afterLast,
memory);
}
int URI_FUNC(SetHostIpFuture)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetHostIpFutureMm)(uri, first, afterLast, NULL);
int URI_FUNC(SetHostIpFuture)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetHostIpFutureMm)(uri, first, afterLast, NULL);
}
#endif

View File

@@ -40,207 +40,178 @@
#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 "UriSetHostRegName.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetHostRegName.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriSetHostRegName.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetHostRegName.c"
# undef URI_PASS_UNICODE
# endif
#else
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# include <wchar.h>
# endif
# 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 "UriMemory.h"
# include "UriSetHostBase.h"
# include "UriSetHostCommon.h"
# endif
# define URI_SET_DIGIT \
_UT('0') : case _UT('1'): \
case _UT('2'): \
case _UT('3'): \
case _UT('4'): \
case _UT('5'): \
case _UT('6'): \
case _UT('7'): \
case _UT('8'): \
case _UT('9')
#ifndef URI_DOXYGEN
# include <uriparser/Uri.h>
# include "UriMemory.h"
# include "UriSetHostBase.h"
# include "UriSetHostCommon.h"
#endif
# define URI_SET_HEX_LETTER_UPPER \
_UT('A') : case _UT('B'): \
case _UT('C'): \
case _UT('D'): \
case _UT('E'): \
case _UT('F')
# define URI_SET_HEX_LETTER_LOWER \
_UT('a') : case _UT('b'): \
case _UT('c'): \
case _UT('d'): \
case _UT('e'): \
case _UT('f')
# define URI_SET_HEXDIG \
URI_SET_DIGIT: \
case URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER
#define URI_SET_DIGIT \
_UT('0'): \
case _UT('1'): \
case _UT('2'): \
case _UT('3'): \
case _UT('4'): \
case _UT('5'): \
case _UT('6'): \
case _UT('7'): \
case _UT('8'): \
case _UT('9')
# define URI_SET_ALPHA \
URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER: \
case _UT('g'): \
case _UT('G'): \
case _UT('h'): \
case _UT('H'): \
case _UT('i'): \
case _UT('I'): \
case _UT('j'): \
case _UT('J'): \
case _UT('k'): \
case _UT('K'): \
case _UT('l'): \
case _UT('L'): \
case _UT('m'): \
case _UT('M'): \
case _UT('n'): \
case _UT('N'): \
case _UT('o'): \
case _UT('O'): \
case _UT('p'): \
case _UT('P'): \
case _UT('q'): \
case _UT('Q'): \
case _UT('r'): \
case _UT('R'): \
case _UT('s'): \
case _UT('S'): \
case _UT('t'): \
case _UT('T'): \
case _UT('u'): \
case _UT('U'): \
case _UT('v'): \
case _UT('V'): \
case _UT('w'): \
case _UT('W'): \
case _UT('x'): \
case _UT('X'): \
case _UT('y'): \
case _UT('Y'): \
case _UT('z'): \
case _UT('Z')
# define URI_SET_SUB_DELIMS \
_UT('!') : case _UT('$'): \
case _UT('&'): \
case _UT('\''): \
case _UT('('): \
case _UT(')'): \
case _UT('*'): \
case _UT('+'): \
case _UT(','): \
case _UT(';'): \
case _UT('=')
# define URI_SET_UNRESERVED \
URI_SET_ALPHA: \
case URI_SET_DIGIT: \
case _UT('-'): \
case _UT('.'): \
case _UT('_'): \
case _UT('~')
#define URI_SET_HEX_LETTER_UPPER \
_UT('A'): \
case _UT('B'): \
case _UT('C'): \
case _UT('D'): \
case _UT('E'): \
case _UT('F')
UriBool URI_FUNC(IsWellFormedHostRegName)(const URI_CHAR * first,
const URI_CHAR * afterLast) {
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
}
/* reg-name = *( unreserved / pct-encoded / sub-delims ) */
while (first < afterLast) {
switch (first[0]) {
case URI_SET_UNRESERVED:
break;
/* pct-encoded */
case _UT('%'):
if (afterLast - first < 3) {
return URI_FALSE;
}
switch (first[1]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
switch (first[2]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
first += 2;
break;
#define URI_SET_HEX_LETTER_LOWER \
_UT('a'): \
case _UT('b'): \
case _UT('c'): \
case _UT('d'): \
case _UT('e'): \
case _UT('f')
case URI_SET_SUB_DELIMS:
break;
default:
return URI_FALSE;
}
#define URI_SET_HEXDIG \
URI_SET_DIGIT: \
case URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER
#define URI_SET_ALPHA \
URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER: \
case _UT('g'): \
case _UT('G'): \
case _UT('h'): \
case _UT('H'): \
case _UT('i'): \
case _UT('I'): \
case _UT('j'): \
case _UT('J'): \
case _UT('k'): \
case _UT('K'): \
case _UT('l'): \
case _UT('L'): \
case _UT('m'): \
case _UT('M'): \
case _UT('n'): \
case _UT('N'): \
case _UT('o'): \
case _UT('O'): \
case _UT('p'): \
case _UT('P'): \
case _UT('q'): \
case _UT('Q'): \
case _UT('r'): \
case _UT('R'): \
case _UT('s'): \
case _UT('S'): \
case _UT('t'): \
case _UT('T'): \
case _UT('u'): \
case _UT('U'): \
case _UT('v'): \
case _UT('V'): \
case _UT('w'): \
case _UT('W'): \
case _UT('x'): \
case _UT('X'): \
case _UT('y'): \
case _UT('Y'): \
case _UT('z'): \
case _UT('Z')
#define URI_SET_SUB_DELIMS \
_UT('!'): \
case _UT('$'): \
case _UT('&'): \
case _UT('\''): \
case _UT('('): \
case _UT(')'): \
case _UT('*'): \
case _UT('+'): \
case _UT(','): \
case _UT(';'): \
case _UT('=')
#define URI_SET_UNRESERVED \
URI_SET_ALPHA: \
case URI_SET_DIGIT: \
case _UT('-'): \
case _UT('.'): \
case _UT('_'): \
case _UT('~')
UriBool URI_FUNC(IsWellFormedHostRegName)(const URI_CHAR * first, const URI_CHAR * afterLast) {
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
}
/* reg-name = *( unreserved / pct-encoded / sub-delims ) */
while (first < afterLast) {
switch (first[0]) {
case URI_SET_UNRESERVED:
break;
/* pct-encoded */
case _UT('%'):
if (afterLast - first < 3) {
return URI_FALSE;
}
switch (first[1]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
switch (first[2]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
first += 2;
break;
case URI_SET_SUB_DELIMS:
break;
default:
return URI_FALSE;
}
first++;
}
return URI_TRUE;
first++;
}
return URI_TRUE;
}
int URI_FUNC(SetHostRegNameMm)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
return URI_FUNC(InternalSetHostMm)(uri, URI_HOST_TYPE_REGNAME, first, afterLast, memory);
int URI_FUNC(SetHostRegNameMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast, UriMemoryManager * memory) {
return URI_FUNC(InternalSetHostMm)(uri, URI_HOST_TYPE_REGNAME, first, afterLast,
memory);
}
int URI_FUNC(SetHostRegName)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetHostRegNameMm)(uri, first, afterLast, NULL);
int URI_FUNC(SetHostRegName)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetHostRegNameMm)(uri, first, afterLast, NULL);
}
#endif

View File

@@ -40,456 +40,403 @@
#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 "UriSetPath.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetPath.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriSetPath.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetPath.c"
# undef URI_PASS_UNICODE
# endif
#else
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# include <wchar.h>
# endif
# 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"
# endif
# include <assert.h>
#ifndef URI_DOXYGEN
# include <uriparser/Uri.h>
# include "UriCommon.h"
# include "UriMemory.h"
#endif
# define URI_SET_DIGIT \
_UT('0') : case _UT('1'): \
case _UT('2'): \
case _UT('3'): \
case _UT('4'): \
case _UT('5'): \
case _UT('6'): \
case _UT('7'): \
case _UT('8'): \
case _UT('9')
# define URI_SET_HEX_LETTER_UPPER \
_UT('A') : case _UT('B'): \
case _UT('C'): \
case _UT('D'): \
case _UT('E'): \
case _UT('F')
# define URI_SET_HEX_LETTER_LOWER \
_UT('a') : case _UT('b'): \
case _UT('c'): \
case _UT('d'): \
case _UT('e'): \
case _UT('f')
#include <assert.h>
# define URI_SET_HEXDIG \
URI_SET_DIGIT: \
case URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER
# define URI_SET_ALPHA \
URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER: \
case _UT('g'): \
case _UT('G'): \
case _UT('h'): \
case _UT('H'): \
case _UT('i'): \
case _UT('I'): \
case _UT('j'): \
case _UT('J'): \
case _UT('k'): \
case _UT('K'): \
case _UT('l'): \
case _UT('L'): \
case _UT('m'): \
case _UT('M'): \
case _UT('n'): \
case _UT('N'): \
case _UT('o'): \
case _UT('O'): \
case _UT('p'): \
case _UT('P'): \
case _UT('q'): \
case _UT('Q'): \
case _UT('r'): \
case _UT('R'): \
case _UT('s'): \
case _UT('S'): \
case _UT('t'): \
case _UT('T'): \
case _UT('u'): \
case _UT('U'): \
case _UT('v'): \
case _UT('V'): \
case _UT('w'): \
case _UT('W'): \
case _UT('x'): \
case _UT('X'): \
case _UT('y'): \
case _UT('Y'): \
case _UT('z'): \
case _UT('Z')
# define URI_SET_SUB_DELIMS \
_UT('!') : case _UT('$'): \
case _UT('&'): \
case _UT('\''): \
case _UT('('): \
case _UT(')'): \
case _UT('*'): \
case _UT('+'): \
case _UT(','): \
case _UT(';'): \
case _UT('=')
#define URI_SET_DIGIT \
_UT('0'): \
case _UT('1'): \
case _UT('2'): \
case _UT('3'): \
case _UT('4'): \
case _UT('5'): \
case _UT('6'): \
case _UT('7'): \
case _UT('8'): \
case _UT('9')
# define URI_SET_UNRESERVED \
URI_SET_ALPHA: \
case URI_SET_DIGIT: \
case _UT('-'): \
case _UT('.'): \
case _UT('_'): \
case _UT('~')
UriBool URI_FUNC(IsWellFormedPath)(const URI_CHAR * first, const URI_CHAR * afterLast,
UriBool hasHost) {
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
}
if ((hasHost == URI_TRUE) && ((first >= afterLast) || (first[0] != _UT('/')))) {
return URI_FALSE;
}
#define URI_SET_HEX_LETTER_UPPER \
_UT('A'): \
case _UT('B'): \
case _UT('C'): \
case _UT('D'): \
case _UT('E'): \
case _UT('F')
/* The related part of the grammar in RFC 3986 (section 3.3) reads:
*
* path = path-abempty ; begins with "/" or is empty
* / path-absolute ; begins with "/" but not "//"
* / path-noscheme ; begins with a non-colon segment
* / path-rootless ; begins with a segment
* / path-empty ; zero characters
*
* path-abempty = *( "/" segment )
* path-absolute = "/" [ segment-nz *( "/" segment ) ]
* path-noscheme = segment-nz-nc *( "/" segment )
* path-rootless = segment-nz *( "/" segment )
* path-empty = 0<pchar>
*
* segment = *pchar
* segment-nz = 1*pchar
* segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
* ; non-zero-length segment without any colon ":"
*
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
*
* The check below simplifies this to ..
*
* path = *( unreserved / pct-encoded / sub-delims / ":" / "@" / "/" )
*
* .. and leaves the rest to pre-return removal of ambiguity
* from cases like "path1:/path2" and "//path1/path2" inside SetPath.
*/
while (first < afterLast) {
switch (first[0]) {
case URI_SET_UNRESERVED:
break;
/* pct-encoded */
case _UT('%'):
if (afterLast - first < 3) {
return URI_FALSE;
}
switch (first[1]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
switch (first[2]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
first += 2;
break;
case URI_SET_SUB_DELIMS:
break;
#define URI_SET_HEX_LETTER_LOWER \
_UT('a'): \
case _UT('b'): \
case _UT('c'): \
case _UT('d'): \
case _UT('e'): \
case _UT('f')
/* ":" / "@" and "/" */
case _UT(':'):
case _UT('@'):
case _UT('/'):
break;
default:
return URI_FALSE;
}
#define URI_SET_HEXDIG \
URI_SET_DIGIT: \
case URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER
#define URI_SET_ALPHA \
URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER: \
case _UT('g'): \
case _UT('G'): \
case _UT('h'): \
case _UT('H'): \
case _UT('i'): \
case _UT('I'): \
case _UT('j'): \
case _UT('J'): \
case _UT('k'): \
case _UT('K'): \
case _UT('l'): \
case _UT('L'): \
case _UT('m'): \
case _UT('M'): \
case _UT('n'): \
case _UT('N'): \
case _UT('o'): \
case _UT('O'): \
case _UT('p'): \
case _UT('P'): \
case _UT('q'): \
case _UT('Q'): \
case _UT('r'): \
case _UT('R'): \
case _UT('s'): \
case _UT('S'): \
case _UT('t'): \
case _UT('T'): \
case _UT('u'): \
case _UT('U'): \
case _UT('v'): \
case _UT('V'): \
case _UT('w'): \
case _UT('W'): \
case _UT('x'): \
case _UT('X'): \
case _UT('y'): \
case _UT('Y'): \
case _UT('z'): \
case _UT('Z')
#define URI_SET_SUB_DELIMS \
_UT('!'): \
case _UT('$'): \
case _UT('&'): \
case _UT('\''): \
case _UT('('): \
case _UT(')'): \
case _UT('*'): \
case _UT('+'): \
case _UT(','): \
case _UT(';'): \
case _UT('=')
#define URI_SET_UNRESERVED \
URI_SET_ALPHA: \
case URI_SET_DIGIT: \
case _UT('-'): \
case _UT('.'): \
case _UT('_'): \
case _UT('~')
UriBool URI_FUNC(IsWellFormedPath)(const URI_CHAR * first, const URI_CHAR * afterLast, UriBool hasHost) {
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
}
if ((hasHost == URI_TRUE) && ((first >= afterLast) || (first[0] != _UT('/')))) {
return URI_FALSE;
}
/* The related part of the grammar in RFC 3986 (section 3.3) reads:
*
* path = path-abempty ; begins with "/" or is empty
* / path-absolute ; begins with "/" but not "//"
* / path-noscheme ; begins with a non-colon segment
* / path-rootless ; begins with a segment
* / path-empty ; zero characters
*
* path-abempty = *( "/" segment )
* path-absolute = "/" [ segment-nz *( "/" segment ) ]
* path-noscheme = segment-nz-nc *( "/" segment )
* path-rootless = segment-nz *( "/" segment )
* path-empty = 0<pchar>
*
* segment = *pchar
* segment-nz = 1*pchar
* segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
* ; non-zero-length segment without any colon ":"
*
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
*
* The check below simplifies this to ..
*
* path = *( unreserved / pct-encoded / sub-delims / ":" / "@" / "/" )
*
* .. and leaves the rest to pre-return removal of ambiguity
* from cases like "path1:/path2" and "//path1/path2" inside SetPath.
*/
while (first < afterLast) {
switch (first[0]) {
case URI_SET_UNRESERVED:
break;
/* pct-encoded */
case _UT('%'):
if (afterLast - first < 3) {
return URI_FALSE;
}
switch (first[1]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
switch (first[2]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
first += 2;
break;
case URI_SET_SUB_DELIMS:
break;
/* ":" / "@" and "/" */
case _UT(':'):
case _UT('@'):
case _UT('/'):
break;
default:
return URI_FALSE;
}
first++;
}
return URI_TRUE;
first++;
}
return URI_TRUE;
}
static void URI_FUNC(DropEmptyFirstPathSegment)(URI_TYPE(Uri) * uri,
UriMemoryManager * memory) {
assert(uri != NULL);
assert(memory != NULL);
assert(uri->pathHead != NULL);
assert(uri->pathHead->text.first == uri->pathHead->text.afterLast);
URI_TYPE(PathSegment) * const originalHead = uri->pathHead;
static void URI_FUNC(DropEmptyFirstPathSegment)(URI_TYPE(Uri) * uri, UriMemoryManager * memory) {
assert(uri != NULL);
assert(memory != NULL);
assert(uri->pathHead != NULL);
assert(uri->pathHead->text.first == uri->pathHead->text.afterLast);
uri->pathHead = uri->pathHead->next;
{
URI_TYPE(PathSegment) * const originalHead = uri->pathHead;
uri->pathHead = uri->pathHead->next;
originalHead->text.first = NULL;
originalHead->text.afterLast = NULL;
memory->free(memory, originalHead);
}
originalHead->text.first = NULL;
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 effect"
* of a leading slash during stringification) and transforms it into .absolutePath == URI_TRUE
* instead, if present. */
static void URI_FUNC(TransformEmptyLeadPathSegments)(URI_TYPE(Uri) * uri, UriMemoryManager * memory) {
assert(uri != NULL);
assert(memory != NULL);
* This function checks for a leading empty path segment (that would have the "visual
* effect" of a leading slash during stringification) and transforms it into .absolutePath
* == URI_TRUE instead, if present. */
static void URI_FUNC(TransformEmptyLeadPathSegments)(URI_TYPE(Uri) * uri,
UriMemoryManager * memory) {
assert(uri != NULL);
assert(memory != NULL);
if ((URI_FUNC(HasHost)(uri) == URI_TRUE)
|| (uri->pathHead == NULL)
|| (uri->pathHead->text.first != uri->pathHead->text.afterLast)) {
return; /* i.e. nothing to do */
}
if ((URI_FUNC(HasHost)(uri) == URI_TRUE) || (uri->pathHead == NULL)
|| (uri->pathHead->text.first != uri->pathHead->text.afterLast)) {
return; /* i.e. nothing to do */
}
assert(uri->absolutePath == URI_FALSE);
assert(uri->absolutePath == URI_FALSE);
URI_FUNC(DropEmptyFirstPathSegment)(uri, memory);
URI_FUNC(DropEmptyFirstPathSegment)(uri, memory);
uri->absolutePath = URI_TRUE;
uri->absolutePath = URI_TRUE;
}
static int URI_FUNC(InternalSetPath)(URI_TYPE(Uri) * destUri, const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
assert(destUri != NULL);
assert(first != NULL);
assert(afterLast != NULL);
assert(memory != NULL);
assert(destUri->pathHead == NULL); /* set by SetPathMm right before */
assert(destUri->pathTail == NULL); /* set by SetPathMm right before */
assert(destUri->absolutePath == URI_FALSE); /* set by SetPathMm right before */
/* Skip the leading slash from target URIs with a host (so that we can
* transfer the path 1:1 further down) */
if (URI_FUNC(HasHost)(destUri) == URI_TRUE) {
/* NOTE: This is because SetPathMm called IsWellFormedPath earlier: */
assert((afterLast - first >= 1) && (first[0] == _UT('/')));
first++;
} else if (first == afterLast) {
/* This avoids (1) all the expensive but unnecessary work below
* and also (2) mis-encoding as single empty path segment
* that would need (detection and) repair further down otherwise */
return URI_SUCCESS;
}
static int URI_FUNC(InternalSetPath)(URI_TYPE(Uri) * destUri,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
assert(destUri != NULL);
assert(first != NULL);
assert(afterLast != NULL);
assert(memory != NULL);
assert(destUri->pathHead == NULL); /* set by SetPathMm right before */
assert(destUri->pathTail == NULL); /* set by SetPathMm right before */
assert(destUri->absolutePath == URI_FALSE); /* set by SetPathMm right before */
/* Assemble "///.." input wrap for upcoming parse as a URI */
const size_t inputLenChars = (afterLast - first);
const size_t MAX_SIZE_T = (size_t)-1;
/* Skip the leading slash from target URIs with a host (so that we can
* transfer the path 1:1 further down) */
if (URI_FUNC(HasHost)(destUri) == URI_TRUE) {
/* NOTE: This is because SetPathMm called IsWellFormedPath earlier: */
assert((afterLast - first >= 1) && (first[0] == _UT('/')));
first++;
} else if (first == afterLast) {
/* This avoids (1) all the expensive but unnecessary work below
* and also (2) mis-encoding as single empty path segment
* that would need (detection and) repair further down otherwise */
return URI_SUCCESS;
}
/* Detect overflow */
if (MAX_SIZE_T - inputLenChars < 3 + 1) {
return URI_ERROR_MALLOC;
}
/* Assemble "///.." input wrap for upcoming parse as a URI */
{
const size_t inputLenChars = (afterLast - first);
const size_t MAX_SIZE_T = (size_t)-1;
const size_t candidateLenChars = 3 + inputLenChars;
/* Detect overflow */
if (MAX_SIZE_T - inputLenChars < 3 + 1) {
return URI_ERROR_MALLOC;
}
/* Detect overflow */
if (MAX_SIZE_T / sizeof(URI_CHAR) < candidateLenChars + 1) {
return URI_ERROR_MALLOC;
}
{
const size_t candidateLenChars = 3 + inputLenChars;
URI_CHAR * const candidate =
memory->malloc(memory, (candidateLenChars + 1) * sizeof(URI_CHAR));
/* Detect overflow */
if (MAX_SIZE_T / sizeof(URI_CHAR) < candidateLenChars + 1) {
return URI_ERROR_MALLOC;
}
if (candidate == NULL) {
return URI_ERROR_MALLOC;
}
{
URI_CHAR * const candidate = memory->malloc(memory, (candidateLenChars + 1) * sizeof(URI_CHAR));
memcpy(candidate, _UT("///"), 3 * sizeof(URI_CHAR));
memcpy(candidate + 3, first, inputLenChars * sizeof(URI_CHAR));
candidate[3 + inputLenChars] = _UT('\0');
if (candidate == NULL) {
return URI_ERROR_MALLOC;
}
/* Parse as an RFC 3986 URI */
URI_TYPE(Uri) tempUri;
int res = 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) {
memory->free(memory, candidate);
return res;
}
memcpy(candidate, _UT("///"), 3 * sizeof(URI_CHAR));
memcpy(candidate + 3, first, inputLenChars * sizeof(URI_CHAR));
candidate[3 + inputLenChars] = _UT('\0');
/* Nothing but path and host is supposed to be set by the parse, in
* particular not: */
assert(tempUri.query.first == NULL);
assert(tempUri.fragment.first == NULL);
/* Parse as an RFC 3986 URI */
{
URI_TYPE(Uri) tempUri;
const int res = 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) {
memory->free(memory, candidate);
return res;
}
/* Ensure that the strings in the path segments are all owned by
* `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. */
res = URI_FUNC(MakeOwnerMm)(&tempUri, memory);
assert((res == URI_SUCCESS) || (res == URI_ERROR_MALLOC));
if (res != URI_SUCCESS) {
URI_FUNC(FreeUriMembersMm)(&tempUri, memory);
memory->free(memory, candidate);
return res;
}
assert(tempUri.owner == URI_TRUE);
/* Nothing but path and host is supposed to be set by the parse, in particular not: */
assert(tempUri.query.first == NULL);
assert(tempUri.fragment.first == NULL);
/* 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;
/* Ensure that the strings in the path segments are all owned by `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);
memory->free(memory, candidate);
return res;
}
assert(tempUri.owner == URI_TRUE);
}
tempUri.pathHead = NULL;
tempUri.pathTail = NULL;
/* 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;
/* Free the rest of the temp URI */
URI_FUNC(FreeUriMembersMm)(&tempUri, memory);
memory->free(memory, candidate);
tempUri.pathHead = NULL;
tempUri.pathTail = NULL;
/* Restore use of .absolutePath as needed */
URI_FUNC(TransformEmptyLeadPathSegments)(destUri, memory);
/* Free the rest of the temp URI */
URI_FUNC(FreeUriMembersMm)(&tempUri, memory);
memory->free(memory, candidate);
/* Disambiguate as needed */
UriBool success = URI_FUNC(FixPathNoScheme)(destUri, memory);
if (success == URI_FALSE) {
return URI_ERROR_MALLOC;
}
/* Restore use of .absolutePath as needed */
URI_FUNC(TransformEmptyLeadPathSegments)(destUri, memory);
success = URI_FUNC(EnsureThatPathIsNotMistakenForHost)(destUri, memory);
if (success == URI_FALSE) {
return URI_ERROR_MALLOC;
}
/* 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;
return URI_SUCCESS;
}
int URI_FUNC(SetPathMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast, UriMemoryManager * memory) {
/* Input validation (before making any changes) */
if ((uri == NULL) || ((first == NULL) != (afterLast == NULL))) {
return URI_ERROR_NULL;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
int URI_FUNC(SetPathMm)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
/* Input validation (before making any changes) */
if ((uri == NULL) || ((first == NULL) != (afterLast == NULL))) {
return URI_ERROR_NULL;
}
if ((first != NULL)
&& (URI_FUNC(IsWellFormedPath)(first, afterLast, URI_FUNC(HasHost)(uri))
== URI_FALSE)) {
return URI_ERROR_SYNTAX;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
/* Clear old value */
int res = URI_FUNC(FreeUriPath)(uri, memory);
if (res != URI_SUCCESS) {
return res;
}
uri->absolutePath = URI_FALSE;
if ((first != NULL) && (URI_FUNC(IsWellFormedPath)(first, afterLast, URI_FUNC(HasHost)(uri)) == URI_FALSE)) {
return URI_ERROR_SYNTAX;
}
/* Already done? */
if (first == NULL) {
return URI_SUCCESS;
}
/* Clear old value */
{
const int res = URI_FUNC(FreeUriPath)(uri, memory);
if (res != URI_SUCCESS) {
return res;
}
uri->absolutePath = URI_FALSE;
}
assert(first != NULL);
/* Already done? */
if (first == NULL) {
return URI_SUCCESS;
}
/* Ensure owned */
if (uri->owner == URI_FALSE) {
res = URI_FUNC(MakeOwnerMm)(uri, memory);
if (res != URI_SUCCESS) {
return res;
}
}
assert(first != NULL);
assert(uri->owner == URI_TRUE);
/* Ensure owned */
if (uri->owner == URI_FALSE) {
const int res = URI_FUNC(MakeOwnerMm)(uri, memory);
if (res != URI_SUCCESS) {
return res;
}
}
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;
}
/* Apply new value */
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) {
return URI_FUNC(SetPathMm)(uri, first, afterLast, NULL);
int URI_FUNC(SetPath)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetPathMm)(uri, first, afterLast, NULL);
}
#endif

View File

@@ -40,140 +40,120 @@
#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 "UriSetPort.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetPort.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriSetPort.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetPort.c"
# undef URI_PASS_UNICODE
# endif
#else
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# include <wchar.h>
# endif
# 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"
# endif
# include <assert.h>
#ifndef URI_DOXYGEN
# include <uriparser/Uri.h>
# include "UriCommon.h"
# include "UriMemory.h"
#endif
#include <assert.h>
#define URI_SET_DIGIT \
_UT('0'): \
case _UT('1'): \
case _UT('2'): \
case _UT('3'): \
case _UT('4'): \
case _UT('5'): \
case _UT('6'): \
case _UT('7'): \
case _UT('8'): \
case _UT('9')
# define URI_SET_DIGIT \
_UT('0') : case _UT('1'): \
case _UT('2'): \
case _UT('3'): \
case _UT('4'): \
case _UT('5'): \
case _UT('6'): \
case _UT('7'): \
case _UT('8'): \
case _UT('9')
UriBool URI_FUNC(IsWellFormedPort)(const URI_CHAR * first, const URI_CHAR * afterLast) {
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
}
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
}
/* NOTE: Grammar reads "port = *DIGIT" which includes the empty string. */
while (first < afterLast) {
switch (first[0]) {
case URI_SET_DIGIT:
break;
default:
return URI_FALSE;
}
first++;
}
return URI_TRUE;
/* NOTE: Grammar reads "port = *DIGIT" which includes the empty string. */
while (first < afterLast) {
switch (first[0]) {
case URI_SET_DIGIT:
break;
default:
return URI_FALSE;
}
first++;
}
return URI_TRUE;
}
int URI_FUNC(SetPortTextMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast, UriMemoryManager * memory) {
/* Input validation (before making any changes) */
if ((uri == NULL) || ((first == NULL) != (afterLast == NULL))) {
return URI_ERROR_NULL;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
int URI_FUNC(SetPortTextMm)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
/* Input validation (before making any changes) */
if ((uri == NULL) || ((first == NULL) != (afterLast == NULL))) {
return URI_ERROR_NULL;
}
/* The RFC 3986 grammar reads:
* authority = [ userinfo "@" ] host [ ":" port ]
* So no port without a host. */
if ((first != NULL) && (URI_FUNC(HasHost)(uri) == URI_FALSE)) {
return URI_ERROR_SETPORT_HOST_NOT_SET;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
if ((first != NULL) && (URI_FUNC(IsWellFormedPort)(first, afterLast) == URI_FALSE)) {
return URI_ERROR_SYNTAX;
}
/* The RFC 3986 grammar reads:
* authority = [ userinfo "@" ] host [ ":" port ]
* So no port without a host. */
if ((first != NULL) && (URI_FUNC(HasHost)(uri) == URI_FALSE)) {
return URI_ERROR_SETPORT_HOST_NOT_SET;
}
/* Clear old value */
if ((uri->owner == URI_TRUE) && (uri->portText.first != uri->portText.afterLast)) {
memory->free(memory, (URI_CHAR *)uri->portText.first);
}
uri->portText.first = NULL;
uri->portText.afterLast = NULL;
if ((first != NULL) && (URI_FUNC(IsWellFormedPort)(first, afterLast) == URI_FALSE)) {
return URI_ERROR_SYNTAX;
}
/* Already done? */
if (first == NULL) {
return URI_SUCCESS;
}
/* Clear old value */
if ((uri->owner == URI_TRUE) && (uri->portText.first != uri->portText.afterLast)) {
memory->free(memory, (URI_CHAR *)uri->portText.first);
}
uri->portText.first = NULL;
uri->portText.afterLast = NULL;
assert(first != NULL);
/* Already done? */
if (first == NULL) {
return URI_SUCCESS;
}
/* Ensure owned */
if (uri->owner == URI_FALSE) {
const int res = URI_FUNC(MakeOwnerMm)(uri, memory);
if (res != URI_SUCCESS) {
return res;
}
}
assert(first != NULL);
assert(uri->owner == URI_TRUE);
/* Ensure owned */
if (uri->owner == URI_FALSE) {
const int res = URI_FUNC(MakeOwnerMm)(uri, memory);
if (res != URI_SUCCESS) {
return res;
}
}
/* Apply new value */
URI_TYPE(TextRange) sourceRange;
sourceRange.first = first;
sourceRange.afterLast = afterLast;
assert(uri->owner == URI_TRUE);
if (URI_FUNC(CopyRangeAsNeeded)(&uri->portText, &sourceRange, memory) == URI_FALSE) {
return URI_ERROR_MALLOC;
}
/* 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;
return URI_SUCCESS;
}
int URI_FUNC(SetPortText)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetPortTextMm)(uri, first, afterLast, NULL);
int URI_FUNC(SetPortText)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetPortTextMm)(uri, first, afterLast, NULL);
}
#endif

View File

@@ -40,267 +40,232 @@
#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 "UriSetQuery.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetQuery.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriSetQuery.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetQuery.c"
# undef URI_PASS_UNICODE
# endif
#else
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# include <wchar.h>
# endif
# 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"
# endif
# include <assert.h>
#ifndef URI_DOXYGEN
# include <uriparser/Uri.h>
# include "UriCommon.h"
# include "UriMemory.h"
#endif
# define URI_SET_DIGIT \
_UT('0') : case _UT('1'): \
case _UT('2'): \
case _UT('3'): \
case _UT('4'): \
case _UT('5'): \
case _UT('6'): \
case _UT('7'): \
case _UT('8'): \
case _UT('9')
# define URI_SET_HEX_LETTER_UPPER \
_UT('A') : case _UT('B'): \
case _UT('C'): \
case _UT('D'): \
case _UT('E'): \
case _UT('F')
# define URI_SET_HEX_LETTER_LOWER \
_UT('a') : case _UT('b'): \
case _UT('c'): \
case _UT('d'): \
case _UT('e'): \
case _UT('f')
#include <assert.h>
# define URI_SET_HEXDIG \
URI_SET_DIGIT: \
case URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER
# define URI_SET_ALPHA \
URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER: \
case _UT('g'): \
case _UT('G'): \
case _UT('h'): \
case _UT('H'): \
case _UT('i'): \
case _UT('I'): \
case _UT('j'): \
case _UT('J'): \
case _UT('k'): \
case _UT('K'): \
case _UT('l'): \
case _UT('L'): \
case _UT('m'): \
case _UT('M'): \
case _UT('n'): \
case _UT('N'): \
case _UT('o'): \
case _UT('O'): \
case _UT('p'): \
case _UT('P'): \
case _UT('q'): \
case _UT('Q'): \
case _UT('r'): \
case _UT('R'): \
case _UT('s'): \
case _UT('S'): \
case _UT('t'): \
case _UT('T'): \
case _UT('u'): \
case _UT('U'): \
case _UT('v'): \
case _UT('V'): \
case _UT('w'): \
case _UT('W'): \
case _UT('x'): \
case _UT('X'): \
case _UT('y'): \
case _UT('Y'): \
case _UT('z'): \
case _UT('Z')
# define URI_SET_SUB_DELIMS \
_UT('!') : case _UT('$'): \
case _UT('&'): \
case _UT('\''): \
case _UT('('): \
case _UT(')'): \
case _UT('*'): \
case _UT('+'): \
case _UT(','): \
case _UT(';'): \
case _UT('=')
#define URI_SET_DIGIT \
_UT('0'): \
case _UT('1'): \
case _UT('2'): \
case _UT('3'): \
case _UT('4'): \
case _UT('5'): \
case _UT('6'): \
case _UT('7'): \
case _UT('8'): \
case _UT('9')
#define URI_SET_HEX_LETTER_UPPER \
_UT('A'): \
case _UT('B'): \
case _UT('C'): \
case _UT('D'): \
case _UT('E'): \
case _UT('F')
#define URI_SET_HEX_LETTER_LOWER \
_UT('a'): \
case _UT('b'): \
case _UT('c'): \
case _UT('d'): \
case _UT('e'): \
case _UT('f')
#define URI_SET_HEXDIG \
URI_SET_DIGIT: \
case URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER
#define URI_SET_ALPHA \
URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER: \
case _UT('g'): \
case _UT('G'): \
case _UT('h'): \
case _UT('H'): \
case _UT('i'): \
case _UT('I'): \
case _UT('j'): \
case _UT('J'): \
case _UT('k'): \
case _UT('K'): \
case _UT('l'): \
case _UT('L'): \
case _UT('m'): \
case _UT('M'): \
case _UT('n'): \
case _UT('N'): \
case _UT('o'): \
case _UT('O'): \
case _UT('p'): \
case _UT('P'): \
case _UT('q'): \
case _UT('Q'): \
case _UT('r'): \
case _UT('R'): \
case _UT('s'): \
case _UT('S'): \
case _UT('t'): \
case _UT('T'): \
case _UT('u'): \
case _UT('U'): \
case _UT('v'): \
case _UT('V'): \
case _UT('w'): \
case _UT('W'): \
case _UT('x'): \
case _UT('X'): \
case _UT('y'): \
case _UT('Y'): \
case _UT('z'): \
case _UT('Z')
#define URI_SET_SUB_DELIMS \
_UT('!'): \
case _UT('$'): \
case _UT('&'): \
case _UT('\''): \
case _UT('('): \
case _UT(')'): \
case _UT('*'): \
case _UT('+'): \
case _UT(','): \
case _UT(';'): \
case _UT('=')
#define URI_SET_UNRESERVED \
URI_SET_ALPHA: \
case URI_SET_DIGIT: \
case _UT('-'): \
case _UT('.'): \
case _UT('_'): \
case _UT('~')
# define URI_SET_UNRESERVED \
URI_SET_ALPHA: \
case URI_SET_DIGIT: \
case _UT('-'): \
case _UT('.'): \
case _UT('_'): \
case _UT('~')
UriBool URI_FUNC(IsWellFormedQuery)(const URI_CHAR * first, const URI_CHAR * afterLast) {
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
}
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
}
/* The related part of the grammar in RFC 3986 reads:
*
* query = *( pchar / "/" / "?" )
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
*/
while (first < afterLast) {
switch (first[0]) {
case URI_SET_UNRESERVED:
break;
/* The related part of the grammar in RFC 3986 reads:
*
* query = *( pchar / "/" / "?" )
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
*/
while (first < afterLast) {
switch (first[0]) {
case URI_SET_UNRESERVED:
break;
/* pct-encoded */
case _UT('%'):
if (afterLast - first < 3) {
return URI_FALSE;
}
switch (first[1]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
switch (first[2]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
first += 2;
break;
/* pct-encoded */
case _UT('%'):
if (afterLast - first < 3) {
return URI_FALSE;
}
switch (first[1]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
switch (first[2]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
first += 2;
break;
case URI_SET_SUB_DELIMS:
break;
case URI_SET_SUB_DELIMS:
break;
/* ":" / "@" and "/" / "?" */
case _UT(':'):
case _UT('@'):
case _UT('/'):
case _UT('?'):
break;
/* ":" / "@" and "/" / "?" */
case _UT(':'):
case _UT('@'):
case _UT('/'):
case _UT('?'):
break;
default:
return URI_FALSE;
}
default:
return URI_FALSE;
}
first++;
}
return URI_TRUE;
first++;
}
return URI_TRUE;
}
int URI_FUNC(SetQueryMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast, UriMemoryManager * memory) {
/* Input validation (before making any changes) */
if ((uri == NULL) || ((first == NULL) != (afterLast == NULL))) {
return URI_ERROR_NULL;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
int URI_FUNC(SetQueryMm)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
/* Input validation (before making any changes) */
if ((uri == NULL) || ((first == NULL) != (afterLast == NULL))) {
return URI_ERROR_NULL;
}
if ((first != NULL) && (URI_FUNC(IsWellFormedQuery)(first, afterLast) == URI_FALSE)) {
return URI_ERROR_SYNTAX;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
/* Clear old value */
if ((uri->owner == URI_TRUE) && (uri->query.first != uri->query.afterLast)) {
memory->free(memory, (URI_CHAR *)uri->query.first);
}
uri->query.first = NULL;
uri->query.afterLast = NULL;
if ((first != NULL) && (URI_FUNC(IsWellFormedQuery)(first, afterLast) == URI_FALSE)) {
return URI_ERROR_SYNTAX;
}
/* Already done? */
if (first == NULL) {
return URI_SUCCESS;
}
/* Clear old value */
if ((uri->owner == URI_TRUE) && (uri->query.first != uri->query.afterLast)) {
memory->free(memory, (URI_CHAR *)uri->query.first);
}
uri->query.first = NULL;
uri->query.afterLast = NULL;
assert(first != NULL);
/* Already done? */
if (first == NULL) {
return URI_SUCCESS;
}
/* Ensure owned */
if (uri->owner == URI_FALSE) {
const int res = URI_FUNC(MakeOwnerMm)(uri, memory);
if (res != URI_SUCCESS) {
return res;
}
}
assert(first != NULL);
assert(uri->owner == URI_TRUE);
/* Ensure owned */
if (uri->owner == URI_FALSE) {
const int res = URI_FUNC(MakeOwnerMm)(uri, memory);
if (res != URI_SUCCESS) {
return res;
}
}
/* Apply new value */
URI_TYPE(TextRange) sourceRange;
sourceRange.first = first;
sourceRange.afterLast = afterLast;
assert(uri->owner == URI_TRUE);
if (URI_FUNC(CopyRangeAsNeeded)(&uri->query, &sourceRange, memory) == URI_FALSE) {
return URI_ERROR_MALLOC;
}
/* Apply new value */
{
URI_TYPE(TextRange) sourceRange;
sourceRange.first = first;
sourceRange.afterLast = afterLast;
if (URI_FUNC(CopyRangeAsNeeded)(&uri->query, &sourceRange, memory) == URI_FALSE) {
return URI_ERROR_MALLOC;
}
}
return URI_SUCCESS;
return URI_SUCCESS;
}
int URI_FUNC(SetQuery)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetQueryMm)(uri, first, afterLast, NULL);
int URI_FUNC(SetQuery)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetQueryMm)(uri, first, afterLast, NULL);
}
#endif

View File

@@ -40,233 +40,202 @@
#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 "UriSetScheme.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetScheme.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriSetScheme.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetScheme.c"
# undef URI_PASS_UNICODE
# endif
#else
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# include <wchar.h>
# endif
# 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"
# endif
# include <assert.h>
#ifndef URI_DOXYGEN
# include <uriparser/Uri.h>
# include "UriCommon.h"
# include "UriMemory.h"
#endif
# define URI_SET_DIGIT \
_UT('0') : case _UT('1'): \
case _UT('2'): \
case _UT('3'): \
case _UT('4'): \
case _UT('5'): \
case _UT('6'): \
case _UT('7'): \
case _UT('8'): \
case _UT('9')
# define URI_SET_HEX_LETTER_UPPER \
_UT('A') : case _UT('B'): \
case _UT('C'): \
case _UT('D'): \
case _UT('E'): \
case _UT('F')
# define URI_SET_HEX_LETTER_LOWER \
_UT('a') : case _UT('b'): \
case _UT('c'): \
case _UT('d'): \
case _UT('e'): \
case _UT('f')
#include <assert.h>
#define URI_SET_DIGIT \
_UT('0'): \
case _UT('1'): \
case _UT('2'): \
case _UT('3'): \
case _UT('4'): \
case _UT('5'): \
case _UT('6'): \
case _UT('7'): \
case _UT('8'): \
case _UT('9')
#define URI_SET_HEX_LETTER_UPPER \
_UT('A'): \
case _UT('B'): \
case _UT('C'): \
case _UT('D'): \
case _UT('E'): \
case _UT('F')
#define URI_SET_HEX_LETTER_LOWER \
_UT('a'): \
case _UT('b'): \
case _UT('c'): \
case _UT('d'): \
case _UT('e'): \
case _UT('f')
#define URI_SET_HEXDIG \
URI_SET_DIGIT: \
case URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER
#define URI_SET_ALPHA \
URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER: \
case _UT('g'): \
case _UT('G'): \
case _UT('h'): \
case _UT('H'): \
case _UT('i'): \
case _UT('I'): \
case _UT('j'): \
case _UT('J'): \
case _UT('k'): \
case _UT('K'): \
case _UT('l'): \
case _UT('L'): \
case _UT('m'): \
case _UT('M'): \
case _UT('n'): \
case _UT('N'): \
case _UT('o'): \
case _UT('O'): \
case _UT('p'): \
case _UT('P'): \
case _UT('q'): \
case _UT('Q'): \
case _UT('r'): \
case _UT('R'): \
case _UT('s'): \
case _UT('S'): \
case _UT('t'): \
case _UT('T'): \
case _UT('u'): \
case _UT('U'): \
case _UT('v'): \
case _UT('V'): \
case _UT('w'): \
case _UT('W'): \
case _UT('x'): \
case _UT('X'): \
case _UT('y'): \
case _UT('Y'): \
case _UT('z'): \
case _UT('Z')
# define URI_SET_HEXDIG \
URI_SET_DIGIT: \
case URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER
# define URI_SET_ALPHA \
URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER: \
case _UT('g'): \
case _UT('G'): \
case _UT('h'): \
case _UT('H'): \
case _UT('i'): \
case _UT('I'): \
case _UT('j'): \
case _UT('J'): \
case _UT('k'): \
case _UT('K'): \
case _UT('l'): \
case _UT('L'): \
case _UT('m'): \
case _UT('M'): \
case _UT('n'): \
case _UT('N'): \
case _UT('o'): \
case _UT('O'): \
case _UT('p'): \
case _UT('P'): \
case _UT('q'): \
case _UT('Q'): \
case _UT('r'): \
case _UT('R'): \
case _UT('s'): \
case _UT('S'): \
case _UT('t'): \
case _UT('T'): \
case _UT('u'): \
case _UT('U'): \
case _UT('v'): \
case _UT('V'): \
case _UT('w'): \
case _UT('W'): \
case _UT('x'): \
case _UT('X'): \
case _UT('y'): \
case _UT('Y'): \
case _UT('z'): \
case _UT('Z')
UriBool URI_FUNC(IsWellFormedScheme)(const URI_CHAR * first, const URI_CHAR * afterLast) {
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
}
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
}
/* The related part of the grammar in RFC 3986 reads:
*
* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
*/
if (first >= afterLast) {
return URI_FALSE;
}
/* The related part of the grammar in RFC 3986 reads:
*
* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
*/
if (first >= afterLast) {
return URI_FALSE;
}
switch (first[0]) {
case URI_SET_ALPHA:
break;
switch (first[0]) {
case URI_SET_ALPHA:
break;
default:
return URI_FALSE;
}
default:
return URI_FALSE;
}
first++;
first++;
while (first < afterLast) {
switch (first[0]) {
case URI_SET_ALPHA:
case URI_SET_DIGIT:
case _UT('+'):
case _UT('-'):
case _UT('.'):
break;
while (first < afterLast) {
switch (first[0]) {
case URI_SET_ALPHA:
case URI_SET_DIGIT:
case _UT('+'):
case _UT('-'):
case _UT('.'):
break;
default:
return URI_FALSE;
}
default:
return URI_FALSE;
}
first++;
}
return URI_TRUE;
first++;
}
return URI_TRUE;
}
int URI_FUNC(SetSchemeMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast, UriMemoryManager * memory) {
/* Input validation (before making any changes) */
if ((uri == NULL) || ((first == NULL) != (afterLast == NULL))) {
return URI_ERROR_NULL;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
int URI_FUNC(SetSchemeMm)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
/* Input validation (before making any changes) */
if ((uri == NULL) || ((first == NULL) != (afterLast == NULL))) {
return URI_ERROR_NULL;
}
if ((first != NULL)
&& (URI_FUNC(IsWellFormedScheme)(first, afterLast) == URI_FALSE)) {
return URI_ERROR_SYNTAX;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
/* Clear old value */
if ((uri->owner == URI_TRUE) && (uri->scheme.first != uri->scheme.afterLast)) {
memory->free(memory, (URI_CHAR *)uri->scheme.first);
}
uri->scheme.first = NULL;
uri->scheme.afterLast = NULL;
if ((first != NULL) && (URI_FUNC(IsWellFormedScheme)(first, afterLast) == URI_FALSE)) {
return URI_ERROR_SYNTAX;
}
/* Already done setting? */
if (first == NULL) {
/* Yes, but disambiguate as needed */
const UriBool success = URI_FUNC(FixPathNoScheme)(uri, memory);
return (success == URI_TRUE) ? URI_SUCCESS : URI_ERROR_MALLOC;
}
/* Clear old value */
if ((uri->owner == URI_TRUE) && (uri->scheme.first != uri->scheme.afterLast)) {
memory->free(memory, (URI_CHAR *)uri->scheme.first);
}
uri->scheme.first = NULL;
uri->scheme.afterLast = NULL;
assert(first != NULL);
/* Already done setting? */
if (first == NULL) {
/* Yes, but disambiguate as needed */
const UriBool success = URI_FUNC(FixPathNoScheme)(uri, memory);
return (success == URI_TRUE)
? URI_SUCCESS
: URI_ERROR_MALLOC;
}
/* Ensure owned */
if (uri->owner == URI_FALSE) {
const int res = URI_FUNC(MakeOwnerMm)(uri, memory);
if (res != URI_SUCCESS) {
return res;
}
}
assert(first != NULL);
assert(uri->owner == URI_TRUE);
/* Ensure owned */
if (uri->owner == URI_FALSE) {
const int res = URI_FUNC(MakeOwnerMm)(uri, memory);
if (res != URI_SUCCESS) {
return res;
}
}
/* Apply new value */
URI_TYPE(TextRange) sourceRange;
sourceRange.first = first;
sourceRange.afterLast = afterLast;
assert(uri->owner == URI_TRUE);
if (URI_FUNC(CopyRangeAsNeeded)(&uri->scheme, &sourceRange, memory) == URI_FALSE) {
return URI_ERROR_MALLOC;
}
/* 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;
return URI_SUCCESS;
}
int URI_FUNC(SetScheme)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetSchemeMm)(uri, first, afterLast, NULL);
int URI_FUNC(SetScheme)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetSchemeMm)(uri, first, afterLast, NULL);
}
#endif

View File

@@ -40,267 +40,234 @@
#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 "UriSetUserInfo.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetUserInfo.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriSetUserInfo.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriSetUserInfo.c"
# undef URI_PASS_UNICODE
# endif
#else
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# include <wchar.h>
# endif
# 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"
# endif
# include <assert.h>
#ifndef URI_DOXYGEN
# include <uriparser/Uri.h>
# include "UriCommon.h"
# include "UriMemory.h"
#endif
# define URI_SET_DIGIT \
_UT('0') : case _UT('1'): \
case _UT('2'): \
case _UT('3'): \
case _UT('4'): \
case _UT('5'): \
case _UT('6'): \
case _UT('7'): \
case _UT('8'): \
case _UT('9')
# define URI_SET_HEX_LETTER_UPPER \
_UT('A') : case _UT('B'): \
case _UT('C'): \
case _UT('D'): \
case _UT('E'): \
case _UT('F')
# define URI_SET_HEX_LETTER_LOWER \
_UT('a') : case _UT('b'): \
case _UT('c'): \
case _UT('d'): \
case _UT('e'): \
case _UT('f')
#include <assert.h>
# define URI_SET_HEXDIG \
URI_SET_DIGIT: \
case URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER
# define URI_SET_ALPHA \
URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER: \
case _UT('g'): \
case _UT('G'): \
case _UT('h'): \
case _UT('H'): \
case _UT('i'): \
case _UT('I'): \
case _UT('j'): \
case _UT('J'): \
case _UT('k'): \
case _UT('K'): \
case _UT('l'): \
case _UT('L'): \
case _UT('m'): \
case _UT('M'): \
case _UT('n'): \
case _UT('N'): \
case _UT('o'): \
case _UT('O'): \
case _UT('p'): \
case _UT('P'): \
case _UT('q'): \
case _UT('Q'): \
case _UT('r'): \
case _UT('R'): \
case _UT('s'): \
case _UT('S'): \
case _UT('t'): \
case _UT('T'): \
case _UT('u'): \
case _UT('U'): \
case _UT('v'): \
case _UT('V'): \
case _UT('w'): \
case _UT('W'): \
case _UT('x'): \
case _UT('X'): \
case _UT('y'): \
case _UT('Y'): \
case _UT('z'): \
case _UT('Z')
# define URI_SET_SUB_DELIMS \
_UT('!') : case _UT('$'): \
case _UT('&'): \
case _UT('\''): \
case _UT('('): \
case _UT(')'): \
case _UT('*'): \
case _UT('+'): \
case _UT(','): \
case _UT(';'): \
case _UT('=')
#define URI_SET_DIGIT \
_UT('0'): \
case _UT('1'): \
case _UT('2'): \
case _UT('3'): \
case _UT('4'): \
case _UT('5'): \
case _UT('6'): \
case _UT('7'): \
case _UT('8'): \
case _UT('9')
# define URI_SET_UNRESERVED \
URI_SET_ALPHA: \
case URI_SET_DIGIT: \
case _UT('-'): \
case _UT('.'): \
case _UT('_'): \
case _UT('~')
UriBool URI_FUNC(IsWellFormedUserInfo)(const URI_CHAR * first,
const URI_CHAR * afterLast) {
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
}
#define URI_SET_HEX_LETTER_UPPER \
_UT('A'): \
case _UT('B'): \
case _UT('C'): \
case _UT('D'): \
case _UT('E'): \
case _UT('F')
/* userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) */
while (first < afterLast) {
switch (first[0]) {
case URI_SET_UNRESERVED:
break;
/* pct-encoded */
case _UT('%'):
if (afterLast - first < 3) {
return URI_FALSE;
}
switch (first[1]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
switch (first[2]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
first += 2;
break;
case URI_SET_SUB_DELIMS:
break;
#define URI_SET_HEX_LETTER_LOWER \
_UT('a'): \
case _UT('b'): \
case _UT('c'): \
case _UT('d'): \
case _UT('e'): \
case _UT('f')
/* ":" */
case _UT(':'):
break;
default:
return URI_FALSE;
}
#define URI_SET_HEXDIG \
URI_SET_DIGIT: \
case URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER
#define URI_SET_ALPHA \
URI_SET_HEX_LETTER_UPPER: \
case URI_SET_HEX_LETTER_LOWER: \
case _UT('g'): \
case _UT('G'): \
case _UT('h'): \
case _UT('H'): \
case _UT('i'): \
case _UT('I'): \
case _UT('j'): \
case _UT('J'): \
case _UT('k'): \
case _UT('K'): \
case _UT('l'): \
case _UT('L'): \
case _UT('m'): \
case _UT('M'): \
case _UT('n'): \
case _UT('N'): \
case _UT('o'): \
case _UT('O'): \
case _UT('p'): \
case _UT('P'): \
case _UT('q'): \
case _UT('Q'): \
case _UT('r'): \
case _UT('R'): \
case _UT('s'): \
case _UT('S'): \
case _UT('t'): \
case _UT('T'): \
case _UT('u'): \
case _UT('U'): \
case _UT('v'): \
case _UT('V'): \
case _UT('w'): \
case _UT('W'): \
case _UT('x'): \
case _UT('X'): \
case _UT('y'): \
case _UT('Y'): \
case _UT('z'): \
case _UT('Z')
#define URI_SET_SUB_DELIMS \
_UT('!'): \
case _UT('$'): \
case _UT('&'): \
case _UT('\''): \
case _UT('('): \
case _UT(')'): \
case _UT('*'): \
case _UT('+'): \
case _UT(','): \
case _UT(';'): \
case _UT('=')
#define URI_SET_UNRESERVED \
URI_SET_ALPHA: \
case URI_SET_DIGIT: \
case _UT('-'): \
case _UT('.'): \
case _UT('_'): \
case _UT('~')
UriBool URI_FUNC(IsWellFormedUserInfo)(const URI_CHAR * first, const URI_CHAR * afterLast) {
if ((first == NULL) || (afterLast == NULL)) {
return URI_FALSE;
}
/* userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) */
while (first < afterLast) {
switch (first[0]) {
case URI_SET_UNRESERVED:
break;
/* pct-encoded */
case _UT('%'):
if (afterLast - first < 3) {
return URI_FALSE;
}
switch (first[1]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
switch (first[2]) {
case URI_SET_HEXDIG:
break;
default:
return URI_FALSE;
}
first += 2;
break;
case URI_SET_SUB_DELIMS:
break;
/* ":" */
case _UT(':'):
break;
default:
return URI_FALSE;
}
first++;
}
return URI_TRUE;
first++;
}
return URI_TRUE;
}
int URI_FUNC(SetUserInfoMm)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast, UriMemoryManager * memory) {
/* Input validation (before making any changes) */
if ((uri == NULL) || ((first == NULL) != (afterLast == NULL))) {
return URI_ERROR_NULL;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
int URI_FUNC(SetUserInfoMm)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
/* Input validation (before making any changes) */
if ((uri == NULL) || ((first == NULL) != (afterLast == NULL))) {
return URI_ERROR_NULL;
}
/* The RFC 3986 grammar reads:
* authority = [ userinfo "@" ] host [ ":" port ]
* So no user info without a host. */
if ((first != NULL) && (URI_FUNC(HasHost)(uri) == URI_FALSE)) {
return URI_ERROR_SETUSERINFO_HOST_NOT_SET;
}
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
if ((first != NULL)
&& (URI_FUNC(IsWellFormedUserInfo)(first, afterLast) == URI_FALSE)) {
return URI_ERROR_SYNTAX;
}
/* The RFC 3986 grammar reads:
* authority = [ userinfo "@" ] host [ ":" port ]
* So no user info without a host. */
if ((first != NULL) && (URI_FUNC(HasHost)(uri) == URI_FALSE)) {
return URI_ERROR_SETUSERINFO_HOST_NOT_SET;
}
/* Clear old value */
if ((uri->owner == URI_TRUE) && (uri->userInfo.first != uri->userInfo.afterLast)) {
memory->free(memory, (URI_CHAR *)uri->userInfo.first);
}
uri->userInfo.first = NULL;
uri->userInfo.afterLast = NULL;
if ((first != NULL) && (URI_FUNC(IsWellFormedUserInfo)(first, afterLast) == URI_FALSE)) {
return URI_ERROR_SYNTAX;
}
/* Already done? */
if (first == NULL) {
return URI_SUCCESS;
}
/* Clear old value */
if ((uri->owner == URI_TRUE) && (uri->userInfo.first != uri->userInfo.afterLast)) {
memory->free(memory, (URI_CHAR *)uri->userInfo.first);
}
uri->userInfo.first = NULL;
uri->userInfo.afterLast = NULL;
assert(first != NULL);
/* Already done? */
if (first == NULL) {
return URI_SUCCESS;
}
/* Ensure owned */
if (uri->owner == URI_FALSE) {
const int res = URI_FUNC(MakeOwnerMm)(uri, memory);
if (res != URI_SUCCESS) {
return res;
}
}
assert(first != NULL);
assert(uri->owner == URI_TRUE);
/* Ensure owned */
if (uri->owner == URI_FALSE) {
const int res = URI_FUNC(MakeOwnerMm)(uri, memory);
if (res != URI_SUCCESS) {
return res;
}
}
/* Apply new value */
URI_TYPE(TextRange) sourceRange;
sourceRange.first = first;
sourceRange.afterLast = afterLast;
assert(uri->owner == URI_TRUE);
if (URI_FUNC(CopyRangeAsNeeded)(&uri->userInfo, &sourceRange, memory) == URI_FALSE) {
return URI_ERROR_MALLOC;
}
/* 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;
return URI_SUCCESS;
}
int URI_FUNC(SetUserInfo)(URI_TYPE(Uri) * uri,
const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetUserInfoMm)(uri, first, afterLast, NULL);
int URI_FUNC(SetUserInfo)(URI_TYPE(Uri) * uri, const URI_CHAR * first,
const URI_CHAR * afterLast) {
return URI_FUNC(SetUserInfoMm)(uri, first, afterLast, NULL);
}
#endif

View File

@@ -41,284 +41,386 @@
#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 "UriShorten.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriShorten.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriShorten.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriShorten.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"
#endif
# 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"
# endif
static URI_INLINE UriBool URI_FUNC(AppendSegment)(URI_TYPE(Uri) * uri,
const URI_CHAR * first, const URI_CHAR * afterLast,
UriMemoryManager * memory) {
/* Create segment */
URI_TYPE(PathSegment) * segment = memory->malloc(memory, 1 * sizeof(URI_TYPE(PathSegment)));
if (segment == NULL) {
return URI_FALSE; /* Raises malloc error */
}
segment->next = NULL;
segment->text.first = first;
segment->text.afterLast = afterLast;
const URI_CHAR * first,
const URI_CHAR * afterLast,
UriMemoryManager * memory) {
/* Create segment */
URI_TYPE(PathSegment) * segment =
memory->malloc(memory, 1 * sizeof(URI_TYPE(PathSegment)));
if (segment == NULL) {
return URI_FALSE; /* Raises malloc error */
}
segment->next = NULL;
segment->text.first = first;
segment->text.afterLast = afterLast;
/* Put into chain */
if (uri->pathTail == NULL) {
uri->pathHead = segment;
} else {
uri->pathTail->next = segment;
}
uri->pathTail = segment;
/* Put into chain */
if (uri->pathTail == NULL) {
uri->pathHead = segment;
} else {
uri->pathTail->next = segment;
}
uri->pathTail = segment;
return URI_TRUE;
return URI_TRUE;
}
static URI_INLINE UriBool URI_FUNC(EqualsAuthority)(const URI_TYPE(Uri) * first,
const URI_TYPE(Uri) * second) {
/* IPv4 */
if (first->hostData.ip4 != NULL) {
return ((second->hostData.ip4 != NULL)
&& !memcmp(first->hostData.ip4->data,
second->hostData.ip4->data, 4)) ? URI_TRUE : URI_FALSE;
}
const URI_TYPE(Uri) * second) {
/* IPv4 */
if (first->hostData.ip4 != NULL) {
return ((second->hostData.ip4 != NULL)
&& !memcmp(first->hostData.ip4->data, second->hostData.ip4->data, 4))
? URI_TRUE
: URI_FALSE;
}
/* IPv6 */
if (first->hostData.ip6 != NULL) {
return ((second->hostData.ip6 != NULL)
&& !memcmp(first->hostData.ip6->data,
second->hostData.ip6->data, 16)) ? URI_TRUE : URI_FALSE;
}
/* IPv6 */
if (first->hostData.ip6 != NULL) {
return ((second->hostData.ip6 != NULL)
&& !memcmp(first->hostData.ip6->data, second->hostData.ip6->data, 16))
? URI_TRUE
: URI_FALSE;
}
/* IPvFuture */
if (first->hostData.ipFuture.first != NULL) {
return ((second->hostData.ipFuture.first != NULL)
&& !URI_FUNC(CompareRange)(&first->hostData.ipFuture,
&second->hostData.ipFuture)) ? URI_TRUE : URI_FALSE;
}
/* IPvFuture */
if (first->hostData.ipFuture.first != NULL) {
return ((second->hostData.ipFuture.first != NULL)
&& !URI_FUNC(CompareRange)(&first->hostData.ipFuture,
&second->hostData.ipFuture))
? URI_TRUE
: URI_FALSE;
}
return !URI_FUNC(CompareRange)(&first->hostText, &second->hostText)
? URI_TRUE : URI_FALSE;
return !URI_FUNC(CompareRange)(&first->hostText, &second->hostText) ? URI_TRUE
: URI_FALSE;
}
static int URI_FUNC(RemoveBaseUriImpl)(URI_TYPE(Uri) * dest,
const URI_TYPE(Uri) * absSource,
const URI_TYPE(Uri) * absBase,
UriBool domainRootMode, UriMemoryManager * memory) {
if (dest == NULL) {
return URI_ERROR_NULL;
}
URI_FUNC(ResetUri)(dest);
const URI_TYPE(Uri) * absSource,
const URI_TYPE(Uri) * absBase,
UriBool domainRootMode,
UriMemoryManager * memory) {
if (dest == NULL) {
return URI_ERROR_NULL;
}
URI_FUNC(ResetUri)(dest);
if ((absSource == NULL) || (absBase == NULL)) {
return URI_ERROR_NULL;
}
if ((absSource == NULL) || (absBase == NULL)) {
return URI_ERROR_NULL;
}
/* absBase absolute? */
if (absBase->scheme.first == NULL) {
return URI_ERROR_REMOVEBASE_REL_BASE;
}
/* absBase absolute? */
if (absBase->scheme.first == NULL) {
return URI_ERROR_REMOVEBASE_REL_BASE;
}
/* absSource absolute? */
if (absSource->scheme.first == NULL) {
return URI_ERROR_REMOVEBASE_REL_SOURCE;
}
/* absSource absolute? */
if (absSource->scheme.first == NULL) {
return URI_ERROR_REMOVEBASE_REL_SOURCE;
}
/* [01/50] if (A.scheme != Base.scheme) then */
if (URI_FUNC(CompareRange)(&absSource->scheme, &absBase->scheme)) {
/* [02/50] T.scheme = A.scheme; */
dest->scheme = absSource->scheme;
/* [03/50] T.authority = A.authority; */
if (!URI_FUNC(CopyAuthority)(dest, absSource, memory)) {
return URI_ERROR_MALLOC;
}
/* [04/50] T.path = A.path; */
if (!URI_FUNC(CopyPath)(dest, absSource, memory)) {
return URI_ERROR_MALLOC;
}
/* [05/50] else */
} else {
/* [06/50] undef(T.scheme); */
/* NOOP */
/* [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, memory)) {
return URI_ERROR_MALLOC;
}
/* [09/50] T.path = A.path; */
if (!URI_FUNC(CopyPath)(dest, absSource, memory)) {
return URI_ERROR_MALLOC;
}
/* [10/50] else */
} else {
/* [11/50] if domainRootMode then */
if (domainRootMode == URI_TRUE) {
/* [12/50] undef(T.authority); */
/* NOOP */
/* [13/50] if (first(A.path) == "") then */
/* GROUPED */
/* [14/50] T.path = "/." + A.path; */
/* GROUPED */
/* [15/50] else */
/* GROUPED */
/* [16/50] T.path = A.path; */
/* GROUPED */
/* [17/50] endif; */
if (!URI_FUNC(CopyPath)(dest, absSource, memory)) {
return URI_ERROR_MALLOC;
}
dest->absolutePath = URI_TRUE;
/* 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;
}
dest->absolutePath = URI_TRUE;
if (!URI_FUNC(FixAmbiguity)(dest, memory)) {
return URI_ERROR_MALLOC;
}
/* [18/50] else */
} else {
const URI_TYPE(PathSegment) * sourceSeg = absSource->pathHead;
const URI_TYPE(PathSegment) * baseSeg = absBase->pathHead;
/* [19/50] bool pathNaked = true; */
UriBool pathNaked = URI_TRUE;
/* [20/50] undef(last(Base.path)); */
/* NOOP */
/* [21/50] T.path = ""; */
dest->absolutePath = URI_FALSE;
/* [22/50] while (first(A.path) == first(Base.path)) do */
while ((sourceSeg != NULL) && (baseSeg != NULL)
&& !URI_FUNC(CompareRange)(&sourceSeg->text, &baseSeg->text)
&& !((sourceSeg->text.first == sourceSeg->text.afterLast)
&& ((sourceSeg->next == NULL) != (baseSeg->next == NULL)))) {
/* [23/50] A.path++; */
sourceSeg = sourceSeg->next;
/* [24/50] Base.path++; */
baseSeg = baseSeg->next;
/* [25/50] endwhile; */
}
/* [26/50] while defined(first(Base.path)) do */
while ((baseSeg != NULL) && (baseSeg->next != NULL)) {
/* [27/50] Base.path++; */
baseSeg = baseSeg->next;
/* [28/50] T.path += "../"; */
if (!URI_FUNC(AppendSegment)(dest, URI_FUNC(ConstParent),
URI_FUNC(ConstParent) + 2, memory)) {
return URI_ERROR_MALLOC;
}
/* [29/50] pathNaked = false; */
pathNaked = URI_FALSE;
/* [30/50] endwhile; */
}
/* [31/50] while defined(first(A.path)) do */
while (sourceSeg != NULL) {
/* [32/50] if pathNaked then */
if (pathNaked == URI_TRUE) {
/* [33/50] if (first(A.path) contains ":") then */
UriBool containsColon = URI_FALSE;
const URI_CHAR * ch = sourceSeg->text.first;
for (; ch < sourceSeg->text.afterLast; ch++) {
if (*ch == _UT(':')) {
containsColon = URI_TRUE;
break;
}
}
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 != 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++) {
if (*ch == _UT(':')) {
containsColon = URI_TRUE;
break;
}
}
if (containsColon) {
/* [34/50] T.path += "./"; */
if (!URI_FUNC(AppendSegment)(dest, URI_FUNC(ConstPwd),
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, memory)) {
return URI_ERROR_MALLOC;
}
/* [37/50] endif; */
}
/* [38/50] endif; */
}
/* [39/50] T.path += first(A.path); */
if (!URI_FUNC(AppendSegment)(dest, sourceSeg->text.first,
sourceSeg->text.afterLast, memory)) {
return URI_ERROR_MALLOC;
}
/* [40/50] pathNaked = false; */
pathNaked = URI_FALSE;
/* [41/50] A.path++; */
sourceSeg = sourceSeg->next;
/* [42/50] if defined(first(A.path)) then */
/* NOOP */
/* [43/50] T.path += + "/"; */
/* NOOP */
/* [44/50] endif; */
/* NOOP */
/* [45/50] endwhile; */
}
/* [46/50] endif; */
}
/* [47/50] endif; */
}
/* [48/50] endif; */
}
/* [49/50] T.query = A.query; */
dest->query = absSource->query;
/* [50/50] T.fragment = A.fragment; */
dest->fragment = absSource->fragment;
return URI_SUCCESS;
if (containsColon) {
/* clang-format off */
/* [34/50] T.path += "./"; */
/* clang-format on */
if (!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(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;
}
int URI_FUNC(RemoveBaseUri)(URI_TYPE(Uri) * dest,
const URI_TYPE(Uri) * absSource,
const URI_TYPE(Uri) * absBase,
UriBool domainRootMode) {
return URI_FUNC(RemoveBaseUriMm)(dest, absSource, absBase,
domainRootMode, NULL);
int URI_FUNC(RemoveBaseUri)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * absSource,
const URI_TYPE(Uri) * absBase, UriBool 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 */
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(FreeUriMembersMm)(dest, memory);
}
return res;
res = URI_FUNC(RemoveBaseUriImpl)(dest, absSource, absBase, domainRootMode, memory);
if ((res != URI_SUCCESS) && (dest != NULL)) {
URI_FUNC(FreeUriMembersMm)(dest, memory);
}
return res;
}
#endif

View File

@@ -46,42 +46,36 @@
#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 "UriVersion.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriVersion.c"
# undef URI_PASS_UNICODE
# endif
# ifdef URI_ENABLE_ANSI
# define URI_PASS_ANSI 1
# include "UriVersion.c"
# undef URI_PASS_ANSI
# endif
# ifdef URI_ENABLE_UNICODE
# define URI_PASS_UNICODE 1
# include "UriVersion.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>
#endif
# ifdef URI_PASS_ANSI
# include <uriparser/UriDefsAnsi.h>
# else
# include <uriparser/UriDefsUnicode.h>
# include <wchar.h>
# endif
# ifndef URI_DOXYGEN
# include <uriparser/Uri.h>
# endif
const URI_CHAR * URI_FUNC(BaseRuntimeVersion)(void) {
#if defined(URI_PASS_ANSI)
return URI_VER_ANSI;
#elif defined(URI_PASS_UNICODE)
return URI_VER_UNICODE;
#else
# error Either URI_PASS_ANSI or URI_PASS_UNICODE must be defined
#endif
# if defined(URI_PASS_ANSI)
return URI_VER_ANSI;
# elif defined(URI_PASS_UNICODE)
return URI_VER_UNICODE;
# else
# error Either URI_PASS_ANSI or URI_PASS_UNICODE must be defined
# endif
}
#endif