typedef struct URI_TYPE(TextRangeStruct) {
const URI_CHAR * first; /**< Pointer to first character */
const URI_CHAR * afterLast; /**< Pointer to character after the last one still in */
-} URI_TYPE(TextRange);
+} URI_TYPE(TextRange); /**< @copydoc UriTextRangeStructA */
struct URI_TYPE(PathSegmentStruct) * next; /**< Pointer to the next path segment in the list, can be NULL if last already */
void * reserved; /**< Reserved to the parser */
-} URI_TYPE(PathSegment);
+} URI_TYPE(PathSegment); /**< @copydoc UriPathSegmentStructA */
UriIp4 * ip4; /**< IPv4 address */
UriIp6 * ip6; /**< IPv6 address */
URI_TYPE(TextRange) ipFuture; /**< IPvFuture address */
-} URI_TYPE(HostData);
+} URI_TYPE(HostData); /**< @copydoc UriHostDataStructA */
UriBool owner; /**< Memory owner flag */
void * reserved; /**< Reserved to the parser */
-} URI_TYPE(Uri);
+} URI_TYPE(Uri); /**< @copydoc UriUriStructA */
const URI_CHAR * errorPos; /**< Pointer to position in case of a syntax error */
void * reserved; /**< Reserved to the parser */
-} URI_TYPE(ParserState);
+} URI_TYPE(ParserState); /**< @copydoc UriParserStateStructA */
/**
- * Converts an absolute Unix filename to a %URI string.
- * The destination buffer must be large enough to hold
- * 7 + 3 * len(filename) + 1 characters.
+ * Converts a Unix filename to a %URI string.
+ * The destination buffer must be large enough to hold 7 + 3 * len(filename) + 1
+ * characters in case of an absolute filename or 3 * len(filename) + 1 in case
+ * of a relative filename.
*
* EXAMPLE
* Input: "/bin/bash"
/**
- * Converts an absolute Windows filename to a %URI string.
- * The destination buffer must be large enough to hold
- * 8 + 3 * len(filename) + 1 characters.
+ * Converts a Windows filename to a %URI string.
+ * The destination buffer must be large enough to hold 8 + 3 * len(filename) + 1
+ * characters in case of an absolute filename or 3 * len(filename) + 1 in case
+ * of a relative filename.
*
* EXAMPLE
* Input: "E:\\Documents and Settings"
/**
- * Extracts an absolute Unix filename from a %URI string.
- * The destination buffer must be large enough to hold
- * len(uriString) + 1 - 7 characters.
+ * Extracts a Unix filename from a %URI string.
+ * The destination buffer must be large enough to hold len(uriString) + 1 - 7
+ * characters in case of an absolute %URI or len(uriString) + 1 in case
+ * of a relative %URI.
*
* @param uriString %URI string to convert
* @param filename Destination to write filename to
/**
- * Extracts an absolute Windows filename from a %URI string.
- * The destination buffer must be large enough to hold
- * len(uriString) + 1 - 8 characters.
+ * Extracts a Windows filename from a %URI string.
+ * The destination buffer must be large enough to hold len(uriString) + 1 - 8
+ * characters in case of an absolute %URI or len(uriString) + 1 in case
+ * of a relative %URI.
*
* @param uriString %URI string to convert
* @param filename Destination to write filename to
/* Version */
#define URI_VER_MAJOR 0
-#define URI_VER_MINOR 5
-#define URI_VER_RELEASE 2
+#define URI_VER_MINOR 6
+#define URI_VER_RELEASE 4
#define URI_VER_SUFFIX_ANSI ""
#define URI_VER_SUFFIX_UNICODE URI_ANSI_TO_UNICODE(URI_VER_SUFFIX_ANSI)
*/
typedef struct UriIp4Struct {
unsigned char data[4]; /**< Each octet in one byte */
-} UriIp4;
+} UriIp4; /**< @copydoc UriIp4Struct */
*/
typedef struct UriIp6Struct {
unsigned char data[16]; /**< Each quad in two bytes */
-} UriIp6;
+} UriIp6; /**< @copydoc UriIp6Struct */
* Specifies a line break conversion mode
*/
typedef enum UriBreakConversionEnum {
- URI_BR_TO_LF,
- URI_BR_TO_CRLF,
- URI_BR_TO_CR,
- URI_BR_TO_UNIX = URI_BR_TO_LF,
- URI_BR_TO_WINDOWS = URI_BR_TO_CRLF,
- URI_BR_TO_MAC = URI_BR_TO_CR,
- URI_BR_DONT_TOUCH
-} UriBreakConversion;
+ 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,
- URI_NORMALIZE_SCHEME = 1 << 0, /* Because of uppercase letters */
- URI_NORMALIZE_USER_INFO = 1 << 1, /* .. uppercase percent-encodings */
- URI_NORMALIZE_HOST = 1 << 2, /* .. uppercase letters */
- URI_NORMALIZE_PATH = 1 << 3, /* .. uppercase percent-encodings or dot segments */
- URI_NORMALIZE_QUERY = 1 << 4, /* .. uppercase percent-encodings */
- URI_NORMALIZE_FRAGMENT = 1 << 5 /* .. uppercase percent-encodings */
-} UriNormalizationMask;
+ 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) */
+} UriNormalizationMask; /**< @copydoc UriNormalizationMaskEnum */
-/*\r
- * uriparser - RFC 3986 URI parsing library\r
- *\r
- * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>\r
- * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- *\r
- * * Redistributions of source code must retain the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer.\r
- *\r
- * * Redistributions in binary form must reproduce the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer in the documentation and/or other materials\r
- * provided with the distribution.\r
- *\r
- * * Neither the name of the <ORGANIZATION> nor the names of its\r
- * contributors may be used to endorse or promote products\r
- * derived from this software without specific prior written\r
- * permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
- * OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/* What encodings are enabled? */\r
-#include <uriparser/UriDefsConfig.h>\r
-#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))\r
-/* Include SELF twice */\r
-# define URI_PASS_ANSI 1\r
-# include "UriCommon.c"\r
-# undef URI_PASS_ANSI\r
-# define URI_PASS_UNICODE 1\r
-# include "UriCommon.c"\r
-# undef URI_PASS_UNICODE\r
-#else\r
-# ifdef URI_PASS_ANSI\r
-# include <uriparser/UriDefsAnsi.h>\r
-# else\r
-# include <uriparser/UriDefsUnicode.h>\r
-# include <wchar.h>\r
-# endif\r
-\r
-\r
-\r
-#ifndef URI_DOXYGEN\r
-# include <uriparser/Uri.h>\r
-# include "UriCommon.h"\r
-#endif\r
-\r
-\r
-\r
-/*extern*/ const URI_CHAR * const URI_FUNC(SafeToPointTo) = _UT("X");\r
-/*extern*/ const URI_CHAR * const URI_FUNC(ConstPwd) = _UT(".");\r
-/*extern*/ const URI_CHAR * const URI_FUNC(ConstParent) = _UT("..");\r
-\r
-\r
-\r
-void URI_FUNC(ResetUri)(URI_TYPE(Uri) * uri) {\r
- memset(uri, 0, sizeof(URI_TYPE(Uri)));\r
-}\r
-\r
-\r
-\r
-/* Properly removes "." and ".." path segments */\r
-UriBool URI_FUNC(RemoveDotSegments)(URI_TYPE(Uri) * uri) {\r
- URI_TYPE(PathSegment) * walker;\r
- if ((uri == NULL) || (uri->pathHead == NULL)) {\r
- return URI_TRUE;\r
- }\r
-\r
- walker = uri->pathHead;\r
- walker->reserved = NULL; /* Prev pointer */\r
- do {\r
- int len = (int)(walker->text.afterLast - walker->text.first);\r
- switch (len) {\r
- case 1:\r
- if ((walker->text.first)[0] == _UT('.')) {\r
- /* Path "." -> remove this segment */\r
- URI_TYPE(PathSegment) * const prev = walker->reserved;\r
- URI_TYPE(PathSegment) * const nextBackup = walker->next;\r
-\r
- /* Last segment? */\r
- if (walker->next != NULL) {\r
- /* Not last segment */\r
- walker->next->reserved = prev;\r
-\r
- if (prev == NULL) {\r
- /* First but not last segment */\r
- uri->pathHead = walker->next;\r
- } else {\r
- /* Middle segment */\r
- prev->next = walker->next;\r
- }\r
-\r
- if (uri->owner) {\r
- free((URI_CHAR *)walker->text.first);\r
- }\r
- free(walker);\r
- } else {\r
- /* Last segment */\r
- if (prev == NULL) {\r
- /* Last and first */\r
- if (uri->owner) {\r
- free((URI_CHAR *)walker->text.first);\r
- }\r
- free(walker);\r
-\r
- uri->pathHead = NULL;\r
- uri->pathTail = NULL;\r
- } else {\r
- /* Last but not first, replace "." with empty segment to represent trailing slash */\r
- if (uri->owner) {\r
- free((URI_CHAR *)walker->text.first);\r
- }\r
- walker->text.first = URI_FUNC(SafeToPointTo);\r
- walker->text.afterLast = URI_FUNC(SafeToPointTo);\r
- }\r
- }\r
-\r
- walker = nextBackup;\r
- } else {\r
- if (walker->next != NULL) {\r
- walker->next->reserved = walker;\r
- } else {\r
- /* Last segment -> update tail */\r
- uri->pathTail = walker;\r
- }\r
- walker = walker->next;\r
- }\r
- break;\r
-\r
- case 2:\r
- if (((walker->text.first)[0] == _UT('.'))\r
- && ((walker->text.first)[1] == _UT('.'))) {\r
- /* Path ".." -> remove this and the previous segment */\r
- URI_TYPE(PathSegment) * const prev = walker->reserved;\r
- URI_TYPE(PathSegment) * prevPrev;\r
- URI_TYPE(PathSegment) * const nextBackup = walker->next;\r
- if (prev != NULL) {\r
- /* Not first segment */\r
- prevPrev = prev->reserved;\r
- if (prevPrev != NULL) {\r
- /* Not even prev is the first one */\r
- prevPrev->next = walker->next;\r
- if (walker->next != NULL) {\r
- walker->next->reserved = prevPrev;\r
- } else {\r
- /* Last segment -> insert "" segment to represent trailing slash, update tail */\r
- URI_TYPE(PathSegment) * const segment = malloc(1 * sizeof(URI_TYPE(PathSegment)));\r
- if (segment == NULL) {\r
- if (uri->owner) {\r
- free((URI_CHAR *)walker->text.first);\r
- }\r
- free(walker);\r
-\r
- if (uri->owner) {\r
- free((URI_CHAR *)prev->text.first);\r
- }\r
- free(prev);\r
-\r
- return URI_FALSE; /* Raises malloc error */\r
- }\r
- memset(segment, 0, sizeof(URI_TYPE(PathSegment)));\r
- segment->text.first = URI_FUNC(SafeToPointTo);\r
- segment->text.afterLast = URI_FUNC(SafeToPointTo);\r
- prevPrev->next = segment;\r
- uri->pathTail = segment;\r
- }\r
-\r
- if (uri->owner) {\r
- free((URI_CHAR *)walker->text.first);\r
- }\r
- free(walker);\r
-\r
- if (uri->owner) {\r
- free((URI_CHAR *)prev->text.first);\r
- }\r
- free(prev);\r
-\r
- walker = nextBackup;\r
- } else {\r
- /* Prev is the first segment */\r
- uri->pathHead = walker->next;\r
- if (walker->next != NULL) {\r
- walker->next->reserved = NULL;\r
- } else {\r
- /* Last segment -> update tail */\r
- uri->pathTail = NULL;\r
- }\r
-\r
- if (uri->owner) {\r
- free((URI_CHAR *)walker->text.first);\r
- }\r
- free(walker);\r
-\r
- if (uri->owner) {\r
- free((URI_CHAR *)prev->text.first);\r
- }\r
- free(prev);\r
-\r
- walker = nextBackup;\r
- }\r
- } else {\r
- URI_TYPE(PathSegment) * const nextBackup = walker->next;\r
- /* First segment -> update head pointer */\r
- uri->pathHead = walker->next;\r
- if (walker->next != NULL) {\r
- walker->next->reserved = NULL;\r
- } else {\r
- /* Last segment -> update tail */\r
- uri->pathTail = NULL;\r
- }\r
-\r
- if (uri->owner) {\r
- free((URI_CHAR *)walker->text.first);\r
- }\r
- free(walker);\r
-\r
- walker = nextBackup;\r
- }\r
- } else {\r
- if (walker->next != NULL) {\r
- walker->next->reserved = walker;\r
- } else {\r
- /* Last segment -> update tail */\r
- uri->pathTail = walker;\r
- }\r
- walker = walker->next;\r
- }\r
- break;\r
-\r
- default:\r
- if (walker->next != NULL) {\r
- walker->next->reserved = walker;\r
- } else {\r
- /* Last segment -> update tail */\r
- uri->pathTail = walker;\r
- }\r
- walker = walker->next;\r
- break;\r
-\r
- }\r
- } while (walker != NULL);\r
-\r
- /* Fix path if only one empty segment */\r
- if ((uri->pathHead != NULL)\r
- && (uri->pathHead->next == NULL)\r
- && (uri->pathHead->text.first == uri->pathHead->text.afterLast)) {\r
- free(uri->pathHead);\r
- uri->pathHead = NULL;\r
- uri->pathTail = NULL;\r
- }\r
-\r
- return URI_TRUE;\r
-}\r
-\r
-\r
-\r
-unsigned char URI_FUNC(HexdigToInt)(URI_CHAR hexdig) {\r
- switch (hexdig) {\r
- case _UT('0'):\r
- case _UT('1'):\r
- case _UT('2'):\r
- case _UT('3'):\r
- case _UT('4'):\r
- case _UT('5'):\r
- case _UT('6'):\r
- case _UT('7'):\r
- case _UT('8'):\r
- case _UT('9'):\r
- return (unsigned char)(9 + hexdig - _UT('9'));\r
-\r
- case _UT('a'):\r
- case _UT('b'):\r
- case _UT('c'):\r
- case _UT('d'):\r
- case _UT('e'):\r
- case _UT('f'):\r
- return (unsigned char)(15 + hexdig - _UT('f'));\r
-\r
- case _UT('A'):\r
- case _UT('B'):\r
- case _UT('C'):\r
- case _UT('D'):\r
- case _UT('E'):\r
- case _UT('F'):\r
- return (unsigned char)(15 + hexdig - _UT('F'));\r
-\r
- default:\r
- return 0;\r
- }\r
-}\r
-\r
-\r
-\r
-URI_CHAR URI_FUNC(HexToLetter)(unsigned int value) {\r
- switch (value) {\r
- case 0: return _UT('0');\r
- case 1: return _UT('1');\r
- case 2: return _UT('2');\r
- case 3: return _UT('3');\r
- case 4: return _UT('4');\r
- case 5: return _UT('5');\r
- case 6: return _UT('6');\r
- case 7: return _UT('7');\r
- case 8: return _UT('8');\r
- case 9: return _UT('9');\r
-\r
- /* Uppercase recommended in section 2.1. of RFC 3986 *\r
- * http://tools.ietf.org/html/rfc3986#section-2.1 */\r
- case 10: return _UT('A');\r
- case 11: return _UT('B');\r
- case 12: return _UT('C');\r
- case 13: return _UT('D');\r
- case 14: return _UT('E');\r
- default: return _UT('F');\r
- }\r
-}\r
-\r
-\r
-\r
-/* Checks if a URI has the host component set. */\r
-UriBool URI_FUNC(IsHostSet)(const URI_TYPE(Uri) * uri) {\r
- return (uri != NULL)\r
- && ((uri->hostText.first != NULL)\r
- || (uri->hostData.ip4 != NULL)\r
- || (uri->hostData.ip6 != NULL)\r
- || (uri->hostData.ipFuture.first != NULL)\r
- );\r
-}\r
-\r
-\r
-\r
-/* Copies the path segment list from one URI to another. */\r
-UriBool URI_FUNC(CopyPath)(URI_TYPE(Uri) * dest,\r
- const URI_TYPE(Uri) * source) {\r
- if (source->pathHead == NULL) {\r
- /* No path component */\r
- dest->pathHead = NULL;\r
- dest->pathTail = NULL;\r
- } else {\r
- /* Copy list but not the text contained */\r
- URI_TYPE(PathSegment) * sourceWalker = source->pathHead;\r
- URI_TYPE(PathSegment) * destPrev = NULL;\r
- do {\r
- URI_TYPE(PathSegment) * cur = malloc(sizeof(URI_TYPE(PathSegment)));\r
- if (cur == NULL) {\r
- /* Fix broken list */\r
- if (destPrev != NULL) {\r
- destPrev->next = NULL;\r
- }\r
- return URI_FALSE; /* Raises malloc error */\r
- }\r
-\r
- /* From this functions usage we know that *\r
- * the dest URI cannot be uri->owner */\r
- cur->text = sourceWalker->text;\r
- if (destPrev == NULL) {\r
- /* First segment ever */\r
- dest->pathHead = cur;\r
- } else {\r
- destPrev->next = cur;\r
- }\r
- destPrev = cur;\r
- sourceWalker = sourceWalker->next;\r
- } while (sourceWalker != NULL);\r
- dest->pathTail = destPrev;\r
- dest->pathTail->next = NULL;\r
- }\r
-\r
- dest->absolutePath = source->absolutePath;\r
- return URI_TRUE;\r
-}\r
-\r
-\r
-\r
-/* Copies the authority part of an URI over to another. */\r
-UriBool URI_FUNC(CopyAuthority)(URI_TYPE(Uri) * dest,\r
- const URI_TYPE(Uri) * source) {\r
- /* From this functions usage we know that *\r
- * the dest URI cannot be uri->owner */\r
-\r
- /* Copy userInfo */\r
- dest->userInfo = source->userInfo;\r
-\r
- /* Copy hostText */\r
- dest->hostText = source->hostText;\r
-\r
- /* Copy hostData */\r
- if (source->hostData.ip4 != NULL) {\r
- dest->hostData.ip4 = malloc(sizeof(UriIp4));\r
- if (dest->hostData.ip4 == NULL) {\r
- return URI_FALSE; /* Raises malloc error */\r
- }\r
- *(dest->hostData.ip4) = *(source->hostData.ip4);\r
- dest->hostData.ip6 = NULL;\r
- dest->hostData.ipFuture.first = NULL;\r
- dest->hostData.ipFuture.afterLast = NULL;\r
- } else if (source->hostData.ip6 != NULL) {\r
- dest->hostData.ip4 = NULL;\r
- dest->hostData.ip6 = malloc(sizeof(UriIp6));\r
- if (dest->hostData.ip6 == NULL) {\r
- return URI_FALSE; /* Raises malloc error */\r
- }\r
- *(dest->hostData.ip6) = *(source->hostData.ip6);\r
- dest->hostData.ipFuture.first = NULL;\r
- dest->hostData.ipFuture.afterLast = NULL;\r
- } else {\r
- dest->hostData.ip4 = NULL;\r
- dest->hostData.ip6 = NULL;\r
- dest->hostData.ipFuture = source->hostData.ipFuture;\r
- }\r
-\r
- /* Copy portText */\r
- dest->portText = source->portText;\r
-\r
- return URI_TRUE;\r
-}\r
-\r
-\r
-\r
-UriBool URI_FUNC(FixAmbiguity)(URI_TYPE(Uri) * uri) {\r
- URI_TYPE(PathSegment) * segment;\r
-\r
- if ( /* Case 1: absolute path, empty first segment */\r
- (uri->absolutePath\r
- && (uri->pathHead != NULL)\r
- && (uri->pathHead->text.afterLast == uri->pathHead->text.first))\r
-\r
- /* Case 2: relative path, empty first and second segment */\r
- || (!uri->absolutePath\r
- && (uri->pathHead != NULL)\r
- && (uri->pathHead->next != NULL)\r
- && (uri->pathHead->text.afterLast == uri->pathHead->text.first)\r
- && (uri->pathHead->next->text.afterLast == uri->pathHead->next->text.first))) {\r
- /* NOOP */\r
- } else {\r
- return URI_TRUE;\r
- }\r
-\r
- segment = malloc(1 * sizeof(URI_TYPE(PathSegment)));\r
- if (segment == NULL) {\r
- return URI_FALSE; /* Raises malloc error */\r
- }\r
-\r
- /* Insert "." segment in front */\r
- segment->next = uri->pathHead;\r
- segment->text.first = URI_FUNC(ConstPwd);\r
- segment->text.afterLast = URI_FUNC(ConstPwd) + 1;\r
- uri->pathHead = segment;\r
- return URI_TRUE;\r
-}\r
-\r
-\r
-\r
-#endif\r
+/*
+ * uriparser - RFC 3986 URI parsing library
+ *
+ * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>
+ * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the <ORGANIZATION> nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* What encodings are enabled? */
+#include <uriparser/UriDefsConfig.h>
+#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
+/* Include SELF twice */
+# define URI_PASS_ANSI 1
+# include "UriCommon.c"
+# undef URI_PASS_ANSI
+# define URI_PASS_UNICODE 1
+# include "UriCommon.c"
+# undef URI_PASS_UNICODE
+#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"
+#endif
+
+
+
+/*extern*/ const URI_CHAR * const URI_FUNC(SafeToPointTo) = _UT("X");
+/*extern*/ const URI_CHAR * const URI_FUNC(ConstPwd) = _UT(".");
+/*extern*/ const URI_CHAR * const URI_FUNC(ConstParent) = _UT("..");
+
+
+
+void URI_FUNC(ResetUri)(URI_TYPE(Uri) * uri) {
+ memset(uri, 0, sizeof(URI_TYPE(Uri)));
+}
+
+
+
+/* Properly removes "." and ".." path segments */
+UriBool URI_FUNC(RemoveDotSegments)(URI_TYPE(Uri) * uri,
+ UriBool relative) {
+ URI_TYPE(PathSegment) * walker;
+ if ((uri == NULL) || (uri->pathHead == NULL)) {
+ return URI_TRUE;
+ }
+
+ walker = uri->pathHead;
+ walker->reserved = NULL; /* Prev pointer */
+ do {
+ UriBool removeSegment = URI_FALSE;
+ int len = (int)(walker->text.afterLast - walker->text.first);
+ switch (len) {
+ case 1:
+ if ((walker->text.first)[0] == _UT('.')) {
+ /* "." segment -> remove if not essential */
+ URI_TYPE(PathSegment) * const prev = walker->reserved;
+ URI_TYPE(PathSegment) * const nextBackup = walker->next;
+
+ /* Is this dot segment essential? */
+ removeSegment = URI_TRUE;
+ if (relative && (walker == uri->pathHead) && (walker->next != NULL)) {
+ const URI_CHAR * ch = walker->next->text.first;
+ for (; ch < walker->next->text.afterLast; ch++) {
+ if (*ch == _UT(':')) {
+ removeSegment = URI_FALSE;
+ break;
+ }
+ }
+ }
+
+ if (removeSegment) {
+ /* Last segment? */
+ if (walker->next != NULL) {
+ /* Not last segment */
+ walker->next->reserved = prev;
+
+ if (prev == NULL) {
+ /* First but not last segment */
+ uri->pathHead = walker->next;
+ } else {
+ /* Middle segment */
+ prev->next = walker->next;
+ }
+
+ if (uri->owner && (walker->text.first != walker->text.afterLast)) {
+ free((URI_CHAR *)walker->text.first);
+ }
+ free(walker);
+ } else {
+ /* Last segment */
+ if (prev == NULL) {
+ /* Last and first */
+ if (uri->owner && (walker->text.first != walker->text.afterLast)) {
+ free((URI_CHAR *)walker->text.first);
+ }
+ free(walker);
+
+ uri->pathHead = NULL;
+ uri->pathTail = NULL;
+ } else {
+ /* Last but not first, replace "." with empty segment to represent trailing slash */
+ if (uri->owner && (walker->text.first != walker->text.afterLast)) {
+ free((URI_CHAR *)walker->text.first);
+ }
+ walker->text.first = URI_FUNC(SafeToPointTo);
+ walker->text.afterLast = URI_FUNC(SafeToPointTo);
+ }
+ }
+
+ walker = nextBackup;
+ }
+ }
+ break;
+
+ case 2:
+ if (((walker->text.first)[0] == _UT('.'))
+ && ((walker->text.first)[1] == _UT('.'))) {
+ /* Path ".." -> remove this and the previous segment */
+ URI_TYPE(PathSegment) * const prev = walker->reserved;
+ URI_TYPE(PathSegment) * prevPrev;
+ URI_TYPE(PathSegment) * const nextBackup = walker->next;
+
+ removeSegment = URI_TRUE;
+ if (relative) {
+ if (prev == NULL) {
+ removeSegment = URI_FALSE;
+ } else if ((prev != NULL)
+ && ((prev->text.afterLast - prev->text.first) == 2)
+ && ((prev->text.first)[0] == _UT('.'))
+ && ((prev->text.first)[1] == _UT('.'))) {
+ removeSegment = URI_FALSE;
+ }
+ }
+
+ if (removeSegment) {
+ if (prev != NULL) {
+ /* Not first segment */
+ prevPrev = prev->reserved;
+ if (prevPrev != NULL) {
+ /* Not even prev is the first one */
+ prevPrev->next = walker->next;
+ if (walker->next != NULL) {
+ walker->next->reserved = prevPrev;
+ } else {
+ /* Last segment -> insert "" segment to represent trailing slash, update tail */
+ URI_TYPE(PathSegment) * const segment = malloc(1 * sizeof(URI_TYPE(PathSegment)));
+ if (segment == NULL) {
+ if (uri->owner && (walker->text.first != walker->text.afterLast)) {
+ free((URI_CHAR *)walker->text.first);
+ }
+ free(walker);
+
+ if (uri->owner && (prev->text.first != prev->text.afterLast)) {
+ free((URI_CHAR *)prev->text.first);
+ }
+ free(prev);
+
+ return URI_FALSE; /* Raises malloc error */
+ }
+ memset(segment, 0, sizeof(URI_TYPE(PathSegment)));
+ segment->text.first = URI_FUNC(SafeToPointTo);
+ segment->text.afterLast = URI_FUNC(SafeToPointTo);
+ prevPrev->next = segment;
+ uri->pathTail = segment;
+ }
+
+ if (uri->owner && (walker->text.first != walker->text.afterLast)) {
+ free((URI_CHAR *)walker->text.first);
+ }
+ free(walker);
+
+ if (uri->owner && (prev->text.first != prev->text.afterLast)) {
+ free((URI_CHAR *)prev->text.first);
+ }
+ free(prev);
+
+ walker = nextBackup;
+ } else {
+ /* Prev is the first segment */
+ uri->pathHead = walker->next;
+ if (walker->next != NULL) {
+ walker->next->reserved = NULL;
+ } else {
+ /* Last segment -> update tail */
+ uri->pathTail = NULL;
+ }
+
+ if (uri->owner && (walker->text.first != walker->text.afterLast)) {
+ free((URI_CHAR *)walker->text.first);
+ }
+ free(walker);
+
+ if (uri->owner && (prev->text.first != prev->text.afterLast)) {
+ free((URI_CHAR *)prev->text.first);
+ }
+ free(prev);
+
+ walker = nextBackup;
+ }
+ } else {
+ URI_TYPE(PathSegment) * const nextBackup = walker->next;
+ /* First segment -> update head pointer */
+ uri->pathHead = walker->next;
+ if (walker->next != NULL) {
+ walker->next->reserved = NULL;
+ } else {
+ /* Last segment -> update tail */
+ uri->pathTail = NULL;
+ }
+
+ if (uri->owner && (walker->text.first != walker->text.afterLast)) {
+ free((URI_CHAR *)walker->text.first);
+ }
+ free(walker);
+
+ walker = nextBackup;
+ }
+ }
+ }
+ break;
+
+ }
+
+ if (!removeSegment) {
+ if (walker->next != NULL) {
+ walker->next->reserved = walker;
+ } else {
+ /* Last segment -> update tail */
+ uri->pathTail = walker;
+ }
+ walker = walker->next;
+ }
+ } while (walker != NULL);
+
+ /* Fix path if only one empty segment */
+ if ((uri->pathHead != NULL)
+ && (uri->pathHead->next == NULL)
+ && (uri->pathHead->text.first == uri->pathHead->text.afterLast)) {
+ free(uri->pathHead);
+ uri->pathHead = NULL;
+ uri->pathTail = NULL;
+ }
+
+ return URI_TRUE;
+}
+
+
+
+/* Properly removes "." and ".." path segments */
+UriBool URI_FUNC(RemoveDotSegmentsAbsolute)(URI_TYPE(Uri) * uri) {
+ const UriBool ABSOLUTE = URI_FALSE;
+ return URI_FUNC(RemoveDotSegments)(uri, ABSOLUTE);
+}
+
+
+
+unsigned char URI_FUNC(HexdigToInt)(URI_CHAR hexdig) {
+ switch (hexdig) {
+ 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'):
+ return (unsigned char)(9 + hexdig - _UT('9'));
+
+ case _UT('a'):
+ case _UT('b'):
+ case _UT('c'):
+ case _UT('d'):
+ case _UT('e'):
+ case _UT('f'):
+ return (unsigned char)(15 + hexdig - _UT('f'));
+
+ case _UT('A'):
+ case _UT('B'):
+ case _UT('C'):
+ case _UT('D'):
+ case _UT('E'):
+ case _UT('F'):
+ return (unsigned char)(15 + hexdig - _UT('F'));
+
+ default:
+ return 0;
+ }
+}
+
+
+
+URI_CHAR URI_FUNC(HexToLetter)(unsigned int value) {
+ switch (value) {
+ case 0: return _UT('0');
+ case 1: return _UT('1');
+ case 2: return _UT('2');
+ case 3: return _UT('3');
+ case 4: return _UT('4');
+ case 5: return _UT('5');
+ case 6: return _UT('6');
+ case 7: return _UT('7');
+ case 8: return _UT('8');
+ case 9: return _UT('9');
+
+ /* Uppercase recommended in section 2.1. of RFC 3986 *
+ * http://tools.ietf.org/html/rfc3986#section-2.1 */
+ case 10: return _UT('A');
+ case 11: return _UT('B');
+ case 12: return _UT('C');
+ case 13: return _UT('D');
+ case 14: return _UT('E');
+ default: return _UT('F');
+ }
+}
+
+
+
+/* Checks if a URI has the host component set. */
+UriBool URI_FUNC(IsHostSet)(const URI_TYPE(Uri) * uri) {
+ return (uri != NULL)
+ && ((uri->hostText.first != NULL)
+ || (uri->hostData.ip4 != NULL)
+ || (uri->hostData.ip6 != NULL)
+ || (uri->hostData.ipFuture.first != NULL)
+ );
+}
+
+
+
+/* Copies the path segment list from one URI to another. */
+UriBool URI_FUNC(CopyPath)(URI_TYPE(Uri) * dest,
+ const URI_TYPE(Uri) * source) {
+ if (source->pathHead == NULL) {
+ /* No path component */
+ dest->pathHead = NULL;
+ dest->pathTail = NULL;
+ } else {
+ /* Copy list but not the text contained */
+ URI_TYPE(PathSegment) * sourceWalker = source->pathHead;
+ URI_TYPE(PathSegment) * destPrev = NULL;
+ do {
+ URI_TYPE(PathSegment) * cur = malloc(sizeof(URI_TYPE(PathSegment)));
+ if (cur == NULL) {
+ /* Fix broken list */
+ if (destPrev != NULL) {
+ destPrev->next = NULL;
+ }
+ return URI_FALSE; /* Raises malloc error */
+ }
+
+ /* From this functions usage we know that *
+ * the dest URI cannot be uri->owner */
+ cur->text = sourceWalker->text;
+ if (destPrev == NULL) {
+ /* First segment ever */
+ dest->pathHead = cur;
+ } else {
+ destPrev->next = cur;
+ }
+ destPrev = cur;
+ sourceWalker = sourceWalker->next;
+ } while (sourceWalker != NULL);
+ dest->pathTail = destPrev;
+ dest->pathTail->next = NULL;
+ }
+
+ dest->absolutePath = source->absolutePath;
+ return URI_TRUE;
+}
+
+
+
+/* Copies the authority part of an URI over to another. */
+UriBool URI_FUNC(CopyAuthority)(URI_TYPE(Uri) * dest,
+ const URI_TYPE(Uri) * source) {
+ /* From this functions usage we know that *
+ * the dest URI cannot be uri->owner */
+
+ /* Copy userInfo */
+ dest->userInfo = source->userInfo;
+
+ /* Copy hostText */
+ dest->hostText = source->hostText;
+
+ /* Copy hostData */
+ if (source->hostData.ip4 != NULL) {
+ dest->hostData.ip4 = malloc(sizeof(UriIp4));
+ if (dest->hostData.ip4 == NULL) {
+ return URI_FALSE; /* Raises malloc error */
+ }
+ *(dest->hostData.ip4) = *(source->hostData.ip4);
+ dest->hostData.ip6 = NULL;
+ dest->hostData.ipFuture.first = NULL;
+ dest->hostData.ipFuture.afterLast = NULL;
+ } else if (source->hostData.ip6 != NULL) {
+ dest->hostData.ip4 = NULL;
+ dest->hostData.ip6 = malloc(sizeof(UriIp6));
+ if (dest->hostData.ip6 == NULL) {
+ return URI_FALSE; /* Raises malloc error */
+ }
+ *(dest->hostData.ip6) = *(source->hostData.ip6);
+ dest->hostData.ipFuture.first = NULL;
+ dest->hostData.ipFuture.afterLast = NULL;
+ } else {
+ dest->hostData.ip4 = NULL;
+ dest->hostData.ip6 = NULL;
+ dest->hostData.ipFuture = source->hostData.ipFuture;
+ }
+
+ /* Copy portText */
+ dest->portText = source->portText;
+
+ return URI_TRUE;
+}
+
+
+
+UriBool URI_FUNC(FixAmbiguity)(URI_TYPE(Uri) * uri) {
+ URI_TYPE(PathSegment) * segment;
+
+ if ( /* Case 1: absolute path, empty first segment */
+ (uri->absolutePath
+ && (uri->pathHead != NULL)
+ && (uri->pathHead->text.afterLast == uri->pathHead->text.first))
+
+ /* Case 2: relative path, empty first and second segment */
+ || (!uri->absolutePath
+ && (uri->pathHead != NULL)
+ && (uri->pathHead->next != NULL)
+ && (uri->pathHead->text.afterLast == uri->pathHead->text.first)
+ && (uri->pathHead->next->text.afterLast == uri->pathHead->next->text.first))) {
+ /* NOOP */
+ } else {
+ return URI_TRUE;
+ }
+
+ segment = malloc(1 * sizeof(URI_TYPE(PathSegment)));
+ if (segment == NULL) {
+ return URI_FALSE; /* Raises malloc error */
+ }
+
+ /* Insert "." segment in front */
+ segment->next = uri->pathHead;
+ segment->text.first = URI_FUNC(ConstPwd);
+ segment->text.afterLast = URI_FUNC(ConstPwd) + 1;
+ uri->pathHead = segment;
+ return URI_TRUE;
+}
+
+
+
+#endif
-/*\r
- * uriparser - RFC 3986 URI parsing library\r
- *\r
- * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>\r
- * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- *\r
- * * Redistributions of source code must retain the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer.\r
- *\r
- * * Redistributions in binary form must reproduce the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer in the documentation and/or other materials\r
- * provided with the distribution.\r
- *\r
- * * Neither the name of the <ORGANIZATION> nor the names of its\r
- * contributors may be used to endorse or promote products\r
- * derived from this software without specific prior written\r
- * permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
- * OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#if (defined(URI_PASS_ANSI) && !defined(URI_COMMON_H_ANSI)) \\r
- || (defined(URI_PASS_UNICODE) && !defined(URI_COMMON_H_UNICODE)) \\r
- || (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))\r
-/* What encodings are enabled? */\r
-#include <uriparser/UriDefsConfig.h>\r
-#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))\r
-/* Include SELF twice */\r
-# define URI_PASS_ANSI 1\r
-# include "UriCommon.h"\r
-# undef URI_PASS_ANSI\r
-# define URI_PASS_UNICODE 1\r
-# include "UriCommon.h"\r
-# undef URI_PASS_UNICODE\r
-/* Only one pass for each encoding */\r
-#elif (defined(URI_PASS_ANSI) && !defined(URI_COMMON_H_ANSI) \\r
- && defined(URI_ENABLE_ANSI)) || (defined(URI_PASS_UNICODE) \\r
- && !defined(URI_COMMON_H_UNICODE) && defined(URI_ENABLE_UNICODE))\r
-# ifdef URI_PASS_ANSI\r
-# define URI_COMMON_H_ANSI 1\r
-# include <uriparser/UriDefsAnsi.h>\r
-# else\r
-# define URI_COMMON_H_UNICODE 1\r
-# include <uriparser/UriDefsUnicode.h>\r
-# endif\r
-\r
-\r
-\r
-/* Used to point to from empty path segments.\r
- * X.first and X.afterLast must be the same non-NULL value then. */\r
-extern const URI_CHAR * const URI_FUNC(SafeToPointTo);\r
-extern const URI_CHAR * const URI_FUNC(ConstPwd);\r
-extern const URI_CHAR * const URI_FUNC(ConstParent);\r
-\r
-\r
-\r
-void URI_FUNC(ResetUri)(URI_TYPE(Uri) * uri);\r
-\r
-UriBool URI_FUNC(RemoveDotSegments)(URI_TYPE(Uri) * uri);\r
-\r
-unsigned char URI_FUNC(HexdigToInt)(URI_CHAR hexdig);\r
-URI_CHAR URI_FUNC(HexToLetter)(unsigned int value);\r
-\r
-UriBool URI_FUNC(IsHostSet)(const URI_TYPE(Uri) * uri);\r
-\r
-UriBool URI_FUNC(CopyPath)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * source);\r
-UriBool URI_FUNC(CopyAuthority)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * source);\r
-\r
-UriBool URI_FUNC(FixAmbiguity)(URI_TYPE(Uri) * uri);\r
-\r
-\r
-\r
-#endif\r
-#endif\r
+/*
+ * uriparser - RFC 3986 URI parsing library
+ *
+ * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>
+ * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the <ORGANIZATION> nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#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))
+/* What encodings are enabled? */
+#include <uriparser/UriDefsConfig.h>
+#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
+/* Include SELF twice */
+# define URI_PASS_ANSI 1
+# include "UriCommon.h"
+# undef URI_PASS_ANSI
+# define URI_PASS_UNICODE 1
+# include "UriCommon.h"
+# undef URI_PASS_UNICODE
+/* 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
+
+
+
+/* Used to point to from empty path segments.
+ * X.first and X.afterLast must be the same non-NULL value then. */
+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);
+
+UriBool URI_FUNC(RemoveDotSegmentsAbsolute)(URI_TYPE(Uri) * uri);
+UriBool URI_FUNC(RemoveDotSegments)(URI_TYPE(Uri) * uri, UriBool relative);
+
+unsigned char URI_FUNC(HexdigToInt)(URI_CHAR hexdig);
+URI_CHAR URI_FUNC(HexToLetter)(unsigned int value);
+
+UriBool URI_FUNC(IsHostSet)(const URI_TYPE(Uri) * uri);
+
+UriBool URI_FUNC(CopyPath)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * source);
+UriBool URI_FUNC(CopyAuthority)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * source);
+
+UriBool URI_FUNC(FixAmbiguity)(URI_TYPE(Uri) * uri);
+
+
+
+#endif
+#endif
-/*\r
- * uriparser - RFC 3986 URI parsing library\r
- *\r
- * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>\r
- * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- *\r
- * * Redistributions of source code must retain the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer.\r
- *\r
- * * Redistributions in binary form must reproduce the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer in the documentation and/or other materials\r
- * provided with the distribution.\r
- *\r
- * * Neither the name of the <ORGANIZATION> nor the names of its\r
- * contributors may be used to endorse or promote products\r
- * derived from this software without specific prior written\r
- * permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
- * OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/* What encodings are enabled? */\r
-#include <uriparser/UriDefsConfig.h>\r
-#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))\r
-/* Include SELF twice */\r
-# define URI_PASS_ANSI 1\r
-# include "UriCompare.c"\r
-# undef URI_PASS_ANSI\r
-# define URI_PASS_UNICODE 1\r
-# include "UriCompare.c"\r
-# undef URI_PASS_UNICODE\r
-#else\r
-# ifdef URI_PASS_ANSI\r
-# include <uriparser/UriDefsAnsi.h>\r
-# else\r
-# include <uriparser/UriDefsUnicode.h>\r
-# include <wchar.h>\r
-# endif\r
-\r
-\r
-\r
-#ifndef URI_DOXYGEN\r
-# include <uriparser/Uri.h>\r
-# include <uriparser/UriIp4.h>\r
-# include "UriCommon.h"\r
-#endif\r
-\r
-\r
-\r
-static int URI_FUNC(CompareRange)(const URI_TYPE(TextRange) * a,\r
- const URI_TYPE(TextRange) * b);\r
-\r
-\r
-\r
-/* Compares two text ranges for equal text content */\r
-static URI_INLINE int URI_FUNC(CompareRange)(const URI_TYPE(TextRange) * a,\r
- const URI_TYPE(TextRange) * b) {\r
- int diff;\r
-\r
- /* NOTE: Both NULL means equal! */\r
- if ((a == NULL) || (b == NULL)) {\r
- return ((a == NULL) && (b == NULL)) ? URI_TRUE : URI_FALSE;\r
- }\r
-\r
- diff = ((int)(a->afterLast - a->first) - (int)(b->afterLast - b->first));\r
- if (diff > 0) {\r
- return 1;\r
- } else if (diff < 0) {\r
- return -1;\r
- }\r
-\r
- return URI_STRNCMP(a->first, b->first, (a->afterLast - a->first));\r
-}\r
-\r
-\r
-\r
-UriBool URI_FUNC(EqualsUri)(const URI_TYPE(Uri) * a,\r
- const URI_TYPE(Uri) * b) {\r
- /* NOTE: Both NULL means equal! */\r
- if ((a == NULL) || (b == NULL)) {\r
- return ((a == NULL) && (b == NULL)) ? URI_TRUE : URI_FALSE;\r
- }\r
-\r
- /* scheme */\r
- if (URI_FUNC(CompareRange)(&(a->scheme), &(b->scheme))) {\r
- return URI_FALSE;\r
- }\r
-\r
- /* absolutePath */\r
- if ((a->scheme.first == NULL)&& (a->absolutePath != b->absolutePath)) {\r
- return URI_FALSE;\r
- }\r
-\r
- /* userInfo */\r
- if (URI_FUNC(CompareRange)(&(a->userInfo), &(b->userInfo))) {\r
- return URI_FALSE;\r
- }\r
-\r
- /* Host */\r
- if (((a->hostData.ip4 == NULL) != (b->hostData.ip4 == NULL))\r
- || ((a->hostData.ip6 == NULL) != (b->hostData.ip6 == NULL))\r
- || ((a->hostData.ipFuture.first == NULL)\r
- != (b->hostData.ipFuture.first == NULL))) {\r
- return URI_FALSE;\r
- }\r
-\r
- if (a->hostData.ip4 != NULL) {\r
- if (memcmp(a->hostData.ip4->data, b->hostData.ip4->data, 4)) {\r
- return URI_FALSE;\r
- }\r
- }\r
-\r
- if (a->hostData.ip6 != NULL) {\r
- if (memcmp(a->hostData.ip6->data, b->hostData.ip6->data, 16)) {\r
- return URI_FALSE;\r
- }\r
- }\r
-\r
- if (a->hostData.ipFuture.first != NULL) {\r
- if (URI_FUNC(CompareRange)(&(a->hostData.ipFuture), &(b->hostData.ipFuture))) {\r
- return URI_FALSE;\r
- }\r
- }\r
-\r
- if ((a->hostData.ip4 == NULL)\r
- && (a->hostData.ip6 == NULL)\r
- && (a->hostData.ipFuture.first == NULL)) {\r
- if (URI_FUNC(CompareRange)(&(a->hostText), &(b->hostText))) {\r
- return URI_FALSE;\r
- }\r
- }\r
-\r
- /* portText */\r
- if (URI_FUNC(CompareRange)(&(a->portText), &(b->portText))) {\r
- return URI_FALSE;\r
- }\r
-\r
- /* Path */\r
- if ((a->pathHead == NULL) != (b->pathHead == NULL)) {\r
- return URI_FALSE;\r
- }\r
-\r
- if (a->pathHead != NULL) {\r
- URI_TYPE(PathSegment) * walkA = a->pathHead;\r
- URI_TYPE(PathSegment) * walkB = b->pathHead;\r
- do {\r
- if (URI_FUNC(CompareRange)(&(walkA->text), &(walkB->text))) {\r
- return URI_FALSE;\r
- }\r
- if ((walkA->next == NULL) != (walkB->next == NULL)) {\r
- return URI_FALSE;\r
- }\r
- walkA = walkA->next;\r
- walkB = walkB->next;\r
- } while (walkA != NULL);\r
- }\r
-\r
- /* query */\r
- if (URI_FUNC(CompareRange)(&(a->query), &(b->query))) {\r
- return URI_FALSE;\r
- }\r
-\r
- /* fragment */\r
- if (URI_FUNC(CompareRange)(&(a->fragment), &(b->fragment))) {\r
- return URI_FALSE;\r
- }\r
-\r
- return URI_TRUE; /* Equal*/\r
-}\r
-\r
-\r
-\r
-#endif\r
+/*
+ * uriparser - RFC 3986 URI parsing library
+ *
+ * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>
+ * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the <ORGANIZATION> nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* What encodings are enabled? */
+#include <uriparser/UriDefsConfig.h>
+#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
+/* Include SELF twice */
+# define URI_PASS_ANSI 1
+# include "UriCompare.c"
+# undef URI_PASS_ANSI
+# define URI_PASS_UNICODE 1
+# include "UriCompare.c"
+# undef URI_PASS_UNICODE
+#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 <uriparser/UriIp4.h>
+# include "UriCommon.h"
+#endif
+
+
+
+static int URI_FUNC(CompareRange)(const URI_TYPE(TextRange) * a,
+ const URI_TYPE(TextRange) * b);
+
+
+
+/* Compares two text ranges for equal text content */
+static URI_INLINE int URI_FUNC(CompareRange)(const URI_TYPE(TextRange) * a,
+ const URI_TYPE(TextRange) * b) {
+ int diff;
+
+ /* NOTE: Both NULL means equal! */
+ if ((a == NULL) || (b == NULL)) {
+ return ((a == NULL) && (b == NULL)) ? URI_TRUE : URI_FALSE;
+ }
+
+ diff = ((int)(a->afterLast - a->first) - (int)(b->afterLast - b->first));
+ if (diff > 0) {
+ return 1;
+ } else if (diff < 0) {
+ return -1;
+ }
+
+ return URI_STRNCMP(a->first, b->first, (a->afterLast - a->first));
+}
+
+
+
+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;
+ }
+
+ /* 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;
+ }
+
+ /* 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) {
+ if (memcmp(a->hostData.ip4->data, b->hostData.ip4->data, 4)) {
+ return URI_FALSE;
+ }
+ }
+
+ if (a->hostData.ip6 != NULL) {
+ if (memcmp(a->hostData.ip6->data, b->hostData.ip6->data, 16)) {
+ return URI_FALSE;
+ }
+ }
+
+ if (a->hostData.ipFuture.first != NULL) {
+ if (URI_FUNC(CompareRange)(&(a->hostData.ipFuture), &(b->hostData.ipFuture))) {
+ 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;
+ }
+ }
+
+ /* portText */
+ if (URI_FUNC(CompareRange)(&(a->portText), &(b->portText))) {
+ 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*/
+}
+
+
+
+#endif
-/*\r
- * uriparser - RFC 3986 URI parsing library\r
- *\r
- * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>\r
- * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- *\r
- * * Redistributions of source code must retain the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer.\r
- *\r
- * * Redistributions in binary form must reproduce the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer in the documentation and/or other materials\r
- * provided with the distribution.\r
- *\r
- * * Neither the name of the <ORGANIZATION> nor the names of its\r
- * contributors may be used to endorse or promote products\r
- * derived from this software without specific prior written\r
- * permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
- * OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/* What encodings are enabled? */\r
-#include <uriparser/UriDefsConfig.h>\r
-#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))\r
-/* Include SELF twice */\r
-# define URI_PASS_ANSI 1\r
-# include "UriEscape.c"\r
-# undef URI_PASS_ANSI\r
-# define URI_PASS_UNICODE 1\r
-# include "UriEscape.c"\r
-# undef URI_PASS_UNICODE\r
-#else\r
-# ifdef URI_PASS_ANSI\r
-# include <uriparser/UriDefsAnsi.h>\r
-# else\r
-# include <uriparser/UriDefsUnicode.h>\r
-# include <wchar.h>\r
-# endif\r
-\r
-\r
-\r
-#ifndef URI_DOXYGEN\r
-# include <uriparser/Uri.h>\r
-# include "UriCommon.h"\r
-#endif\r
-\r
-\r
-\r
-URI_CHAR * URI_FUNC(Escape)(const URI_CHAR * in, URI_CHAR * out,\r
- UriBool spaceToPlus, UriBool normalizeBreaks) {\r
- return URI_FUNC(EscapeEx)(in, NULL, out, spaceToPlus, normalizeBreaks);\r
-}\r
-\r
-\r
-\r
-URI_CHAR * URI_FUNC(EscapeEx)(const URI_CHAR * inFirst,\r
- const URI_CHAR * inAfterLast, URI_CHAR * out,\r
- UriBool spaceToPlus, UriBool normalizeBreaks) {\r
- const URI_CHAR * read = inFirst;\r
- URI_CHAR * write = out;\r
- UriBool prevWasCr = URI_FALSE;\r
- if ((out == NULL) || (inFirst == out)) {\r
- return NULL;\r
- } else if (inFirst == NULL) {\r
- if (out != NULL) {\r
- out[0] = _UT('\0');\r
- }\r
- return out;\r
- }\r
-\r
- for (;;) {\r
- if ((inAfterLast != NULL) && (read >= inAfterLast)) {\r
- write[0] = _UT('\0');\r
- return write;\r
- }\r
-\r
- switch (read[0]) {\r
- case _UT('\0'):\r
- write[0] = _UT('\0');\r
- return write;\r
-\r
- case _UT(' '):\r
- if (spaceToPlus) {\r
- write[0] = _UT('+');\r
- write++;\r
- } else {\r
- write[0] = _UT('%');\r
- write[1] = _UT('2');\r
- write[2] = _UT('0');\r
- write += 3;\r
- }\r
- prevWasCr = URI_FALSE;\r
- break;\r
-\r
- case _UT('a'): /* ALPHA */\r
- case _UT('A'):\r
- case _UT('b'):\r
- case _UT('B'):\r
- case _UT('c'):\r
- case _UT('C'):\r
- case _UT('d'):\r
- case _UT('D'):\r
- case _UT('e'):\r
- case _UT('E'):\r
- case _UT('f'):\r
- case _UT('F'):\r
- case _UT('g'):\r
- case _UT('G'):\r
- case _UT('h'):\r
- case _UT('H'):\r
- case _UT('i'):\r
- case _UT('I'):\r
- case _UT('j'):\r
- case _UT('J'):\r
- case _UT('k'):\r
- case _UT('K'):\r
- case _UT('l'):\r
- case _UT('L'):\r
- case _UT('m'):\r
- case _UT('M'):\r
- case _UT('n'):\r
- case _UT('N'):\r
- case _UT('o'):\r
- case _UT('O'):\r
- case _UT('p'):\r
- case _UT('P'):\r
- case _UT('q'):\r
- case _UT('Q'):\r
- case _UT('r'):\r
- case _UT('R'):\r
- case _UT('s'):\r
- case _UT('S'):\r
- case _UT('t'):\r
- case _UT('T'):\r
- case _UT('u'):\r
- case _UT('U'):\r
- case _UT('v'):\r
- case _UT('V'):\r
- case _UT('w'):\r
- case _UT('W'):\r
- case _UT('x'):\r
- case _UT('X'):\r
- case _UT('y'):\r
- case _UT('Y'):\r
- case _UT('z'):\r
- case _UT('Z'):\r
- case _UT('0'): /* DIGIT */\r
- case _UT('1'):\r
- case _UT('2'):\r
- case _UT('3'):\r
- case _UT('4'):\r
- case _UT('5'):\r
- case _UT('6'):\r
- case _UT('7'):\r
- case _UT('8'):\r
- case _UT('9'):\r
- case _UT('-'): /* "-" / "." / "_" / "~" */\r
- case _UT('.'):\r
- case _UT('_'):\r
- case _UT('~'):\r
- /* Copy unmodified */\r
- write[0] = read[0];\r
- write++;\r
-\r
- prevWasCr = URI_FALSE;\r
- break;\r
-\r
- case _UT('\x0a'):\r
- if (normalizeBreaks) {\r
- if (!prevWasCr) {\r
- write[0] = _UT('%');\r
- write[1] = _UT('0');\r
- write[2] = _UT('D');\r
- write[3] = _UT('%');\r
- write[4] = _UT('0');\r
- write[5] = _UT('A');\r
- write += 6;\r
- }\r
- } else {\r
- write[0] = _UT('%');\r
- write[1] = _UT('0');\r
- write[2] = _UT('A');\r
- write += 3;\r
- }\r
- prevWasCr = URI_FALSE;\r
- break;\r
-\r
- case _UT('\x0d'):\r
- if (normalizeBreaks) {\r
- write[0] = _UT('%');\r
- write[1] = _UT('0');\r
- write[2] = _UT('D');\r
- write[3] = _UT('%');\r
- write[4] = _UT('0');\r
- write[5] = _UT('A');\r
- write += 6;\r
- } else {\r
- write[0] = _UT('%');\r
- write[1] = _UT('0');\r
- write[2] = _UT('D');\r
- write += 3;\r
- }\r
- prevWasCr = URI_TRUE;\r
- break;\r
-\r
- default:\r
- /* Percent encode */\r
- {\r
- const unsigned char code = (unsigned char)read[0];\r
- write[0] = _UT('%');\r
- write[1] = URI_FUNC(HexToLetter)(code >> 4);\r
- write[2] = URI_FUNC(HexToLetter)(code & 0x0f);\r
- write += 3;\r
- }\r
- prevWasCr = URI_FALSE;\r
- break;\r
- }\r
-\r
- read++;\r
- }\r
-}\r
-\r
-\r
-\r
-const URI_CHAR * URI_FUNC(UnescapeInPlace)(URI_CHAR * inout) {\r
- return URI_FUNC(UnescapeInPlaceEx)(inout, URI_FALSE, URI_BR_DONT_TOUCH);\r
-}\r
-\r
-\r
-\r
-const URI_CHAR * URI_FUNC(UnescapeInPlaceEx)(URI_CHAR * inout,\r
- UriBool plusToSpace, UriBreakConversion breakConversion) {\r
- URI_CHAR * read = inout;\r
- URI_CHAR * write = inout;\r
- UriBool prevWasCr = URI_FALSE;\r
-\r
- if (inout == NULL) {\r
- return NULL;\r
- }\r
-\r
- for (;;) {\r
- switch (read[0]) {\r
- case _UT('\0'):\r
- if (read > write) {\r
- write[0] = _UT('\0');\r
- }\r
- return write;\r
-\r
- case _UT('%'):\r
- switch (read[1]) {\r
- case _UT('0'):\r
- case _UT('1'):\r
- case _UT('2'):\r
- case _UT('3'):\r
- case _UT('4'):\r
- case _UT('5'):\r
- case _UT('6'):\r
- case _UT('7'):\r
- case _UT('8'):\r
- case _UT('9'):\r
- case _UT('a'):\r
- case _UT('b'):\r
- case _UT('c'):\r
- case _UT('d'):\r
- case _UT('e'):\r
- case _UT('f'):\r
- case _UT('A'):\r
- case _UT('B'):\r
- case _UT('C'):\r
- case _UT('D'):\r
- case _UT('E'):\r
- case _UT('F'):\r
- switch (read[2]) {\r
- case _UT('0'):\r
- case _UT('1'):\r
- case _UT('2'):\r
- case _UT('3'):\r
- case _UT('4'):\r
- case _UT('5'):\r
- case _UT('6'):\r
- case _UT('7'):\r
- case _UT('8'):\r
- case _UT('9'):\r
- case _UT('a'):\r
- case _UT('b'):\r
- case _UT('c'):\r
- case _UT('d'):\r
- case _UT('e'):\r
- case _UT('f'):\r
- case _UT('A'):\r
- case _UT('B'):\r
- case _UT('C'):\r
- case _UT('D'):\r
- case _UT('E'):\r
- case _UT('F'):\r
- {\r
- /* Percent group found */\r
- const unsigned char left = URI_FUNC(HexdigToInt)(read[1]);\r
- const unsigned char right = URI_FUNC(HexdigToInt)(read[2]);\r
- const int code = 16 * left + right;\r
- switch (code) {\r
- case 10:\r
- switch (breakConversion) {\r
- case URI_BR_TO_LF:\r
- if (!prevWasCr) {\r
- write[0] = (URI_CHAR)10;\r
- write++;\r
- }\r
- break;\r
-\r
- case URI_BR_TO_CRLF:\r
- if (!prevWasCr) {\r
- write[0] = (URI_CHAR)13;\r
- write[1] = (URI_CHAR)10;\r
- write += 2;\r
- }\r
- break;\r
-\r
- case URI_BR_TO_CR:\r
- if (!prevWasCr) {\r
- write[0] = (URI_CHAR)13;\r
- write++;\r
- }\r
- break;\r
-\r
- case URI_BR_DONT_TOUCH:\r
- default:\r
- write[0] = (URI_CHAR)10;\r
- write++;\r
-\r
- }\r
- prevWasCr = URI_FALSE;\r
- break;\r
-\r
- case 13:\r
- switch (breakConversion) {\r
- case URI_BR_TO_LF:\r
- write[0] = (URI_CHAR)10;\r
- write++;\r
- break;\r
-\r
- case URI_BR_TO_CRLF:\r
- write[0] = (URI_CHAR)13;\r
- write[1] = (URI_CHAR)10;\r
- write += 2;\r
- break;\r
-\r
- case URI_BR_TO_CR:\r
- write[0] = (URI_CHAR)13;\r
- write++;\r
- break;\r
-\r
- case URI_BR_DONT_TOUCH:\r
- default:\r
- write[0] = (URI_CHAR)13;\r
- write++;\r
-\r
- }\r
- prevWasCr = URI_TRUE;\r
- break;\r
-\r
- default:\r
- write[0] = (URI_CHAR)(code);\r
- write++;\r
-\r
- prevWasCr = URI_FALSE;\r
-\r
- }\r
- read += 3;\r
- }\r
- break;\r
-\r
- default:\r
- /* Copy two chars unmodified and */\r
- /* look at this char again */\r
- if (read > write) {\r
- write[0] = read[0];\r
- write[1] = read[1];\r
- }\r
- read += 2;\r
- write += 2;\r
-\r
- prevWasCr = URI_FALSE;\r
- }\r
- break;\r
-\r
- default:\r
- /* Copy one char unmodified and */\r
- /* look at this char again */\r
- if (read > write) {\r
- write[0] = read[0];\r
- }\r
- read++;\r
- write++;\r
-\r
- prevWasCr = URI_FALSE;\r
- }\r
- break;\r
-\r
- case _UT('+'):\r
- if (plusToSpace) {\r
- /* Convert '+' to ' ' */\r
- write[0] = _UT(' ');\r
- } else {\r
- /* Copy one char unmodified */\r
- if (read > write) {\r
- write[0] = read[0];\r
- }\r
- }\r
- read++;\r
- write++;\r
-\r
- prevWasCr = URI_FALSE;\r
- break;\r
-\r
- default:\r
- /* Copy one char unmodified */\r
- if (read > write) {\r
- write[0] = read[0];\r
- }\r
- read++;\r
- write++;\r
-\r
- prevWasCr = URI_FALSE;\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-#endif\r
+/*
+ * uriparser - RFC 3986 URI parsing library
+ *
+ * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>
+ * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the <ORGANIZATION> nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* What encodings are enabled? */
+#include <uriparser/UriDefsConfig.h>
+#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
+/* Include SELF twice */
+# define URI_PASS_ANSI 1
+# include "UriEscape.c"
+# undef URI_PASS_ANSI
+# define URI_PASS_UNICODE 1
+# include "UriEscape.c"
+# undef URI_PASS_UNICODE
+#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"
+#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(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;
+ }
+
+ switch (read[0]) {
+ case _UT('\0'):
+ 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;
+
+ 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++;
+
+ prevWasCr = URI_FALSE;
+ 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;
+
+ 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];
+ write[0] = _UT('%');
+ write[1] = URI_FUNC(HexToLetter)(code >> 4);
+ write[2] = URI_FUNC(HexToLetter)(code & 0x0f);
+ write += 3;
+ }
+ prevWasCr = URI_FALSE;
+ break;
+ }
+
+ read++;
+ }
+}
+
+
+
+const URI_CHAR * URI_FUNC(UnescapeInPlace)(URI_CHAR * inout) {
+ 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;
+ }
+
+ for (;;) {
+ switch (read[0]) {
+ case _UT('\0'):
+ if (read > write) {
+ write[0] = _UT('\0');
+ }
+ return write;
+
+ 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_CRLF:
+ if (!prevWasCr) {
+ write[0] = (URI_CHAR)13;
+ write[1] = (URI_CHAR)10;
+ write += 2;
+ }
+ break;
+
+ case URI_BR_TO_CR:
+ if (!prevWasCr) {
+ write[0] = (URI_CHAR)13;
+ write++;
+ }
+ break;
+
+ case URI_BR_DONT_TOUCH:
+ default:
+ write[0] = (URI_CHAR)10;
+ write++;
+
+ }
+ prevWasCr = URI_FALSE;
+ break;
+
+ case 13:
+ switch (breakConversion) {
+ case URI_BR_TO_LF:
+ write[0] = (URI_CHAR)10;
+ write++;
+ break;
+
+ case URI_BR_TO_CRLF:
+ write[0] = (URI_CHAR)13;
+ write[1] = (URI_CHAR)10;
+ write += 2;
+ break;
+
+ case URI_BR_TO_CR:
+ write[0] = (URI_CHAR)13;
+ write++;
+ break;
+
+ case URI_BR_DONT_TOUCH:
+ default:
+ write[0] = (URI_CHAR)13;
+ write++;
+
+ }
+ prevWasCr = URI_TRUE;
+ break;
+
+ default:
+ write[0] = (URI_CHAR)(code);
+ write++;
+
+ prevWasCr = URI_FALSE;
+
+ }
+ read += 3;
+ }
+ break;
+
+ 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;
+
+ 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;
+ }
+ }
+}
+
+
+
+#endif
-/*\r
- * uriparser - RFC 3986 URI parsing library\r
- *\r
- * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>\r
- * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- *\r
- * * Redistributions of source code must retain the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer.\r
- *\r
- * * Redistributions in binary form must reproduce the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer in the documentation and/or other materials\r
- * provided with the distribution.\r
- *\r
- * * Neither the name of the <ORGANIZATION> nor the names of its\r
- * contributors may be used to endorse or promote products\r
- * derived from this software without specific prior written\r
- * permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
- * OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/* What encodings are enabled? */\r
-#include <uriparser/UriDefsConfig.h>\r
-#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))\r
-/* Include SELF twice */\r
-# define URI_PASS_ANSI 1\r
-# include "UriFile.c"\r
-# undef URI_PASS_ANSI\r
-# define URI_PASS_UNICODE 1\r
-# include "UriFile.c"\r
-# undef URI_PASS_UNICODE\r
-#else\r
-# ifdef URI_PASS_ANSI\r
-# include <uriparser/UriDefsAnsi.h>\r
-# else\r
-# include <uriparser/UriDefsUnicode.h>\r
-# include <wchar.h>\r
-# endif\r
-\r
-\r
-\r
-#ifndef URI_DOXYGEN\r
-# include <uriparser/Uri.h>\r
-#endif\r
-\r
-
-\r
-static URI_INLINE int URI_FUNC(FilenameToUriString)(const URI_CHAR * filename,\r
- URI_CHAR * uriString, UriBool fromUnix) {\r
- const URI_CHAR * const prefix = fromUnix ? _UT("file://") : _UT("file:///");\r
- const int prefixLen = fromUnix ? 7 : 8;\r
-\r
- const URI_CHAR * input = filename;\r
- URI_CHAR * output = uriString + prefixLen;\r
- const URI_CHAR * lastSep = input - 1;\r
- UriBool firstSegment = URI_TRUE;\r
-\r
- /* Copy prefix */\r
- memcpy(uriString, prefix, prefixLen * sizeof(URI_CHAR));\r
-\r
- /* Copy and escape on the fly */\r
- for (;;) {\r
- if ((input[0] == _UT('\0'))\r
- || (fromUnix && input[0] == _UT('/'))\r
- || (!fromUnix && input[0] == _UT('\\'))) {\r
- /* Copy text after last seperator */\r
- if (lastSep + 1 < input) {\r
- if (!fromUnix && (firstSegment == URI_TRUE)) {\r
- /* Quick hack to not convert "C:" to "C%3A" */\r
- const int charsToCopy = (int)(input - (lastSep + 1));\r
- memcpy(output, lastSep + 1, charsToCopy * sizeof(URI_CHAR));\r
- output += charsToCopy;\r
- } else {\r
- output = URI_FUNC(EscapeEx)(lastSep + 1, input, output,\r
- URI_FALSE, URI_FALSE);\r
- }\r
- }\r
- firstSegment = URI_FALSE;\r
- }\r
-\r
- if (input[0] == _UT('\0')) {\r
- output[0] = _UT('\0');\r
- break;\r
- } else if (fromUnix && (input[0] == _UT('/'))) {\r
- /* Copy separators unmodified */\r
- output[0] = _UT('/');\r
- output++;\r
- lastSep = input;\r
- } else if (!fromUnix && (input[0] == _UT('\\'))) {\r
- /* Convert backslashes to forward slashes */\r
- output[0] = _UT('/');\r
- output++;\r
- lastSep = input;\r
- }\r
- input++;\r
- }\r
-\r
- return URI_SUCCESS;\r
-}\r
-\r
-\r
-\r
-static URI_INLINE int URI_FUNC(UriStringToFilename)(const URI_CHAR * uriString,\r
- URI_CHAR * filename, UriBool toUnix) {\r
- const URI_CHAR * const prefix = toUnix ? _UT("file://") : _UT("file:///");\r
- const int prefixLen = toUnix ? 7 : 8;\r
- URI_CHAR * walker = filename;\r
- size_t charsToCopy;\r
-\r
- if (URI_STRNCMP(uriString, prefix, prefixLen)) {\r
- return URI_ERROR_SYNTAX;\r
- }\r
- charsToCopy = URI_STRLEN(uriString + prefixLen) + 1;\r
- memcpy(filename, uriString + prefixLen, charsToCopy * sizeof(URI_CHAR));\r
- URI_FUNC(UnescapeInPlaceEx)(filename, URI_FALSE, URI_BR_DONT_TOUCH);\r
-\r
- /* Convert forward slashes to backslashes */\r
- if (!toUnix) {\r
- while (walker[0] != _UT('\0')) {\r
- if (walker[0] == _UT('/')) {\r
- walker[0] = _UT('\\');\r
- }\r
- walker++;\r
- }\r
- }\r
-\r
- return URI_SUCCESS;\r
-}\r
-\r
-\r
-\r
-int URI_FUNC(UnixFilenameToUriString)(const URI_CHAR * filename, URI_CHAR * uriString) {\r
- return URI_FUNC(FilenameToUriString)(filename, uriString, URI_TRUE);\r
-}\r
-\r
-\r
-\r
-int URI_FUNC(WindowsFilenameToUriString)(const URI_CHAR * filename, URI_CHAR * uriString) {\r
- return URI_FUNC(FilenameToUriString)(filename, uriString, URI_FALSE);\r
-}\r
-\r
-\r
-\r
-int URI_FUNC(UriStringToUnixFilename)(const URI_CHAR * uriString, URI_CHAR * filename) {\r
- return URI_FUNC(UriStringToFilename)(uriString, filename, URI_TRUE);\r
-}\r
-\r
-\r
-\r
-int URI_FUNC(UriStringToWindowsFilename)(const URI_CHAR * uriString, URI_CHAR * filename) {\r
- return URI_FUNC(UriStringToFilename)(uriString, filename, URI_FALSE);\r
-}\r
-\r
-\r
-\r
-#endif\r
+/*
+ * uriparser - RFC 3986 URI parsing library
+ *
+ * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>
+ * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the <ORGANIZATION> nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* What encodings are enabled? */
+#include <uriparser/UriDefsConfig.h>
+#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
+/* Include SELF twice */
+# define URI_PASS_ANSI 1
+# include "UriFile.c"
+# undef URI_PASS_ANSI
+# define URI_PASS_UNICODE 1
+# include "UriFile.c"
+# undef URI_PASS_UNICODE
+#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
+
+
+
+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;
+ const UriBool absolute = (filename != NULL) && ((fromUnix && (filename[0] == _UT('/')))
+ || (!fromUnix && (filename[0] != _UT('\0')) && (filename[1] == _UT(':'))));
+
+ if ((filename == NULL) || (uriString == NULL)) {
+ return URI_ERROR_NULL;
+ }
+
+ if (absolute) {
+ const URI_CHAR * const prefix = fromUnix ? _UT("file://") : _UT("file:///");
+ const int prefixLen = fromUnix ? 7 : 8;
+
+ /* 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 seperator */
+ 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++;
+ }
+
+ return URI_SUCCESS;
+}
+
+
+
+static URI_INLINE int URI_FUNC(UriStringToFilename)(const URI_CHAR * uriString,
+ URI_CHAR * filename, UriBool toUnix) {
+ const URI_CHAR * const prefix = toUnix ? _UT("file://") : _UT("file:///");
+ const int prefixLen = toUnix ? 7 : 8;
+ URI_CHAR * walker = filename;
+ size_t charsToCopy;
+ const UriBool absolute = (URI_STRNCMP(uriString, prefix, prefixLen) == 0);
+ const int charsToSkip = (absolute ? prefixLen : 0);
+
+ charsToCopy = URI_STRLEN(uriString + charsToSkip) + 1;
+ memcpy(filename, uriString + charsToSkip, charsToCopy * sizeof(URI_CHAR));
+ URI_FUNC(UnescapeInPlaceEx)(filename, URI_FALSE, URI_BR_DONT_TOUCH);
+
+ /* Convert forward slashes to backslashes */
+ if (!toUnix) {
+ while (walker[0] != _UT('\0')) {
+ if (walker[0] == _UT('/')) {
+ walker[0] = _UT('\\');
+ }
+ walker++;
+ }
+ }
+
+ return URI_SUCCESS;
+}
+
+
+
+int URI_FUNC(UnixFilenameToUriString)(const URI_CHAR * filename, URI_CHAR * uriString) {
+ 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(UriStringToUnixFilename)(const URI_CHAR * uriString, URI_CHAR * filename) {
+ 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);
+}
+
+
+
+#endif
-/*\r
- * uriparser - RFC 3986 URI parsing library\r
- *\r
- * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>\r
- * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- *\r
- * * Redistributions of source code must retain the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer.\r
- *\r
- * * Redistributions in binary form must reproduce the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer in the documentation and/or other materials\r
- * provided with the distribution.\r
- *\r
- * * Neither the name of the <ORGANIZATION> nor the names of its\r
- * contributors may be used to endorse or promote products\r
- * derived from this software without specific prior written\r
- * permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
- * OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/**\r
- * @file UriNormalize.c\r
- * Holds the RFC 3986 %URI normalization implementation.\r
- * NOTE: This source file includes itself twice.\r
- */\r
-\r
-/* What encodings are enabled? */\r
-#include <uriparser/UriDefsConfig.h>\r
-#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))\r
-/* Include SELF twice */\r
-# define URI_PASS_ANSI 1\r
-# include "UriNormalize.c"\r
-# undef URI_PASS_ANSI\r
-# define URI_PASS_UNICODE 1\r
-# include "UriNormalize.c"\r
-# undef URI_PASS_UNICODE\r
-#else\r
-# ifdef URI_PASS_ANSI\r
-# include <uriparser/UriDefsAnsi.h>\r
-# else\r
-# include <uriparser/UriDefsUnicode.h>\r
-# include <wchar.h>\r
-# endif\r
-\r
-\r
-\r
-#ifndef URI_DOXYGEN\r
-# include <uriparser/Uri.h>\r
-# include "UriNormalizeBase.h"\r
-# include "UriCommon.h"\r
-#endif\r
-\r
-\r
-\r
-static int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, unsigned int inMask,\r
- unsigned int * outMask);\r
-\r
-static UriBool URI_FUNC(MakeRangeOwner)(unsigned int * doneMask,\r
- unsigned int maskTest, URI_TYPE(TextRange) * range);\r
-static UriBool URI_FUNC(MakeOwner)(URI_TYPE(Uri) * uri,\r
- unsigned int * doneMask);\r
-\r
-static void URI_FUNC(FixPercentEncodingInplace)(const URI_CHAR * first,\r
- const URI_CHAR ** afterLast);\r
-static UriBool URI_FUNC(FixPercentEncodingMalloc)(const URI_CHAR ** first,\r
- const URI_CHAR ** afterLast);\r
-static void URI_FUNC(FixPercentEncodingEngine)(\r
- const URI_CHAR * inFirst, const URI_CHAR * inAfterLast,\r
- const URI_CHAR * outFirst, const URI_CHAR ** outAfterLast);\r
-\r
-static UriBool URI_FUNC(ContainsUppercaseLetters)(const URI_CHAR * first,\r
- const URI_CHAR * afterLast);\r
-static UriBool URI_FUNC(ContainsUglyPercentEncoding)(const URI_CHAR * first,\r
- const URI_CHAR * afterLast);\r
-\r
-static void URI_FUNC(LowercaseInplace)(const URI_CHAR * first,\r
- const URI_CHAR * afterLast);\r
-static UriBool URI_FUNC(LowercaseMalloc)(const URI_CHAR ** first,\r
- const URI_CHAR ** afterLast);\r
-\r
-static void URI_FUNC(PreventLeakage)(URI_TYPE(Uri) * uri,\r
- unsigned int revertMask);\r
-\r
-\r
-\r
-static URI_INLINE void URI_FUNC(PreventLeakage)(URI_TYPE(Uri) * uri,\r
- unsigned int revertMask) {\r
- if (revertMask & URI_NORMALIZE_SCHEME) {\r
- free((URI_CHAR *)uri->scheme.first);\r
- uri->scheme.first = NULL;\r
- uri->scheme.afterLast = NULL;\r
- }\r
-\r
- if (revertMask & URI_NORMALIZE_USER_INFO) {\r
- free((URI_CHAR *)uri->userInfo.first);\r
- uri->userInfo.first = NULL;\r
- uri->userInfo.afterLast = NULL;\r
- }\r
-\r
- if (revertMask & URI_NORMALIZE_HOST) {\r
- if (uri->hostData.ipFuture.first != NULL) {\r
- /* IPvFuture */\r
- free((URI_CHAR *)uri->hostData.ipFuture.first);\r
- uri->hostData.ipFuture.first = NULL;\r
- uri->hostData.ipFuture.afterLast = NULL;\r
- uri->hostText.first = NULL;\r
- uri->hostText.afterLast = NULL;\r
- } else if ((uri->hostText.first != NULL)\r
- && (uri->hostData.ip4 == NULL)\r
- && (uri->hostData.ip6 == NULL)) {\r
- /* Regname */\r
- free((URI_CHAR *)uri->hostText.first);\r
- uri->hostText.first = NULL;\r
- uri->hostText.afterLast = NULL;\r
- }\r
- }\r
-\r
- /* NOTE: Port cannot happen! */\r
-\r
- if (revertMask & URI_NORMALIZE_PATH) {\r
- URI_TYPE(PathSegment) * walker = uri->pathHead;\r
- while (walker != NULL) {\r
- URI_TYPE(PathSegment) * const next = walker->next;\r
- if (walker->text.afterLast > walker->text.first) {\r
- free((URI_CHAR *)walker->text.first);\r
- }\r
- free(walker);\r
- walker = next;\r
- }\r
- uri->pathHead = NULL;\r
- uri->pathTail = NULL;\r
- }\r
-\r
- if (revertMask & URI_NORMALIZE_QUERY) {\r
- free((URI_CHAR *)uri->query.first);\r
- uri->query.first = NULL;\r
- uri->query.afterLast = NULL;\r
- }\r
-\r
- if (revertMask & URI_NORMALIZE_FRAGMENT) {\r
- free((URI_CHAR *)uri->fragment.first);\r
- uri->fragment.first = NULL;\r
- uri->fragment.afterLast = NULL;\r
- }\r
-}\r
-\r
-\r
-\r
-static URI_INLINE UriBool URI_FUNC(ContainsUppercaseLetters)(const URI_CHAR * first,\r
- const URI_CHAR * afterLast) {\r
- if ((first != NULL) && (afterLast != NULL) && (afterLast > first)) {\r
- const URI_CHAR * i = first;\r
- for (; i < afterLast; i++) {\r
- /* 6.2.2.1 Case Normalization: uppercase letters in scheme or host */\r
- if ((*i >= _UT('A')) && (*i <= _UT('Z'))) {\r
- return URI_TRUE;\r
- }\r
- }\r
- }\r
- return URI_FALSE;\r
-}\r
-\r
-\r
-\r
-static URI_INLINE UriBool URI_FUNC(ContainsUglyPercentEncoding)(const URI_CHAR * first,\r
- const URI_CHAR * afterLast) {\r
- if ((first != NULL) && (afterLast != NULL) && (afterLast > first)) {\r
- const URI_CHAR * i = first;\r
- for (; i + 2 < afterLast; i++) {\r
- if (i[0] == _UT('%')) {\r
- /* 6.2.2.1 Case Normalization: *\r
- * lowercase percent-encodings */\r
- if (((i[1] >= _UT('a')) && (i[1] <= _UT('f')))\r
- || ((i[2] >= _UT('a')) && (i[2] <= _UT('f')))) {\r
- return URI_TRUE;\r
- } else {\r
- /* 6.2.2.2 Percent-Encoding Normalization: *\r
- * percent-encoded unreserved characters */\r
- const unsigned char left = URI_FUNC(HexdigToInt)(i[1]);\r
- const unsigned char right = URI_FUNC(HexdigToInt)(i[2]);\r
- const int code = 16 * left + right;\r
- if (uriIsUnreserved(code)) {\r
- return URI_TRUE;\r
- }\r
- }\r
- }\r
- }\r
- }\r
- return URI_FALSE;\r
-}\r
-\r
-\r
-\r
-static URI_INLINE void URI_FUNC(LowercaseInplace)(const URI_CHAR * first,\r
- const URI_CHAR * afterLast) {\r
- if ((first != NULL) && (afterLast != NULL) && (afterLast > first)) {\r
- URI_CHAR * i = (URI_CHAR *)first;\r
- const int lowerUpperDiff = (_UT('a') - _UT('A'));\r
- for (; i < afterLast; i++) {\r
- if ((*i >= _UT('A')) && (*i <=_UT('Z'))) {\r
- *i = (URI_CHAR)(*i + lowerUpperDiff);\r
- }\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-static URI_INLINE UriBool URI_FUNC(LowercaseMalloc)(const URI_CHAR ** first,\r
- const URI_CHAR ** afterLast) {\r
- int lenInChars;\r
- const int lowerUpperDiff = (_UT('a') - _UT('A'));\r
- URI_CHAR * buffer;\r
- int i = 0;\r
-\r
- if ((first == NULL) || (afterLast == NULL) || (*first == NULL)\r
- || (*afterLast == NULL)) {\r
- return URI_FALSE;\r
- }\r
-\r
- lenInChars = (int)(*afterLast - *first);\r
- if (lenInChars == 0) {\r
- return URI_TRUE;\r
- } else if (lenInChars < 0) {\r
- return URI_FALSE;\r
- }\r
-\r
- buffer = malloc(lenInChars * sizeof(URI_CHAR));\r
- if (buffer == NULL) {\r
- return URI_FALSE;\r
- }\r
-\r
- for (; i < lenInChars; i++) {\r
- if (((*first)[i] >= _UT('A')) && ((*first)[i] <=_UT('Z'))) {\r
- buffer[i] = (URI_CHAR)((*first)[i] + lowerUpperDiff);\r
- } else {\r
- buffer[i] = (*first)[i];\r
- }\r
- }\r
-\r
- *first = buffer;\r
- *afterLast = buffer + lenInChars;\r
- return URI_TRUE;\r
-}\r
-\r
-\r
-\r
-/* NOTE: Implementation must stay inplace-compatible */\r
-static URI_INLINE void URI_FUNC(FixPercentEncodingEngine)(\r
- const URI_CHAR * inFirst, const URI_CHAR * inAfterLast,\r
- const URI_CHAR * outFirst, const URI_CHAR ** outAfterLast) {\r
- URI_CHAR * write = (URI_CHAR *)outFirst;\r
- const int lenInChars = (int)(inAfterLast - inFirst);\r
- int i = 0;\r
-\r
- /* All but last two */\r
- for (; i + 2 < lenInChars; i++) {\r
- if (inFirst[i] != _UT('%')) {\r
- write[0] = inFirst[i];\r
- write++;\r
- } else {\r
- /* 6.2.2.2 Percent-Encoding Normalization: *\r
- * percent-encoded unreserved characters */\r
- const URI_CHAR one = inFirst[i + 1];\r
- const URI_CHAR two = inFirst[i + 2];\r
- const unsigned char left = URI_FUNC(HexdigToInt)(one);\r
- const unsigned char right = URI_FUNC(HexdigToInt)(two);\r
- const int code = 16 * left + right;\r
- if (uriIsUnreserved(code)) {\r
- write[0] = (URI_CHAR)(code);\r
- write++;\r
- } else {\r
- /* 6.2.2.1 Case Normalization: *\r
- * lowercase percent-encodings */\r
- write[0] = _UT('%');\r
- write[1] = URI_FUNC(HexToLetter)(left);\r
- write[2] = URI_FUNC(HexToLetter)(right);\r
- write += 3;\r
- }\r
-\r
- i += 2; /* For the two chars of the percent group we just ate */\r
- }\r
- }\r
-\r
- /* Last two */\r
- for (; i < lenInChars; i++) {\r
- write[0] = inFirst[i];\r
- write++;\r
- }\r
-\r
- *outAfterLast = write;\r
-}\r
-\r
-\r
-\r
-static URI_INLINE void URI_FUNC(FixPercentEncodingInplace)(const URI_CHAR * first,\r
- const URI_CHAR ** afterLast) {\r
- /* Death checks */\r
- if ((first == NULL) || (afterLast == NULL) || (*afterLast == NULL)) {\r
- return;\r
- }\r
-\r
- /* Fix inplace */\r
- URI_FUNC(FixPercentEncodingEngine)(first, *afterLast, first, afterLast);\r
-}\r
-\r
-\r
-\r
-static URI_INLINE UriBool URI_FUNC(FixPercentEncodingMalloc)(const URI_CHAR ** first,\r
- const URI_CHAR ** afterLast) {\r
- int lenInChars;\r
- URI_CHAR * buffer;\r
-\r
- /* Death checks */\r
- if ((first == NULL) || (afterLast == NULL) || (*first == NULL)\r
- || (*afterLast == NULL)) {\r
- return URI_FALSE;\r
- }\r
-\r
- /* Old text length */\r
- lenInChars = (int)(*afterLast - *first);\r
- if (lenInChars == 0) {\r
- return URI_TRUE;\r
- } else if (lenInChars < 0) {\r
- return URI_FALSE;\r
- }\r
-\r
- /* New buffer */\r
- buffer = malloc(lenInChars * sizeof(URI_CHAR));\r
- if (buffer == NULL) {\r
- return URI_FALSE;\r
- }\r
-\r
- /* Fix on copy */\r
- URI_FUNC(FixPercentEncodingEngine)(*first, *afterLast, buffer, afterLast);\r
- *first = buffer;\r
- return URI_TRUE;\r
-}\r
-\r
-\r
-\r
-static URI_INLINE UriBool URI_FUNC(MakeRangeOwner)(unsigned int * doneMask,\r
- unsigned int maskTest, URI_TYPE(TextRange) * range) {\r
- if (((*doneMask & maskTest) == 0)\r
- && (range->first != NULL)\r
- && (range->afterLast != NULL)\r
- && (range->afterLast > range->first)) {\r
- const int lenInChars = (int)(range->afterLast - range->first);\r
- const int lenInBytes = lenInChars * sizeof(URI_CHAR);\r
- URI_CHAR * dup = malloc(lenInBytes);\r
- if (dup == NULL) {\r
- return URI_FALSE; /* Raises malloc error */\r
- }\r
- memcpy(dup, range->afterLast, lenInBytes);\r
- range->first = dup;\r
- range->afterLast = dup + lenInChars;\r
- *doneMask |= maskTest;\r
- }\r
- return URI_TRUE;\r
-}\r
-\r
-\r
-\r
-static URI_INLINE UriBool URI_FUNC(MakeOwner)(URI_TYPE(Uri) * uri,\r
- unsigned int * doneMask) {\r
- URI_TYPE(PathSegment) * walker = uri->pathHead;\r
- if (!URI_FUNC(MakeRangeOwner)(doneMask, URI_NORMALIZE_SCHEME,\r
- &(uri->scheme))\r
- || !URI_FUNC(MakeRangeOwner)(doneMask, URI_NORMALIZE_USER_INFO,\r
- &(uri->userInfo))\r
- || !URI_FUNC(MakeRangeOwner)(doneMask, URI_NORMALIZE_QUERY,\r
- &(uri->query))\r
- || !URI_FUNC(MakeRangeOwner)(doneMask, URI_NORMALIZE_FRAGMENT,\r
- &(uri->fragment))) {\r
- return URI_FALSE; /* Raises malloc error */\r
- }\r
-\r
- /* Host */\r
- if ((*doneMask & URI_NORMALIZE_HOST) == 0) {\r
- if ((uri->hostData.ip4 == NULL)\r
- && (uri->hostData.ip6 == NULL)) {\r
- if (uri->hostData.ipFuture.first != NULL) {\r
- /* IPvFuture */\r
- if (!URI_FUNC(MakeRangeOwner)(doneMask, URI_NORMALIZE_HOST,\r
- &(uri->hostData.ipFuture))) {\r
- return URI_FALSE; /* Raises malloc error */\r
- }\r
- uri->hostText.first = uri->hostData.ipFuture.first;\r
- uri->hostText.afterLast = uri->hostData.ipFuture.afterLast;\r
- } else if (uri->hostText.first != NULL) {\r
- /* Regname */\r
- if (!URI_FUNC(MakeRangeOwner)(doneMask, URI_NORMALIZE_HOST,\r
- &(uri->hostText))) {\r
- return URI_FALSE; /* Raises malloc error */\r
- }\r
- }\r
- }\r
- }\r
-\r
- /* Path */\r
- if ((*doneMask & URI_NORMALIZE_PATH) == 0) {\r
- while (walker != NULL) {\r
- if (!URI_FUNC(MakeRangeOwner)(doneMask, 0, &(walker->text))) {\r
- /* Kill path to one before walker */\r
- URI_TYPE(PathSegment) * ranger = uri->pathHead;\r
- while (ranger->next != walker) {\r
- URI_TYPE(PathSegment) * const next = ranger->next;\r
- if ((ranger->text.first != NULL)\r
- && (ranger->text.afterLast != NULL)\r
- && (ranger->text.afterLast > ranger->text.first)) {\r
- free((URI_CHAR *)ranger->text.first);\r
- free(ranger);\r
- }\r
- ranger = next;\r
- }\r
-\r
- /* Kill path from walker */\r
- while (walker != NULL) {\r
- URI_TYPE(PathSegment) * const next = walker->next;\r
- free(walker);\r
- walker = next;\r
- }\r
-\r
- uri->pathHead = NULL;\r
- uri->pathTail = NULL;\r
- return URI_FALSE; /* Raises malloc error */\r
- }\r
- walker = walker->next;\r
- }\r
- *doneMask |= URI_NORMALIZE_PATH;\r
- }\r
-\r
- /* Port text, must come last so we don't have to undo that one if it fails. *\r
- * Otherwise we would need and extra enum flag for it althoug the port *\r
- * cannot go unnormalized... */\r
- if (!URI_FUNC(MakeRangeOwner)(doneMask, 0, &(uri->userInfo))) {\r
- return URI_FALSE; /* Raises malloc error */\r
- }\r
-\r
- return URI_TRUE;\r
-}\r
-\r
-\r
-\r
-unsigned int URI_FUNC(NormalizeSyntaxMaskRequired)(const URI_TYPE(Uri) * uri) {\r
- unsigned int res;\r
- URI_FUNC(NormalizeSyntaxEngine)((URI_TYPE(Uri) *)uri, 0, &res);\r
- return res;\r
-}\r
-\r
-\r
-\r
-int URI_FUNC(NormalizeSyntaxEx)(URI_TYPE(Uri) * uri, unsigned int mask) {\r
- return URI_FUNC(NormalizeSyntaxEngine)(uri, mask, NULL);\r
-}\r
-\r
-\r
-\r
-int URI_FUNC(NormalizeSyntax)(URI_TYPE(Uri) * uri) {\r
- return URI_FUNC(NormalizeSyntaxEx)(uri, (unsigned int)-1);\r
-}\r
-\r
-\r
-\r
-static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, unsigned int inMask, unsigned int * outMask) {\r
- unsigned int doneMask = URI_NORMALIZED;\r
- if (uri == NULL) {\r
- if (outMask != NULL) {\r
- *outMask = URI_NORMALIZED;\r
- return URI_SUCCESS;\r
- } else {\r
- return URI_ERROR_NULL;\r
- }\r
- }\r
-\r
- if (outMask != NULL) {\r
- /* Reset mask */\r
- *outMask = URI_NORMALIZED;\r
- } else if (inMask == URI_NORMALIZED) {\r
- /* Nothing to do */\r
- return URI_SUCCESS;\r
- } else if ((uri->scheme.first == NULL) && !uri->absolutePath) {\r
- /* Normalization only fone for absolute paths */\r
- return URI_SUCCESS;\r
- }\r
-\r
- /* Scheme, host */\r
- if (outMask != NULL) {\r
- const UriBool normalizeScheme = URI_FUNC(ContainsUppercaseLetters)(\r
- uri->scheme.first, uri->scheme.afterLast);\r
- const UriBool normalizeHost = URI_FUNC(ContainsUppercaseLetters)(\r
- uri->hostText.first, uri->hostText.afterLast);\r
- if (normalizeScheme) {\r
- *outMask |= URI_NORMALIZE_SCHEME;\r
- }\r
-\r
- if (normalizeHost) {\r
- *outMask |= URI_NORMALIZE_HOST;\r
- }\r
- } else {\r
- /* Scheme */\r
- if ((inMask & URI_NORMALIZE_SCHEME) && (uri->scheme.first != NULL)) {\r
- if (uri->owner) {\r
- URI_FUNC(LowercaseInplace)(uri->scheme.first, uri->scheme.afterLast);\r
- } else {\r
- if (!URI_FUNC(LowercaseMalloc)(&(uri->scheme.first), &(uri->scheme.afterLast))) {\r
- URI_FUNC(PreventLeakage)(uri, doneMask);\r
- return URI_ERROR_MALLOC;\r
- }\r
- doneMask |= URI_NORMALIZE_SCHEME;\r
- }\r
- }\r
-\r
- /* Host */\r
- if (inMask & URI_NORMALIZE_HOST) {\r
- if (uri->hostData.ipFuture.first != NULL) {\r
- /* IPvFuture */\r
- if (uri->owner) {\r
- URI_FUNC(LowercaseInplace)(uri->hostData.ipFuture.first,\r
- uri->hostData.ipFuture.afterLast);\r
- } else {\r
- if (!URI_FUNC(LowercaseMalloc)(&(uri->hostData.ipFuture.first),\r
- &(uri->hostData.ipFuture.afterLast))) {\r
- URI_FUNC(PreventLeakage)(uri, doneMask);\r
- return URI_ERROR_MALLOC;\r
- }\r
- doneMask |= URI_NORMALIZE_HOST;\r
- }\r
- uri->hostText.first = uri->hostData.ipFuture.first;\r
- uri->hostText.afterLast = uri->hostData.ipFuture.afterLast;\r
- } else if ((uri->hostText.first != NULL)\r
- && (uri->hostData.ip4 == NULL)\r
- && (uri->hostData.ip6 == NULL)) {\r
- /* Regname */\r
- if (uri->owner) {\r
- URI_FUNC(LowercaseInplace)(uri->hostText.first,\r
- uri->hostText.afterLast);\r
- } else {\r
- if (!URI_FUNC(LowercaseMalloc)(&(uri->hostText.first),\r
- &(uri->hostText.afterLast))) {\r
- URI_FUNC(PreventLeakage)(uri, doneMask);\r
- return URI_ERROR_MALLOC;\r
- }\r
- doneMask |= URI_NORMALIZE_HOST;\r
- }\r
- }\r
- }\r
- }\r
-\r
- /* User info */\r
- if (outMask != NULL) {\r
- const UriBool normalizeUserInfo = URI_FUNC(ContainsUglyPercentEncoding)(\r
- uri->userInfo.first, uri->userInfo.afterLast);\r
- if (normalizeUserInfo) {\r
- *outMask |= URI_NORMALIZE_USER_INFO;\r
- }\r
- } else {\r
- if ((inMask & URI_NORMALIZE_USER_INFO) && (uri->userInfo.first != NULL)) {\r
- if (uri->owner) {\r
- URI_FUNC(FixPercentEncodingInplace)(uri->userInfo.first, &(uri->userInfo.afterLast));\r
- } else {\r
- if (!URI_FUNC(FixPercentEncodingMalloc)(&(uri->userInfo.first),\r
- &(uri->userInfo.afterLast))) {\r
- URI_FUNC(PreventLeakage)(uri, doneMask);\r
- return URI_ERROR_MALLOC;\r
- }\r
- doneMask |= URI_NORMALIZE_USER_INFO;\r
- }\r
- }\r
- }\r
-\r
- /* Path */\r
- if (outMask != NULL) {\r
- const URI_TYPE(PathSegment) * walker = uri->pathHead;\r
- while (walker != NULL) {\r
- const URI_CHAR * const first = walker->text.first;\r
- const URI_CHAR * const afterLast = walker->text.afterLast;\r
- if ((first != NULL)\r
- && (afterLast != NULL)\r
- && (afterLast > first)\r
- && (\r
- (((afterLast - first) == 1)\r
- && (first[0] == _UT('.')))\r
- ||\r
- (((afterLast - first) == 2)\r
- && (first[0] == _UT('.'))\r
- && (first[1] == _UT('.')))\r
- ||\r
- URI_FUNC(ContainsUglyPercentEncoding)(first, afterLast)\r
- )) {\r
- *outMask |= URI_NORMALIZE_PATH;\r
- break;\r
- }\r
- walker = walker->next;\r
- }\r
- } else {\r
- const URI_TYPE(PathSegment) * walker;\r
-\r
- /* 6.2.2.3 Path Segment Normalization */\r
- if (!URI_FUNC(RemoveDotSegments)(uri)) {\r
- URI_FUNC(PreventLeakage)(uri, doneMask);\r
- return URI_ERROR_MALLOC;\r
- }\r
-\r
- /* Fix percent-encoding for each segment */\r
- walker = uri->pathHead;\r
- if (uri->owner) {\r
- while (walker != NULL) {\r
- URI_FUNC(FixPercentEncodingInplace)(walker->text.first, &(walker->text.afterLast));\r
- walker = walker->next;\r
- }\r
- } else {\r
- while (walker != NULL) {\r
- if (!URI_FUNC(FixPercentEncodingMalloc)(&(walker->text.first),\r
- &(walker->text.afterLast))) {\r
- URI_FUNC(PreventLeakage)(uri, doneMask);\r
- return URI_ERROR_MALLOC;\r
- }\r
- walker = walker->next;\r
- }\r
- doneMask |= URI_NORMALIZE_PATH;\r
- }\r
- }\r
-\r
- /* Query, fragment */\r
- if (outMask != NULL) {\r
- const UriBool normalizeQuery = URI_FUNC(ContainsUglyPercentEncoding)(\r
- uri->query.first, uri->query.afterLast);\r
- const UriBool normalizeFragment = URI_FUNC(ContainsUglyPercentEncoding)(\r
- uri->fragment.first, uri->fragment.afterLast);\r
- if (normalizeQuery) {\r
- *outMask |= URI_NORMALIZE_QUERY;\r
- }\r
-\r
- if (normalizeFragment) {\r
- *outMask |= URI_NORMALIZE_FRAGMENT;\r
- }\r
- } else {\r
- /* Query */\r
- if ((inMask & URI_NORMALIZE_QUERY) && (uri->query.first != NULL)) {\r
- if (uri->owner) {\r
- URI_FUNC(FixPercentEncodingInplace)(uri->query.first, &(uri->query.afterLast));\r
- } else {\r
- if (!URI_FUNC(FixPercentEncodingMalloc)(&(uri->query.first),\r
- &(uri->query.afterLast))) {\r
- URI_FUNC(PreventLeakage)(uri, doneMask);\r
- return URI_ERROR_MALLOC;\r
- }\r
- doneMask |= URI_NORMALIZE_QUERY;\r
- }\r
- }\r
-\r
- /* Fragment */\r
- if ((inMask & URI_NORMALIZE_FRAGMENT) && (uri->fragment.first != NULL)) {\r
- if (uri->owner) {\r
- URI_FUNC(FixPercentEncodingInplace)(uri->fragment.first, &(uri->fragment.afterLast));\r
- } else {\r
- if (!URI_FUNC(FixPercentEncodingMalloc)(&(uri->fragment.first),\r
- &(uri->fragment.afterLast))) {\r
- URI_FUNC(PreventLeakage)(uri, doneMask);\r
- return URI_ERROR_MALLOC;\r
- }\r
- doneMask |= URI_NORMALIZE_FRAGMENT;\r
- }\r
- }\r
- }\r
-\r
- /* Dup all not duped yet */\r
- if ((outMask == NULL) && !uri->owner) {\r
- if (!URI_FUNC(MakeOwner)(uri, &doneMask)) {\r
- URI_FUNC(PreventLeakage)(uri, doneMask);\r
- return URI_ERROR_MALLOC;\r
- }\r
- uri->owner = URI_TRUE;\r
- }\r
-\r
- return URI_SUCCESS;\r
-}\r
-\r
-\r
-\r
-#endif\r
+/*
+ * uriparser - RFC 3986 URI parsing library
+ *
+ * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>
+ * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the <ORGANIZATION> nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file UriNormalize.c
+ * Holds the RFC 3986 %URI normalization implementation.
+ * NOTE: This source file includes itself twice.
+ */
+
+/* What encodings are enabled? */
+#include <uriparser/UriDefsConfig.h>
+#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))
+/* Include SELF twice */
+# define URI_PASS_ANSI 1
+# include "UriNormalize.c"
+# undef URI_PASS_ANSI
+# define URI_PASS_UNICODE 1
+# include "UriNormalize.c"
+# undef URI_PASS_UNICODE
+#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 "UriNormalizeBase.h"
+# include "UriCommon.h"
+#endif
+
+
+
+static int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, unsigned int inMask,
+ unsigned int * outMask);
+
+static UriBool URI_FUNC(MakeRangeOwner)(unsigned int * doneMask,
+ unsigned int maskTest, URI_TYPE(TextRange) * range);
+static UriBool URI_FUNC(MakeOwner)(URI_TYPE(Uri) * uri,
+ unsigned int * doneMask);
+
+static void URI_FUNC(FixPercentEncodingInplace)(const URI_CHAR * first,
+ const URI_CHAR ** afterLast);
+static UriBool URI_FUNC(FixPercentEncodingMalloc)(const URI_CHAR ** first,
+ const URI_CHAR ** afterLast);
+static void URI_FUNC(FixPercentEncodingEngine)(
+ const URI_CHAR * inFirst, const URI_CHAR * inAfterLast,
+ const URI_CHAR * outFirst, const URI_CHAR ** outAfterLast);
+
+static UriBool URI_FUNC(ContainsUppercaseLetters)(const URI_CHAR * first,
+ const URI_CHAR * afterLast);
+static UriBool URI_FUNC(ContainsUglyPercentEncoding)(const URI_CHAR * first,
+ const URI_CHAR * afterLast);
+
+static void URI_FUNC(LowercaseInplace)(const URI_CHAR * first,
+ const URI_CHAR * afterLast);
+static UriBool URI_FUNC(LowercaseMalloc)(const URI_CHAR ** first,
+ const URI_CHAR ** afterLast);
+
+static void URI_FUNC(PreventLeakage)(URI_TYPE(Uri) * uri,
+ unsigned int revertMask);
+
+
+
+static URI_INLINE void URI_FUNC(PreventLeakage)(URI_TYPE(Uri) * uri,
+ unsigned int revertMask) {
+ if (revertMask & URI_NORMALIZE_SCHEME) {
+ free((URI_CHAR *)uri->scheme.first);
+ uri->scheme.first = NULL;
+ uri->scheme.afterLast = NULL;
+ }
+
+ if (revertMask & URI_NORMALIZE_USER_INFO) {
+ free((URI_CHAR *)uri->userInfo.first);
+ uri->userInfo.first = NULL;
+ uri->userInfo.afterLast = NULL;
+ }
+
+ if (revertMask & URI_NORMALIZE_HOST) {
+ if (uri->hostData.ipFuture.first != NULL) {
+ /* IPvFuture */
+ free((URI_CHAR *)uri->hostData.ipFuture.first);
+ uri->hostData.ipFuture.first = NULL;
+ uri->hostData.ipFuture.afterLast = NULL;
+ uri->hostText.first = NULL;
+ uri->hostText.afterLast = NULL;
+ } else if ((uri->hostText.first != NULL)
+ && (uri->hostData.ip4 == NULL)
+ && (uri->hostData.ip6 == NULL)) {
+ /* Regname */
+ free((URI_CHAR *)uri->hostText.first);
+ uri->hostText.first = NULL;
+ uri->hostText.afterLast = NULL;
+ }
+ }
+
+ /* NOTE: Port cannot happen! */
+
+ if (revertMask & URI_NORMALIZE_PATH) {
+ URI_TYPE(PathSegment) * walker = uri->pathHead;
+ while (walker != NULL) {
+ URI_TYPE(PathSegment) * const next = walker->next;
+ if (walker->text.afterLast > walker->text.first) {
+ free((URI_CHAR *)walker->text.first);
+ }
+ free(walker);
+ walker = next;
+ }
+ uri->pathHead = NULL;
+ uri->pathTail = NULL;
+ }
+
+ if (revertMask & URI_NORMALIZE_QUERY) {
+ free((URI_CHAR *)uri->query.first);
+ uri->query.first = NULL;
+ uri->query.afterLast = NULL;
+ }
+
+ if (revertMask & URI_NORMALIZE_FRAGMENT) {
+ free((URI_CHAR *)uri->fragment.first);
+ uri->fragment.first = NULL;
+ uri->fragment.afterLast = NULL;
+ }
+}
+
+
+
+static URI_INLINE UriBool URI_FUNC(ContainsUppercaseLetters)(const URI_CHAR * first,
+ const URI_CHAR * afterLast) {
+ if ((first != NULL) && (afterLast != NULL) && (afterLast > first)) {
+ const URI_CHAR * i = first;
+ for (; i < afterLast; i++) {
+ /* 6.2.2.1 Case Normalization: uppercase letters in scheme or host */
+ if ((*i >= _UT('A')) && (*i <= _UT('Z'))) {
+ return URI_TRUE;
+ }
+ }
+ }
+ return URI_FALSE;
+}
+
+
+
+static URI_INLINE UriBool URI_FUNC(ContainsUglyPercentEncoding)(const URI_CHAR * first,
+ const URI_CHAR * afterLast) {
+ if ((first != NULL) && (afterLast != NULL) && (afterLast > first)) {
+ const URI_CHAR * i = first;
+ for (; i + 2 < afterLast; i++) {
+ if (i[0] == _UT('%')) {
+ /* 6.2.2.1 Case Normalization: *
+ * lowercase percent-encodings */
+ if (((i[1] >= _UT('a')) && (i[1] <= _UT('f')))
+ || ((i[2] >= _UT('a')) && (i[2] <= _UT('f')))) {
+ return URI_TRUE;
+ } else {
+ /* 6.2.2.2 Percent-Encoding Normalization: *
+ * percent-encoded unreserved characters */
+ const unsigned char left = URI_FUNC(HexdigToInt)(i[1]);
+ const unsigned char right = URI_FUNC(HexdigToInt)(i[2]);
+ const int code = 16 * left + right;
+ if (uriIsUnreserved(code)) {
+ return URI_TRUE;
+ }
+ }
+ }
+ }
+ }
+ return URI_FALSE;
+}
+
+
+
+static URI_INLINE void URI_FUNC(LowercaseInplace)(const URI_CHAR * first,
+ const URI_CHAR * afterLast) {
+ if ((first != NULL) && (afterLast != NULL) && (afterLast > first)) {
+ URI_CHAR * i = (URI_CHAR *)first;
+ const int lowerUpperDiff = (_UT('a') - _UT('A'));
+ for (; i < afterLast; i++) {
+ if ((*i >= _UT('A')) && (*i <=_UT('Z'))) {
+ *i = (URI_CHAR)(*i + lowerUpperDiff);
+ }
+ }
+ }
+}
+
+
+
+static URI_INLINE UriBool URI_FUNC(LowercaseMalloc)(const URI_CHAR ** first,
+ const URI_CHAR ** afterLast) {
+ int lenInChars;
+ const int lowerUpperDiff = (_UT('a') - _UT('A'));
+ URI_CHAR * buffer;
+ int i = 0;
+
+ if ((first == NULL) || (afterLast == NULL) || (*first == NULL)
+ || (*afterLast == NULL)) {
+ return URI_FALSE;
+ }
+
+ lenInChars = (int)(*afterLast - *first);
+ if (lenInChars == 0) {
+ return URI_TRUE;
+ } else if (lenInChars < 0) {
+ return URI_FALSE;
+ }
+
+ buffer = malloc(lenInChars * sizeof(URI_CHAR));
+ if (buffer == NULL) {
+ return URI_FALSE;
+ }
+
+ for (; i < lenInChars; i++) {
+ if (((*first)[i] >= _UT('A')) && ((*first)[i] <=_UT('Z'))) {
+ buffer[i] = (URI_CHAR)((*first)[i] + lowerUpperDiff);
+ } else {
+ buffer[i] = (*first)[i];
+ }
+ }
+
+ *first = buffer;
+ *afterLast = buffer + lenInChars;
+ return URI_TRUE;
+}
+
+
+
+/* NOTE: Implementation must stay inplace-compatible */
+static URI_INLINE void URI_FUNC(FixPercentEncodingEngine)(
+ const URI_CHAR * inFirst, const URI_CHAR * inAfterLast,
+ const URI_CHAR * outFirst, const URI_CHAR ** outAfterLast) {
+ URI_CHAR * write = (URI_CHAR *)outFirst;
+ const int lenInChars = (int)(inAfterLast - inFirst);
+ int i = 0;
+
+ /* All but last two */
+ for (; i + 2 < lenInChars; i++) {
+ if (inFirst[i] != _UT('%')) {
+ write[0] = inFirst[i];
+ write++;
+ } else {
+ /* 6.2.2.2 Percent-Encoding Normalization: *
+ * percent-encoded unreserved characters */
+ const URI_CHAR one = inFirst[i + 1];
+ const URI_CHAR two = inFirst[i + 2];
+ const unsigned char left = URI_FUNC(HexdigToInt)(one);
+ const unsigned char right = URI_FUNC(HexdigToInt)(two);
+ const int code = 16 * left + right;
+ if (uriIsUnreserved(code)) {
+ write[0] = (URI_CHAR)(code);
+ write++;
+ } else {
+ /* 6.2.2.1 Case Normalization: *
+ * lowercase percent-encodings */
+ write[0] = _UT('%');
+ write[1] = URI_FUNC(HexToLetter)(left);
+ write[2] = URI_FUNC(HexToLetter)(right);
+ write += 3;
+ }
+
+ i += 2; /* For the two chars of the percent group we just ate */
+ }
+ }
+
+ /* Last two */
+ for (; i < lenInChars; i++) {
+ write[0] = inFirst[i];
+ write++;
+ }
+
+ *outAfterLast = write;
+}
+
+
+
+static URI_INLINE void URI_FUNC(FixPercentEncodingInplace)(const URI_CHAR * first,
+ const URI_CHAR ** afterLast) {
+ /* Death checks */
+ if ((first == NULL) || (afterLast == NULL) || (*afterLast == NULL)) {
+ return;
+ }
+
+ /* Fix inplace */
+ URI_FUNC(FixPercentEncodingEngine)(first, *afterLast, first, afterLast);
+}
+
+
+
+static URI_INLINE UriBool URI_FUNC(FixPercentEncodingMalloc)(const URI_CHAR ** first,
+ const URI_CHAR ** afterLast) {
+ int lenInChars;
+ URI_CHAR * buffer;
+
+ /* Death checks */
+ if ((first == NULL) || (afterLast == NULL)
+ || (*first == NULL) || (*afterLast == NULL)) {
+ return URI_FALSE;
+ }
+
+ /* Old text length */
+ lenInChars = (int)(*afterLast - *first);
+ if (lenInChars == 0) {
+ return URI_TRUE;
+ } else if (lenInChars < 0) {
+ return URI_FALSE;
+ }
+
+ /* New buffer */
+ buffer = malloc(lenInChars * sizeof(URI_CHAR));
+ if (buffer == NULL) {
+ return URI_FALSE;
+ }
+
+ /* Fix on copy */
+ URI_FUNC(FixPercentEncodingEngine)(*first, *afterLast, buffer, afterLast);
+ *first = buffer;
+ return URI_TRUE;
+}
+
+
+
+static URI_INLINE UriBool URI_FUNC(MakeRangeOwner)(unsigned int * doneMask,
+ unsigned int maskTest, URI_TYPE(TextRange) * range) {
+ if (((*doneMask & maskTest) == 0)
+ && (range->first != NULL)
+ && (range->afterLast != NULL)
+ && (range->afterLast > range->first)) {
+ const int lenInChars = (int)(range->afterLast - range->first);
+ const int lenInBytes = lenInChars * sizeof(URI_CHAR);
+ URI_CHAR * dup = malloc(lenInBytes);
+ if (dup == NULL) {
+ return URI_FALSE; /* Raises malloc error */
+ }
+ memcpy(dup, range->first, lenInBytes);
+ range->first = dup;
+ range->afterLast = dup + lenInChars;
+ *doneMask |= maskTest;
+ }
+ return URI_TRUE;
+}
+
+
+
+static URI_INLINE UriBool URI_FUNC(MakeOwner)(URI_TYPE(Uri) * uri,
+ unsigned int * doneMask) {
+ URI_TYPE(PathSegment) * walker = uri->pathHead;
+ if (!URI_FUNC(MakeRangeOwner)(doneMask, URI_NORMALIZE_SCHEME,
+ &(uri->scheme))
+ || !URI_FUNC(MakeRangeOwner)(doneMask, URI_NORMALIZE_USER_INFO,
+ &(uri->userInfo))
+ || !URI_FUNC(MakeRangeOwner)(doneMask, URI_NORMALIZE_QUERY,
+ &(uri->query))
+ || !URI_FUNC(MakeRangeOwner)(doneMask, URI_NORMALIZE_FRAGMENT,
+ &(uri->fragment))) {
+ return URI_FALSE; /* Raises malloc error */
+ }
+
+ /* Host */
+ if ((*doneMask & URI_NORMALIZE_HOST) == 0) {
+ if ((uri->hostData.ip4 == NULL)
+ && (uri->hostData.ip6 == NULL)) {
+ if (uri->hostData.ipFuture.first != NULL) {
+ /* IPvFuture */
+ if (!URI_FUNC(MakeRangeOwner)(doneMask, URI_NORMALIZE_HOST,
+ &(uri->hostData.ipFuture))) {
+ return URI_FALSE; /* Raises malloc error */
+ }
+ uri->hostText.first = uri->hostData.ipFuture.first;
+ uri->hostText.afterLast = uri->hostData.ipFuture.afterLast;
+ } else if (uri->hostText.first != NULL) {
+ /* Regname */
+ if (!URI_FUNC(MakeRangeOwner)(doneMask, URI_NORMALIZE_HOST,
+ &(uri->hostText))) {
+ return URI_FALSE; /* Raises malloc error */
+ }
+ }
+ }
+ }
+
+ /* Path */
+ if ((*doneMask & URI_NORMALIZE_PATH) == 0) {
+ while (walker != NULL) {
+ if (!URI_FUNC(MakeRangeOwner)(doneMask, 0, &(walker->text))) {
+ /* Kill path to one before walker */
+ URI_TYPE(PathSegment) * ranger = uri->pathHead;
+ while (ranger->next != walker) {
+ URI_TYPE(PathSegment) * const next = ranger->next;
+ if ((ranger->text.first != NULL)
+ && (ranger->text.afterLast != NULL)
+ && (ranger->text.afterLast > ranger->text.first)) {
+ free((URI_CHAR *)ranger->text.first);
+ free(ranger);
+ }
+ ranger = next;
+ }
+
+ /* Kill path from walker */
+ while (walker != NULL) {
+ URI_TYPE(PathSegment) * const next = walker->next;
+ free(walker);
+ walker = next;
+ }
+
+ uri->pathHead = NULL;
+ uri->pathTail = NULL;
+ return URI_FALSE; /* Raises malloc error */
+ }
+ walker = walker->next;
+ }
+ *doneMask |= URI_NORMALIZE_PATH;
+ }
+
+ /* Port text, must come last so we don't have to undo that one if it fails. *
+ * Otherwise we would need and extra enum flag for it although the port *
+ * cannot go unnormalized... */
+ if (!URI_FUNC(MakeRangeOwner)(doneMask, 0, &(uri->portText))) {
+ return URI_FALSE; /* Raises malloc error */
+ }
+
+ return URI_TRUE;
+}
+
+
+
+unsigned int URI_FUNC(NormalizeSyntaxMaskRequired)(const URI_TYPE(Uri) * uri) {
+ unsigned int res;
+#if defined(__GNUC__) && ((__GNUC__ > 4) \
+ || ((__GNUC__ == 4) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 2)))
+ /* Slower code that fixes a warning, not sure if this is a smart idea */
+ URI_TYPE(Uri) writeableClone;
+ memcpy(&writeableClone, uri, 1 * sizeof(URI_TYPE(Uri)));
+ URI_FUNC(NormalizeSyntaxEngine)(&writeableClone, 0, &res);
+#else
+ URI_FUNC(NormalizeSyntaxEngine)((URI_TYPE(Uri) *)uri, 0, &res);
+#endif
+ return res;
+}
+
+
+
+int URI_FUNC(NormalizeSyntaxEx)(URI_TYPE(Uri) * uri, unsigned int mask) {
+ return URI_FUNC(NormalizeSyntaxEngine)(uri, mask, NULL);
+}
+
+
+
+int URI_FUNC(NormalizeSyntax)(URI_TYPE(Uri) * uri) {
+ return URI_FUNC(NormalizeSyntaxEx)(uri, (unsigned int)-1);
+}
+
+
+
+static URI_INLINE int URI_FUNC(NormalizeSyntaxEngine)(URI_TYPE(Uri) * uri, unsigned int inMask, unsigned int * outMask) {
+ unsigned int doneMask = URI_NORMALIZED;
+ if (uri == NULL) {
+ if (outMask != NULL) {
+ *outMask = URI_NORMALIZED;
+ return URI_SUCCESS;
+ } else {
+ return URI_ERROR_NULL;
+ }
+ }
+
+ if (outMask != NULL) {
+ /* Reset mask */
+ *outMask = URI_NORMALIZED;
+ } else if (inMask == URI_NORMALIZED) {
+ /* Nothing to do */
+ return URI_SUCCESS;
+ }
+
+ /* Scheme, host */
+ if (outMask != NULL) {
+ const UriBool normalizeScheme = URI_FUNC(ContainsUppercaseLetters)(
+ uri->scheme.first, uri->scheme.afterLast);
+ const UriBool normalizeHostCase = URI_FUNC(ContainsUppercaseLetters)(
+ uri->hostText.first, uri->hostText.afterLast);
+ if (normalizeScheme) {
+ *outMask |= URI_NORMALIZE_SCHEME;
+ }
+
+ if (normalizeHostCase) {
+ *outMask |= URI_NORMALIZE_HOST;
+ } else {
+ const UriBool normalizeHostPrecent = URI_FUNC(ContainsUglyPercentEncoding)(
+ uri->hostText.first, uri->hostText.afterLast);
+ if (normalizeHostPrecent) {
+ *outMask |= URI_NORMALIZE_HOST;
+ }
+ }
+ } else {
+ /* Scheme */
+ if ((inMask & URI_NORMALIZE_SCHEME) && (uri->scheme.first != NULL)) {
+ if (uri->owner) {
+ URI_FUNC(LowercaseInplace)(uri->scheme.first, uri->scheme.afterLast);
+ } else {
+ if (!URI_FUNC(LowercaseMalloc)(&(uri->scheme.first), &(uri->scheme.afterLast))) {
+ URI_FUNC(PreventLeakage)(uri, doneMask);
+ return URI_ERROR_MALLOC;
+ }
+ doneMask |= URI_NORMALIZE_SCHEME;
+ }
+ }
+
+ /* Host */
+ if (inMask & URI_NORMALIZE_HOST) {
+ if (uri->hostData.ipFuture.first != NULL) {
+ /* IPvFuture */
+ if (uri->owner) {
+ URI_FUNC(LowercaseInplace)(uri->hostData.ipFuture.first,
+ uri->hostData.ipFuture.afterLast);
+ } else {
+ if (!URI_FUNC(LowercaseMalloc)(&(uri->hostData.ipFuture.first),
+ &(uri->hostData.ipFuture.afterLast))) {
+ URI_FUNC(PreventLeakage)(uri, doneMask);
+ return URI_ERROR_MALLOC;
+ }
+ doneMask |= URI_NORMALIZE_HOST;
+ }
+ uri->hostText.first = uri->hostData.ipFuture.first;
+ uri->hostText.afterLast = uri->hostData.ipFuture.afterLast;
+ } else if ((uri->hostText.first != NULL)
+ && (uri->hostData.ip4 == NULL)
+ && (uri->hostData.ip6 == NULL)) {
+ /* Regname */
+ if (uri->owner) {
+ URI_FUNC(FixPercentEncodingInplace)(uri->hostText.first,
+ &(uri->hostText.afterLast));
+ } else {
+ if (!URI_FUNC(FixPercentEncodingMalloc)(
+ &(uri->hostText.first),
+ &(uri->hostText.afterLast))) {
+ URI_FUNC(PreventLeakage)(uri, doneMask);
+ return URI_ERROR_MALLOC;
+ }
+ doneMask |= URI_NORMALIZE_HOST;
+ }
+
+ URI_FUNC(LowercaseInplace)(uri->hostText.first,
+ uri->hostText.afterLast);
+ }
+ }
+ }
+
+ /* User info */
+ if (outMask != NULL) {
+ const UriBool normalizeUserInfo = URI_FUNC(ContainsUglyPercentEncoding)(
+ uri->userInfo.first, uri->userInfo.afterLast);
+ if (normalizeUserInfo) {
+ *outMask |= URI_NORMALIZE_USER_INFO;
+ }
+ } else {
+ if ((inMask & URI_NORMALIZE_USER_INFO) && (uri->userInfo.first != NULL)) {
+ if (uri->owner) {
+ URI_FUNC(FixPercentEncodingInplace)(uri->userInfo.first, &(uri->userInfo.afterLast));
+ } else {
+ if (!URI_FUNC(FixPercentEncodingMalloc)(&(uri->userInfo.first),
+ &(uri->userInfo.afterLast))) {
+ URI_FUNC(PreventLeakage)(uri, doneMask);
+ return URI_ERROR_MALLOC;
+ }
+ doneMask |= URI_NORMALIZE_USER_INFO;
+ }
+ }
+ }
+
+ /* Path */
+ if (outMask != NULL) {
+ const URI_TYPE(PathSegment) * walker = uri->pathHead;
+ while (walker != NULL) {
+ const URI_CHAR * const first = walker->text.first;
+ const URI_CHAR * const afterLast = walker->text.afterLast;
+ if ((first != NULL)
+ && (afterLast != NULL)
+ && (afterLast > first)
+ && (
+ (((afterLast - first) == 1)
+ && (first[0] == _UT('.')))
+ ||
+ (((afterLast - first) == 2)
+ && (first[0] == _UT('.'))
+ && (first[1] == _UT('.')))
+ ||
+ URI_FUNC(ContainsUglyPercentEncoding)(first, afterLast)
+ )) {
+ *outMask |= URI_NORMALIZE_PATH;
+ break;
+ }
+ walker = walker->next;
+ }
+ } else if (inMask & URI_NORMALIZE_PATH) {
+ URI_TYPE(PathSegment) * walker;
+ const UriBool relative = ((uri->scheme.first == NULL)
+ && !uri->absolutePath) ? URI_TRUE : URI_FALSE;
+
+ /* Fix percent-encoding for each segment */
+ walker = uri->pathHead;
+ if (uri->owner) {
+ while (walker != NULL) {
+ URI_FUNC(FixPercentEncodingInplace)(walker->text.first, &(walker->text.afterLast));
+ walker = walker->next;
+ }
+ } else {
+ while (walker != NULL) {
+ if (!URI_FUNC(FixPercentEncodingMalloc)(&(walker->text.first),
+ &(walker->text.afterLast))) {
+ URI_FUNC(PreventLeakage)(uri, doneMask);
+ return URI_ERROR_MALLOC;
+ }
+ walker = walker->next;
+ }
+ doneMask |= URI_NORMALIZE_PATH;
+ }
+
+ /* 6.2.2.3 Path Segment Normalization */
+ if (!URI_FUNC(RemoveDotSegments)(uri, relative)) {
+ URI_FUNC(PreventLeakage)(uri, doneMask);
+ return URI_ERROR_MALLOC;
+ }
+ }
+
+ /* Query, fragment */
+ if (outMask != NULL) {
+ const UriBool normalizeQuery = URI_FUNC(ContainsUglyPercentEncoding)(
+ uri->query.first, uri->query.afterLast);
+ const UriBool normalizeFragment = URI_FUNC(ContainsUglyPercentEncoding)(
+ uri->fragment.first, uri->fragment.afterLast);
+ if (normalizeQuery) {
+ *outMask |= URI_NORMALIZE_QUERY;
+ }
+
+ if (normalizeFragment) {
+ *outMask |= URI_NORMALIZE_FRAGMENT;
+ }
+ } else {
+ /* Query */
+ if ((inMask & URI_NORMALIZE_QUERY) && (uri->query.first != NULL)) {
+ if (uri->owner) {
+ URI_FUNC(FixPercentEncodingInplace)(uri->query.first, &(uri->query.afterLast));
+ } else {
+ if (!URI_FUNC(FixPercentEncodingMalloc)(&(uri->query.first),
+ &(uri->query.afterLast))) {
+ URI_FUNC(PreventLeakage)(uri, doneMask);
+ return URI_ERROR_MALLOC;
+ }
+ doneMask |= URI_NORMALIZE_QUERY;
+ }
+ }
+
+ /* Fragment */
+ if ((inMask & URI_NORMALIZE_FRAGMENT) && (uri->fragment.first != NULL)) {
+ if (uri->owner) {
+ URI_FUNC(FixPercentEncodingInplace)(uri->fragment.first, &(uri->fragment.afterLast));
+ } else {
+ if (!URI_FUNC(FixPercentEncodingMalloc)(&(uri->fragment.first),
+ &(uri->fragment.afterLast))) {
+ URI_FUNC(PreventLeakage)(uri, doneMask);
+ return URI_ERROR_MALLOC;
+ }
+ doneMask |= URI_NORMALIZE_FRAGMENT;
+ }
+ }
+ }
+
+ /* Dup all not duped yet */
+ if ((outMask == NULL) && !uri->owner) {
+ if (!URI_FUNC(MakeOwner)(uri, &doneMask)) {
+ URI_FUNC(PreventLeakage)(uri, doneMask);
+ return URI_ERROR_MALLOC;
+ }
+ uri->owner = URI_TRUE;
+ }
+
+ return URI_SUCCESS;
+}
+
+
+
+#endif
-/*\r
- * uriparser - RFC 3986 URI parsing library\r
- *\r
- * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>\r
- * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- *\r
- * * Redistributions of source code must retain the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer.\r
- *\r
- * * Redistributions in binary form must reproduce the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer in the documentation and/or other materials\r
- * provided with the distribution.\r
- *\r
- * * Neither the name of the <ORGANIZATION> nor the names of its\r
- * contributors may be used to endorse or promote products\r
- * derived from this software without specific prior written\r
- * permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
- * OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#ifndef URI_DOXYGEN\r
-# include "UriNormalizeBase.h"\r
-#endif\r
-\r
-\r
-\r
-UriBool uriIsUnreserved(int code) {\r
- switch (code) {\r
- case L'a': /* ALPHA */\r
- case L'A':\r
- case L'b':\r
- case L'B':\r
- case L'c':\r
- case L'C':\r
- case L'd':\r
- case L'D':\r
- case L'e':\r
- case L'E':\r
- case L'f':\r
- case L'F':\r
- case L'g':\r
- case L'G':\r
- case L'h':\r
- case L'H':\r
- case L'i':\r
- case L'I':\r
- case L'j':\r
- case L'J':\r
- case L'k':\r
- case L'K':\r
- case L'l':\r
- case L'L':\r
- case L'm':\r
- case L'M':\r
- case L'n':\r
- case L'N':\r
- case L'o':\r
- case L'O':\r
- case L'p':\r
- case L'P':\r
- case L'q':\r
- case L'Q':\r
- case L'r':\r
- case L'R':\r
- case L's':\r
- case L'S':\r
- case L't':\r
- case L'T':\r
- case L'u':\r
- case L'U':\r
- case L'v':\r
- case L'V':\r
- case L'w':\r
- case L'W':\r
- case L'x':\r
- case L'X':\r
- case L'y':\r
- case L'Y':\r
- case L'z':\r
- case L'Z':\r
- case L'0': /* DIGIT */\r
- case L'1':\r
- case L'2':\r
- case L'3':\r
- case L'4':\r
- case L'5':\r
- case L'6':\r
- case L'7':\r
- case L'8':\r
- case L'9':\r
- case L'-': /* "-" / "." / "_" / "~" */\r
- case L'.':\r
- case L'_':\r
- case L'~':\r
- return URI_TRUE;\r
-\r
- default:\r
- return URI_FALSE;\r
- }\r
-}\r
+/*
+ * uriparser - RFC 3986 URI parsing library
+ *
+ * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>
+ * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the <ORGANIZATION> nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef URI_DOXYGEN
+# include "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;
+
+ default:
+ return URI_FALSE;
+ }
+}
-/*\r
- * uriparser - RFC 3986 URI parsing library\r
- *\r
- * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>\r
- * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- *\r
- * * Redistributions of source code must retain the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer.\r
- *\r
- * * Redistributions in binary form must reproduce the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer in the documentation and/or other materials\r
- * provided with the distribution.\r
- *\r
- * * Neither the name of the <ORGANIZATION> nor the names of its\r
- * contributors may be used to endorse or promote products\r
- * derived from this software without specific prior written\r
- * permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
- * OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#ifndef URI_NORMALIZE_BASE_H\r
-#define URI_NORMALIZE_BASE_H 1\r
-\r
-\r
-\r
-#include <uriparser/UriBase.h>\r
-\r
-\r
-\r
-UriBool uriIsUnreserved(int code);\r
-\r
-\r
-\r
-#endif /* URI_NORMALIZE_BASE_H */\r
+/*
+ * uriparser - RFC 3986 URI parsing library
+ *
+ * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>
+ * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the <ORGANIZATION> nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef URI_NORMALIZE_BASE_H
+#define URI_NORMALIZE_BASE_H 1
+
+
+
+#include <uriparser/UriBase.h>
+
+
+
+UriBool uriIsUnreserved(int code);
+
+
+
+#endif /* URI_NORMALIZE_BASE_H */
-/*\r
- * uriparser - RFC 3986 URI parsing library\r
- *\r
- * Copyright (C) 2007, Weijia Song <songweijia@gmail.com>\r
- * Copyright (C) 2007, Sebastian Pipping <webmaster@hartwork.org>\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- *\r
- * * Redistributions of source code must retain the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer.\r
- *\r
- * * Redistributions in binary form must reproduce the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer in the documentation and/or other materials\r
- * provided with the distribution.\r
- *\r
- * * Neither the name of the <ORGANIZATION> nor the names of its\r
- * contributors may be used to endorse or promote products\r
- * derived from this software without specific prior written\r
- * permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\r
- * OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/**\r
- * @file UriParse.c\r
- * Holds the RFC 3986 %URI parsing implementation.\r
- * NOTE: This source file includes itself twice.\r
- */\r
-\r
-/* What encodings are enabled? */\r
-#include <uriparser/UriDefsConfig.h>\r
-#if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE))\r
-/* Include SELF twice */\r
-# define URI_PASS_ANSI 1\r
-# include "UriParse.c"\r
-# undef URI_PASS_ANSI\r
-# define URI_PASS_UNICODE 1\r
-# include "UriParse.c"\r
-# undef URI_PASS_UNICODE\r
-#else\r
-# ifdef URI_PASS_ANSI\r
-# include <uriparser/UriDefsAnsi.h>\r
-# else\r
-# include <uriparser/UriDefsUnicode.h>\r
-# include <wchar.h>\r
-# endif\r
-\r
-\r
-\r
-#ifndef URI_DOXYGEN\r
-# include <uriparser/Uri.h>\r
-# include <uriparser/UriIp4.h>\r
-# include "UriCommon.h"\r
-# include "UriParseBase.h"\r
-#endif\r
-\r
-\r
-\r
-#define URI_SET_DIGIT \\r
- _UT('0'): \\r
- case _UT('1'): \\r
- case _UT('2'): \\r
- case _UT('3'): \\r
- case _UT('4'): \\r
- case _UT('5'): \\r
- case _UT('6'): \\r
- case _UT('7'): \\r
- case _UT('8'): \\r
- case _UT('9')\r
-\r
-#define URI_SET_HEX_LETTER_UPPER \\r
- _UT('A'): \\r
- case _UT('B'): \\r
- case _UT('C'): \\r
- case _UT('D'): \\r
- case _UT('E'): \\r
- case _UT('F')\r
-\r
-#define URI_SET_HEX_LETTER_LOWER \\r
- _UT('a'): \\r
- case _UT('b'): \\r
- case _UT('c'): \\r
- case _UT('d'): \\r
- case _UT('e'): \\r
- case _UT('f')\r
-\r
-#define URI_SET_HEXDIG \\r
- URI_SET_DIGIT: \\r
- case URI_SET_HEX_LETTER_UPPER: \\r
- case URI_SET_HEX_LETTER_LOWER\r
-\r
-#define URI_SET_ALPHA \\r
- URI_SET_HEX_LETTER_UPPER: \\r
- case URI_SET_HEX_LETTER_LOWER: \\r
- case _UT('g'): \\r
- case _UT('G'): \\r
- case _UT('h'): \\r
- case _UT('H'): \\r
- case _UT('i'): \\r
- case _UT('I'): \\r
- case _UT('j'): \\r
- case _UT('J'): \\r
- case _UT('k'): \\r
- case _UT('K'): \\r
- case _UT('l'): \\r
- case _UT('L'): \\r
- case _UT('m'): \\r
- case _UT('M'): \\r
- case _UT('n'): \\r
- case _UT('N'): \\r
- case _UT('o'): \\r
- case _UT('O'): \\r
- case _UT('p'): \\r
- case _UT('P'): \\r
- case _UT('q'): \\r
- case _UT('Q'): \\r
- case _UT('r'): \\r
- case _UT('R'): \\r
- case _UT('s'): \\r
- case _UT('S'): \\r
- case _UT('t'): \\r
- case _UT('T'): \\r
- case _UT('u'): \\r
- case _UT('U'): \\r
- case _UT('v'): \\r
- case _UT('V'): \\r
- case _UT('w'): \\r
- case _UT('W'): \\r
- case _UT('x'): \\r
- case _UT('X'): \\r
- case _UT('y'): \\r
- case _UT('Y'): \\r
- case _UT('z'): \\r
- case _UT('Z')\r
-\r
-\r
-\r
-static const URI_CHAR * URI_FUNC(ParseAuthority)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseAuthorityTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseHexZero)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseHierPart)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseIpFutLoop)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseIpFutStopGo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseIpLit2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseMustBeSegmentNzNc)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseOwnHost)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseOwnHost2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseOwnHostUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseOwnHostUserInfoNz)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseOwnPortUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseOwnUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParsePartHelperTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParsePathAbsEmpty)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParsePathAbsNoLeadSlash)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParsePathRootless)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParsePchar)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParsePctEncoded)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParsePctSubUnres)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParsePort)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseQueryFrag)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseSegment)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseSegmentNz)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseSegmentNzNcOrScheme2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseUriReference)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseUriTail)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseUriTailTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-static const URI_CHAR * URI_FUNC(ParseZeroMoreSlashSegs)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-\r
-static UriBool URI_FUNC(OnExitOwnHost2)(URI_TYPE(ParserState) * state, const URI_CHAR * first);\r
-static UriBool URI_FUNC(OnExitOwnHostUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first);\r
-static UriBool URI_FUNC(OnExitOwnPortUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first);\r
-static UriBool URI_FUNC(OnExitSegmentNzNcOrScheme2)(URI_TYPE(ParserState) * state, const URI_CHAR * first);\r
-static void URI_FUNC(OnExitPartHelperTwo)(URI_TYPE(ParserState) * state);\r
-\r
-static void URI_FUNC(ResetParserState)(URI_TYPE(ParserState) * state);\r
-\r
-static UriBool URI_FUNC(PushPathSegment)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast);\r
-\r
-static void URI_FUNC(StopSyntax)(URI_TYPE(ParserState) * state, const URI_CHAR * errorPos);\r
-static void URI_FUNC(StopMalloc)(URI_TYPE(ParserState) * state);\r
-\r
-\r
-\r
-static URI_INLINE void URI_FUNC(StopSyntax)(URI_TYPE(ParserState) * state,\r
- const URI_CHAR * errorPos) {\r
- URI_FUNC(FreeUriMembers)(state->uri);\r
- state->errorPos = errorPos;\r
- state->errorCode = URI_ERROR_SYNTAX;\r
-}\r
-\r
-\r
-\r
-static URI_INLINE void URI_FUNC(StopMalloc)(URI_TYPE(ParserState) * state) {\r
- URI_FUNC(FreeUriMembers)(state->uri);\r
- state->errorPos = NULL;\r
- state->errorCode = URI_ERROR_MALLOC;\r
-}\r
-\r
-\r
-\r
-/*\r
- * [authority]-><[>[ipLit2][authorityTwo]\r
- * [authority]->[ownHostUserInfoNz]\r
- * [authority]-><NULL>\r
- */\r
-static URI_INLINE const URI_CHAR * URI_FUNC(ParseAuthority)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) {\r
- if (first >= afterLast) {\r
- /* "" regname host */\r
- state->uri->hostText.first = URI_FUNC(SafeToPointTo);\r
- state->uri->hostText.afterLast = URI_FUNC(SafeToPointTo);\r
- return afterLast;\r
- }\r
-\r
- switch (*first) {\r
- case _UT('['):\r
- {\r
- const URI_CHAR * const afterIpLit2\r
- = URI_FUNC(ParseIpLit2)(state, first + 1, afterLast);\r
- if (afterIpLit2 == NULL) {\r
- return NULL;\r
- }\r
- state->uri->hostText.first = first + 1; /* HOST BEGIN */\r
- return URI_FUNC(ParseAuthorityTwo)(state, afterIpLit2, afterLast);\r
- }\r
-\r
- case _UT('!'):\r
- case _UT('$'):\r
- case _UT('%'):\r
- case _UT('&'):\r
- case _UT('('):\r
- case _UT(')'):\r
- case _UT('-'):\r
- case _UT('*'):\r
- case _UT(','):\r
- case _UT('.'):\r
- case _UT(':'):\r
- case _UT(';'):\r
- case _UT('@'):\r
- case _UT('\''):\r
- case _UT('_'):\r
- case _UT('~'):\r
- case _UT('+'):\r
- case _UT('='):\r
- case URI_SET_DIGIT:\r
- case URI_SET_ALPHA:\r
- state->uri->userInfo.first = first; /* USERINFO BEGIN */\r
- return URI_FUNC(ParseOwnHostUserInfoNz)(state, first, afterLast);\r
-\r
- default:\r
- /* "" regname host */\r
- state->uri->hostText.first = URI_FUNC(SafeToPointTo);\r
- state->uri->hostText.afterLast = URI_FUNC(SafeToPointTo);\r
- return first;\r
- }\r
-}\r
-\r
-\r
-\r
-/*\r
- * [authorityTwo]-><:>[port]\r
- * [authorityTwo]-><NULL>\r
- */\r
-static URI_INLINE const URI_CHAR * URI_FUNC(ParseAuthorityTwo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) {\r
- if (first >= afterLast) {\r
- return afterLast;\r
- }\r
-\r
- switch (*first) {\r
- case _UT(':'):\r
- {\r
- const URI_CHAR * const afterPort = URI_FUNC(ParsePort)(state, first + 1, afterLast);\r
- if (afterPort == NULL) {\r
- return NULL;\r
- }\r
- state->uri->portText.first = first + 1; /* PORT BEGIN */\r
- state->uri->portText.afterLast = afterPort; /* PORT END */\r
- return afterPort;\r
- }\r
-\r
- default:\r
- return first;\r
- }\r
-}\r
-\r
-\r
-\r
-/*\r
- * [hexZero]->[HEXDIG][hexZero]\r
- * [hexZero]-><NULL>\r
- */\r
-static const URI_CHAR * URI_FUNC(ParseHexZero)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) {\r
- if (first >= afterLast) {\r
- return afterLast;\r
- }\r
-\r
- switch (*first) {\r
- case URI_SET_HEXDIG:\r
- return URI_FUNC(ParseHexZero)(state, first + 1, afterLast);\r
-\r
- default:\r
- return first;\r
- }\r
-}\r
-\r
-\r
-\r
-/*\r
- * [hierPart]->[pathRootless]\r
- * [hierPart]-></>[partHelperTwo]\r
- * [hierPart]-><NULL>\r
- */\r
-static URI_INLINE const URI_CHAR * URI_FUNC(ParseHierPart)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) {\r
- if (first >= afterLast) {\r
- return afterLast;\r
- }\r
-\r
- switch (*first) {\r
- case _UT('!'):\r
- case _UT('$'):\r
- case _UT('%'):\r
- case _UT('&'):\r
- case _UT('('):\r
- case _UT(')'):\r
- case _UT('-'):\r
- case _UT('*'):\r
- case _UT(','):\r
- case _UT('.'):\r
- case _UT(':'):\r
- case _UT(';'):\r
- case _UT('@'):\r
- case _UT('\''):\r
- case _UT('_'):\r
- case _UT('~'):\r
- case _UT('+'):\r
- case _UT('='):\r
- case URI_SET_DIGIT:\r
- case URI_SET_ALPHA:\r
- return URI_FUNC(ParsePathRootless)(state, first, afterLast);\r
-\r
- case _UT('/'):\r
- return URI_FUNC(ParsePartHelperTwo)(state, first + 1, afterLast);\r
-\r
- default:\r
- return first;\r
- }\r
-}\r
-\r
-\r
-\r
-/*\r
- * [ipFutLoop]->[subDelims][ipFutStopGo]\r
- * [ipFutLoop]->[unreserved][ipFutStopGo]\r
- * [ipFutLoop]-><:>[ipFutStopGo]\r
- */\r
-static const URI_CHAR * URI_FUNC(ParseIpFutLoop)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) {\r
- if (first >= afterLast) {\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- }\r
-\r
- switch (*first) {\r
- case _UT('!'):\r
- case _UT('$'):\r
- case _UT('&'):\r
- case _UT('('):\r
- case _UT(')'):\r
- case _UT('-'):\r
- case _UT('*'):\r
- case _UT(','):\r
- case _UT('.'):\r
- case _UT(':'):\r
- case _UT(';'):\r
- case _UT('\''):\r
- case _UT('_'):\r
- case _UT('~'):\r
- case _UT('+'):\r
- case _UT('='):\r
- case URI_SET_DIGIT:\r
- case URI_SET_ALPHA:\r
- return URI_FUNC(ParseIpFutStopGo)(state, first + 1, afterLast);\r
-\r
- default:\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- }\r
-}\r
-\r
-\r
-\r
-/*\r
- * [ipFutStopGo]->[ipFutLoop]\r
- * [ipFutStopGo]-><NULL>\r
- */\r
-static const URI_CHAR * URI_FUNC(ParseIpFutStopGo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) {\r
- if (first >= afterLast) {\r
- return afterLast;\r
- }\r
-\r
- switch (*first) {\r
- case _UT('!'):\r
- case _UT('$'):\r
- case _UT('&'):\r
- case _UT('('):\r
- case _UT(')'):\r
- case _UT('-'):\r
- case _UT('*'):\r
- case _UT(','):\r
- case _UT('.'):\r
- case _UT(':'):\r
- case _UT(';'):\r
- case _UT('\''):\r
- case _UT('_'):\r
- case _UT('~'):\r
- case _UT('+'):\r
- case _UT('='):\r
- case URI_SET_DIGIT:\r
- case URI_SET_ALPHA:\r
- return URI_FUNC(ParseIpFutLoop)(state, first, afterLast);\r
-\r
- default:\r
- return first;\r
- }\r
-}\r
-\r
-\r
-\r
-/*\r
- * [ipFuture]-><v>[HEXDIG][hexZero]<.>[ipFutLoop]\r
- */\r
-static const URI_CHAR * URI_FUNC(ParseIpFuture)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) {\r
- if (first >= afterLast) {\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- }\r
-\r
- /*\r
- First character has already been\r
- checked before entering this rule.\r
-\r
- switch (*first) {\r
- case _UT('v'):\r
- */\r
- if (first + 1 >= afterLast) {\r
- URI_FUNC(StopSyntax)(state, first + 1);\r
- return NULL;\r
- }\r
-\r
- switch (first[1]) {\r
- case URI_SET_HEXDIG:\r
- {\r
- const URI_CHAR * afterIpFutLoop;\r
- const URI_CHAR * const afterHexZero\r
- = URI_FUNC(ParseHexZero)(state, first + 2, afterLast);\r
- if (afterHexZero == NULL) {\r
- return NULL;\r
- }\r
- if ((afterHexZero >= afterLast)\r
- || (*afterHexZero != _UT('.'))) {\r
- URI_FUNC(StopSyntax)(state, afterHexZero);\r
- return NULL;\r
- }\r
- state->uri->hostText.first = first; /* HOST BEGIN */\r
- state->uri->hostData.ipFuture.first = first; /* IPFUTURE BEGIN */\r
- afterIpFutLoop = URI_FUNC(ParseIpFutLoop)(state, afterHexZero + 1, afterLast);\r
- if (afterIpFutLoop == NULL) {\r
- return NULL;\r
- }\r
- state->uri->hostText.afterLast = afterIpFutLoop; /* HOST END */\r
- state->uri->hostData.ipFuture.afterLast = afterIpFutLoop; /* IPFUTURE END */\r
- return afterIpFutLoop;\r
- }\r
-\r
- default:\r
- URI_FUNC(StopSyntax)(state, first + 1);\r
- return NULL;\r
- }\r
-\r
- /*\r
- default:\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- }\r
- */\r
-}\r
-\r
-\r
-\r
-/*\r
- * [ipLit2]->[ipFuture]<]>\r
- * [ipLit2]->[IPv6address2]\r
- */\r
-static URI_INLINE const URI_CHAR * URI_FUNC(ParseIpLit2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) {\r
- if (first >= afterLast) {\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- }\r
-\r
- switch (*first) {\r
- case _UT('v'):\r
- {\r
- const URI_CHAR * const afterIpFuture\r
- = URI_FUNC(ParseIpFuture)(state, first, afterLast);\r
- if (afterIpFuture == NULL) {\r
- return NULL;\r
- }\r
- if ((afterIpFuture >= afterLast)\r
- || (*afterIpFuture != _UT(']'))) {\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- }\r
- return afterIpFuture + 1;\r
- }\r
-\r
- case _UT(':'):\r
- case _UT(']'):\r
- case URI_SET_HEXDIG:\r
- state->uri->hostData.ip6 = malloc(1 * sizeof(UriIp6)); /* Freed when stopping on parse error */\r
- if (state->uri->hostData.ip6 == NULL) {\r
- URI_FUNC(StopMalloc)(state);\r
- return NULL;\r
- }\r
- return URI_FUNC(ParseIPv6address2)(state, first, afterLast);\r
-\r
- default:\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- }\r
-}\r
-\r
-\r
-\r
-/*\r
- * [IPv6address2]->..<]>\r
- */\r
-static const URI_CHAR * URI_FUNC(ParseIPv6address2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) {\r
- int zipperEver = 0;\r
- int quadsDone = 0;\r
- int digitCount = 0;\r
- unsigned char digitHistory[4];\r
- int ip4OctetsDone = 0;\r
-\r
- unsigned char quadsAfterZipper[14];\r
- int quadsAfterZipperCount = 0;\r
-\r
-\r
- for (;;) {\r
- if (first >= afterLast) {\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- }\r
-\r
- /* Inside IPv4 part? */\r
- if (ip4OctetsDone > 0) {\r
- /* Eat rest of IPv4 address */\r
- for (;;) {\r
- switch (*first) {\r
- case URI_SET_DIGIT:\r
- if (digitCount == 4) {\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- }\r
- digitHistory[digitCount++] = (unsigned char)(9 + *first - _UT('9'));\r
- break;\r
-\r
- case _UT('.'):\r
- if ((ip4OctetsDone == 4) /* NOTE! */\r
- || (digitCount == 0)\r
- || (digitCount == 4)) {\r
- /* Invalid digit or octet count */\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- } else if ((digitCount > 1)\r
- && (digitHistory[0] == 0)) {\r
- /* Leading zero */\r
- URI_FUNC(StopSyntax)(state, first - digitCount);\r
- return NULL;\r
- } else if ((digitCount > 2)\r
- && (digitHistory[1] == 0)) {\r
- /* Leading zero */\r
- URI_FUNC(StopSyntax)(state, first - digitCount + 1);\r
- return NULL;\r
- } else if ((digitCount == 3)\r
- && (100 * digitHistory[0]\r
- + 10 * digitHistory[1]\r
- + digitHistory[2] > 255)) {\r
- /* Octet value too large */\r
- if (digitHistory[0] > 2) {\r
- URI_FUNC(StopSyntax)(state, first - 3);\r
- } else if (digitHistory[1] > 5) {\r
- URI_FUNC(StopSyntax)(state, first - 2);\r
- } else {\r
- URI_FUNC(StopSyntax)(state, first - 1);\r
- }\r
- return NULL;\r
- }\r
-\r
- /* Copy IPv4 octet */\r
- state->uri->hostData.ip6->data[16 - 4 + ip4OctetsDone] = uriGetOctetValue(digitHistory, digitCount);\r
- digitCount = 0;\r
- ip4OctetsDone++;\r
- break;\r
-\r
- case _UT(']'):\r
- if ((ip4OctetsDone != 3) /* NOTE! */\r
- || (digitCount == 0)\r
- || (digitCount == 4)) {\r
- /* Invalid digit or octet count */\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- } else if ((digitCount > 1)\r
- && (digitHistory[0] == 0)) {\r
- /* Leading zero */\r
- URI_FUNC(StopSyntax)(state, first - digitCount);\r
- return NULL;\r
- } else if ((digitCount > 2)\r
- && (digitHistory[1] == 0)) {\r
- /* Leading zero */\r
- URI_FUNC(StopSyntax)(state, first - digitCount + 1);\r
- return NULL;\r
- } else if ((digitCount == 3)\r
- && (100 * digitHistory[0]\r
- + 10 * digitHistory[1]\r
- + digitHistory[2] > 255)) {\r
- /* Octet value too large */\r
- if (digitHistory[0] > 2) {\r
- URI_FUNC(StopSyntax)(state, first - 3);\r
- } else if (digitHistory[1] > 5) {\r
- URI_FUNC(StopSyntax)(state, first - 2);\r
- } else {\r
- URI_FUNC(StopSyntax)(state, first - 1);\r
- }\r
- return NULL;\r
- }\r
-\r
- state->uri->hostText.afterLast = first; /* HOST END */\r
-\r
- /* Copy missing quads right before IPv4 */\r
- memcpy(state->uri->hostData.ip6->data + 16 - 4 - 2 * quadsAfterZipperCount,\r
- quadsAfterZipper, 2 * quadsAfterZipperCount);\r
-\r
- /* Copy last IPv4 octet */\r
- state->uri->hostData.ip6->data[16 - 4 + 3] = uriGetOctetValue(digitHistory, digitCount);\r
-\r
- return first + 1;\r
-\r
- default:\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- }\r
- first++;\r
- }\r
- } else {\r
- /* Eat while no dot in sight */\r
- int letterAmong = 0;\r
- int walking = 1;\r
- do {\r
- switch (*first) {\r
- case URI_SET_HEX_LETTER_LOWER:\r
- letterAmong = 1;\r
- if (digitCount == 4) {\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- }\r
- digitHistory[digitCount] = (unsigned char)(15 + *first - _UT('f'));\r
- digitCount++;\r
- break;\r
-\r
- case URI_SET_HEX_LETTER_UPPER:\r
- letterAmong = 1;\r
- if (digitCount == 4) {\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- }\r
- digitHistory[digitCount] = (unsigned char)(15 + *first - _UT('F'));\r
- digitCount++;\r
- break;\r
-\r
- case URI_SET_DIGIT:\r
- if (digitCount == 4) {\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- }\r
- digitHistory[digitCount] = (unsigned char)(9 + *first - _UT('9'));\r
- digitCount++;\r
- break;\r
-\r
- case _UT(':'):\r
- {\r
- int setZipper = 0;\r
-\r
- /* Too many quads? */\r
- if (quadsDone > 8 - zipperEver) {\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- }\r
-\r
- /* "::"? */\r
- if (first + 1 >= afterLast) {\r
- URI_FUNC(StopSyntax)(state, first + 1);\r
- return NULL;\r
- }\r
- if (first[1] == _UT(':')) {\r
- const int resetOffset = 2 * (quadsDone + (digitCount > 0));\r
-\r
- first++;\r
- if (zipperEver) {\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL; /* "::.+::" */\r
- }\r
-\r
- /* Zero everything after zipper */\r
- memset(state->uri->hostData.ip6->data + resetOffset, 0, 16 - resetOffset);\r
- setZipper = 1;\r
-\r
- /* ":::+"? */\r
- if (first + 1 >= afterLast) {\r
- URI_FUNC(StopSyntax)(state, first + 1);\r
- return NULL; /* No ']' yet */\r
- }\r
- if (first[1] == _UT(':')) {\r
- URI_FUNC(StopSyntax)(state, first + 1);\r
- return NULL; /* ":::+ "*/\r
- }\r
- }\r
- if (digitCount > 0) {\r
- if (zipperEver) {\r
- uriWriteQuadToDoubleByte(digitHistory, digitCount, quadsAfterZipper + 2 * quadsAfterZipperCount);\r
- quadsAfterZipperCount++;\r
- } else {\r
- uriWriteQuadToDoubleByte(digitHistory, digitCount, state->uri->hostData.ip6->data + 2 * quadsDone);\r
- }\r
- quadsDone++;\r
- digitCount = 0;\r
- }\r
- letterAmong = 0;\r
-\r
- if (setZipper) {\r
- zipperEver = 1;\r
- }\r
- }\r
- break;\r
-\r
- case _UT('.'):\r
- if ((quadsDone > 6) /* NOTE */\r
- || (!zipperEver && (quadsDone < 6))\r
- || letterAmong\r
- || (digitCount == 0)\r
- || (digitCount == 4)) {\r
- /* Invalid octet before */\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- } else if ((digitCount > 1)\r
- && (digitHistory[0] == 0)) {\r
- /* Leading zero */\r
- URI_FUNC(StopSyntax)(state, first - digitCount);\r
- return NULL;\r
- } else if ((digitCount > 2)\r
- && (digitHistory[1] == 0)) {\r
- /* Leading zero */\r
- URI_FUNC(StopSyntax)(state, first - digitCount + 1);\r
- return NULL;\r
- } else if ((digitCount == 3)\r
- && (100 * digitHistory[0]\r
- + 10 * digitHistory[1]\r
- + digitHistory[2] > 255)) {\r
- /* Octet value too large */\r
- if (digitHistory[0] > 2) {\r
- URI_FUNC(StopSyntax)(state, first - 3);\r
- } else if (digitHistory[1] > 5) {\r
- URI_FUNC(StopSyntax)(state, first - 2);\r
- } else {\r
- URI_FUNC(StopSyntax)(state, first - 1);\r
- }\r
- return NULL;\r
- }\r
-\r
- /* Copy first IPv4 octet */\r
- state->uri->hostData.ip6->data[16 - 4] = uriGetOctetValue(digitHistory, digitCount);\r
- digitCount = 0;\r
-\r
- /* Switch over to IPv4 loop */\r
- ip4OctetsDone = 1;\r
- walking = 0;\r
- break;\r
-\r
- case _UT(']'):\r
- /* Too little quads? */\r
- if (!zipperEver && !((quadsDone == 7) && (digitCount > 0))) {\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- }\r
-\r
- if (digitCount > 0) {\r
- if (zipperEver) {\r
- uriWriteQuadToDoubleByte(digitHistory, digitCount, quadsAfterZipper + 2 * quadsAfterZipperCount);\r
- quadsAfterZipperCount++;\r
- } else {\r
- uriWriteQuadToDoubleByte(digitHistory, digitCount, state->uri->hostData.ip6->data + 2 * quadsDone);\r
- }\r
- /*\r
- quadsDone++;\r
- digitCount = 0;\r
- */\r
- }\r
-\r
- /* Copy missing quads to the end */\r
- memcpy(state->uri->hostData.ip6->data + 16 - 2 * quadsAfterZipperCount,\r
- quadsAfterZipper, 2 * quadsAfterZipperCount);\r
-\r
- state->uri->hostText.afterLast = first; /* HOST END */\r
- return first + 1; /* Fine */\r
-\r
- default:\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL;\r
- }\r
- first++;\r
-\r
- if (first >= afterLast) {\r
- URI_FUNC(StopSyntax)(state, first);\r
- return NULL; /* No ']' yet */\r
- }\r
- } while (walking);\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-/*\r
- * [mustBeSegmentNzNc]->[pctEncoded][mustBeSegmentNzNc]\r
- * [mustBeSegmentNzNc]->[subDelims][mustBeSegmentNzNc]\r
- * [mustBeSegmentNzNc]->[unreserved][mustBeSegmentNzNc]\r
- * [mustBeSegmentNzNc]->[uriTail] // can take <NULL>\r
- * [mustBeSegmentNzNc]-></>[segment][zeroMoreSlashSegs][uriTail]\r
- * [mustBeSegmentNzNc]-><@>[mustBeSegmentNzNc]\r
- */\r
-static const URI_CHAR * URI_FUNC(ParseMustBeSegmentNzNc)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) {\r
- if (first >= afterLast) {\r
- if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first)) { /* SEGMENT BOTH */\r
- URI_FUNC(StopMalloc)(state);\r
- return NULL;\r
- }\r
- state->uri->scheme.first = NULL; /* Not a scheme, reset */\r
- return afterLast;\r
- }\r
-\r
- switch (*first) {\r
- case _UT('%'):\r
- {\r
- const URI_CHAR * const afterPctEncoded\r
- = URI_FUNC(ParsePctEncoded)(state, first, afterLast);\r
- if (afterPctEncoded == NULL) {\r
- return NULL;\r
- }\r
- return URI_FUNC(ParseMustBeSegmentNzNc)(state, afterPctEncoded, afterLast);\r
- }\r
-\r
- case _UT('@'):\r
- case _UT('!'):\r
- case _UT('$'):\r
- case _UT('&'):\r
- case _UT('('):\r
- case _UT(')'):\r
- case _UT('*'):\r
- case _UT(','):\r
- case _UT(';'):\r
- case _UT('\''):\r
- case _UT('+'):\r
- case _UT('='):\r
- case _UT('-'):\r
- case _UT('.'):\r
- case _UT('_'):\r
- case _UT('~'):\r
- case URI_SET_DIGIT:\r
- case URI_SET_ALPHA:\r
- return URI_FUNC(ParseMustBeSegmentNzNc)(state, first + 1, afterLast);\r
-\r
- case _UT('/'):\r
- {\r
- const URI_CHAR * afterZeroMoreSlashSegs;\r
- const URI_CHAR * afterSegment;\r
- if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first)) { /* SEGMENT BOTH */\r
- URI_FUNC(StopMalloc)(state);\r
- return NULL;\r
- }\r
- state->uri->scheme.first = NULL; /* Not a scheme, reset */\r
- afterSegment = URI_FUNC(ParseSegment)(state, first + 1, afterLast);\r
- if (afterSegment == NULL) {\r
- return NULL;\r
- }\r
- if (!URI_FUNC(PushPathSegment)(state, first + 1, afterSegment)) { /* SEGMENT BOTH */\r
- URI_FUNC(StopMalloc)(state);\r
- return NULL;\r
- }\r
- afterZeroMoreSlashSegs\r
- = URI_FUNC(ParseZeroMoreSlashSegs)(state, afterSegment, afterLast);\r
- if (afterZeroMoreSlashSegs == NULL) {\r
- return NULL;\r
- }\r
- return URI_FUNC(ParseUriTail)(state, afterZeroMoreSlashSegs, afterLast);\r
- }\r
-\r
- default:\r
- if (!URI_FUNC(PushPathSegment)(state, state->uri->scheme.first, first)) { /* SEGMENT BOTH */\r
- URI_FUNC(StopMalloc)(state);\r
- return NULL;\r
- }\r
- state->uri->scheme.first = NULL; /* Not a scheme, reset */\r
- return URI_FUNC(ParseUriTail)(state, first, afterLast);\r
- }\r
-}\r
-\r
-\r
-\r
-/*\r
- * [ownHost]-><[>[ipLit2][authorityTwo]\r
- * [ownHost]->[ownHost2] // can take <NULL>\r
- */\r
-static URI_INLINE const URI_CHAR * URI_FUNC(ParseOwnHost)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) {\r
- if (first >= afterLast) {\r
- return afterLast;\r
- }\r
-\r
- switch (*first) {\r
- case _UT('['):\r
- {\r
- const URI_CHAR * const afterIpLit2\r
- = URI_FUNC(ParseIpLit2)(state, first + 1, afterLast);\r
- if (afterIpLit2 == NULL) {\r
- return NULL;\r
- }\r
- state->uri->hostText.first = first + 1; /* HOST BEGIN */\r
- return URI_FUNC(ParseAuthorityTwo)(state, afterIpLit2, afterLast);\r
- }\r
-\r
- default:\r
- return URI_FUNC(ParseOwnHost2)(state, first, afterLast);\r
- }\r
-}\r
-\r
-\r
-\r
-static URI_INLINE UriBool URI_FUNC(OnExitOwnHost2)(URI_TYPE(ParserState) * state, const URI_CHAR * first) {\r
- state->uri->hostText.afterLast = first; /* HOST END */\r
-\r
- /* Valid IPv4 or just a regname? */\r
- state->uri->hostData.ip4 = malloc(1 * sizeof(UriIp4)); /* Freed when stopping on parse error */\r
- if (state->uri->hostData.ip4 == NULL) {\r
- return URI_FALSE; /* Raises malloc error */\r
- }\r
- if (URI_FUNC(ParseIpFourAddress)(state->uri->hostData.ip4->data,\r
- state->uri->hostText.first, state->uri->hostText.afterLast)) {\r
- /* Not IPv4 */\r
- free(state->uri->hostData.ip4);\r
- state->uri->hostData.ip4 = NULL;\r
- }\r
- return URI_TRUE; /* Success */\r
-}\r
-\r
-\r
-\r
-/*\r
- * [ownHost2]->[authorityTwo] // can take <NULL>\r
- * [ownHost2]->[pctSubUnres][ownHost2]\r
- */\r
-static const URI_CHAR * URI_FUNC(ParseOwnHost2)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) {\r
- if (first >= afterLast) {\r
- if (!URI_FUNC(OnExitOwnHost2)(state, first)) {\r
- URI_FUNC(StopMalloc)(state);\r
- return NULL;\r
- }\r
- return afterLast;\r
- }\r
-\r
- switch (*first) {\r
- case _UT('!'):\r
- case _UT('$'):\r
- case _UT('%'):\r
- case _UT('&'):\r
- case _UT('('):\r
- case _UT(')'):\r
- case _UT('-'):\r
- case _UT('*'):\r
- case _UT(','):\r
- case _UT('.'):\r
- case _UT(';'):\r
- case _UT('\''):\r
- case _UT('_'):\r
- case _UT('~'):\r
- case _UT('+'):\r
- case _UT('='):\r
- case URI_SET_DIGIT:\r
- case URI_SET_ALPHA:\r
- {\r
- const URI_CHAR * const afterPctSubUnres\r
- = URI_FUNC(ParsePctSubUnres)(state, first, afterLast);\r
- if (afterPctSubUnres == NULL) {\r
- return NULL;\r
- }\r
- return URI_FUNC(ParseOwnHost2)(state, afterPctSubUnres, afterLast);\r
- }\r
-\r
- default:\r
- if (!URI_FUNC(OnExitOwnHost2)(state, first)) {\r
- URI_FUNC(StopMalloc)(state);\r
- return NULL;\r
- }\r
- return URI_FUNC(ParseAuthorityTwo)(state, first, afterLast);\r
- }\r
-}\r
-\r
-\r
-\r
-static URI_INLINE UriBool URI_FUNC(OnExitOwnHostUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first) {\r
- state->uri->hostText.first = state->uri->userInfo.first; /* Host instead of userInfo, update */\r
- state->uri->userInfo.first = NULL; /* Not a userInfo, reset */\r
- state->uri->hostText.afterLast = first; /* HOST END */\r
-\r
- /* Valid IPv4 or just a regname? */\r
- state->uri->hostData.ip4 = malloc(1 * sizeof(UriIp4)); /* Freed when stopping on parse error */\r
- if (state->uri->hostData.ip4 == NULL) {\r
- return URI_FALSE; /* Raises malloc error */\r
- }\r
- if (URI_FUNC(ParseIpFourAddress)(state->uri->hostData.ip4->data,\r
- state->uri->hostText.first, state->uri->hostText.afterLast)) {\r
- /* Not IPv4 */\r
- free(state->uri->hostData.ip4);\r
- state->uri->hostData.ip4 = NULL;\r
- }\r
- return URI_TRUE; /* Success */\r
-}\r
-\r
-\r
-\r
-/*\r
- * [ownHostUserInfo]->[ownHostUserInfoNz]\r
- * [ownHostUserInfo]-><NULL>\r
- */\r
-static URI_INLINE const URI_CHAR * URI_FUNC(ParseOwnHostUserInfo)(URI_TYPE(ParserState) * state, const URI_CHAR * first, const URI_CHAR * afterLast) {\r
- if (first >= afterLast) {\r
- if (!URI_FUNC(OnExitOwnHostUserInfo)(state, first)) {\r
- URI_FUNC(StopMalloc)(state);\r
- return NULL;\r
- }\r
- return afterLast;\r
- }\r
-\r
- switch (*first) {\r
- case _UT('!'):\r
- case _UT('$'):\r
- case _UT('%'):\r
- case _UT('&'):\r
- case _UT('('):\r
- case _UT(')'):\r
- case _UT('-'):\r
- case _UT('*'):\r
- case _UT(','):\r
- case _UT('.'):\r
- case _UT(':'):\r
- case _UT(';'):\r
- case _UT('@'):\r
- case _UT('\''):\r
- case _UT('_'):\r
- case _UT('~'):\r
- case _UT('+'):\r
- case _UT('='):\r
- case URI_SET_DIGIT:\r
- case URI_SET_ALPHA:\r
- &n