diff options
| author | Jörg Frings-Fürst <debian@jff-webhsoting.net> | 2021-04-26 20:34:11 +0200 | 
|---|---|---|
| committer | Jörg Frings-Fürst <debian@jff-webhsoting.net> | 2021-04-26 20:34:11 +0200 | 
| commit | 7d4216c07bd36b69ae7f5eabb7b4d6b59166a508 (patch) | |
| tree | f161e88bc941e1c861b1dd1a34a332f8cdc53f7a /src/UriCommon.c | |
| parent | cf9293531802f491b4b145d98a4900e72a7d105b (diff) | |
| parent | cb39f81ea1957f5fdd9b5b67d7d326091efd3d02 (diff) | |
Update upstream source from tag 'upstream/0.9.5'
Update to upstream version '0.9.5'
with Debian dir 7a51c03cb2a73fa740ed9845ba2837c909f3e3ba
Diffstat (limited to 'src/UriCommon.c')
| -rw-r--r-- | src/UriCommon.c | 96 | 
1 files changed, 70 insertions, 26 deletions
| diff --git a/src/UriCommon.c b/src/UriCommon.c index 60bd319..7ba92f2 100644 --- a/src/UriCommon.c +++ b/src/UriCommon.c @@ -119,17 +119,6 @@ int URI_FUNC(CompareRange)( -/* Properly removes "." and ".." path segments */ -UriBool URI_FUNC(RemoveDotSegments)(URI_TYPE(Uri) * uri, -		UriBool relative, UriMemoryManager * memory) { -	if (uri == NULL) { -		return URI_TRUE; -	} -	return URI_FUNC(RemoveDotSegmentsEx)(uri, relative, uri->owner, memory); -} - - -  UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,  		UriBool relative, UriBool pathOwned, UriMemoryManager * memory) {  	URI_TYPE(PathSegment) * walker; @@ -149,7 +138,13 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,  				URI_TYPE(PathSegment) * const prev = walker->reserved;  				URI_TYPE(PathSegment) * const nextBackup = walker->next; -				/* Is this dot segment essential? */ +				/* +				 * Is this dot segment essential, +				 * i.e. is there a chance of changing semantics by dropping this dot segment? +				 * +				 * For example, changing "./http://foo" into "http://foo" would change semantics +				 * and hence the dot segment is essential to that case and cannot be removed. +				 */  				removeSegment = URI_TRUE;  				if (relative && (walker == uri->pathHead) && (walker->next != NULL)) {  					const URI_CHAR * ch = walker->next->text.first; @@ -162,16 +157,23 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,  				}  				if (removeSegment) { +					/* .. then let's go remove that segment. */  					/* Last segment? */  					if (walker->next != NULL) { -						/* Not last segment */ +						/* Not last segment, i.e. first or middle segment +						 * OLD: (prev|NULL) <- walker <- next +						 * NEW: (prev|NULL) <----------- next */  						walker->next->reserved = prev;  						if (prev == NULL) { -							/* First but not last segment */ +							/* First but not last segment +							 * OLD: head -> walker -> next +							 * NEW: head -----------> next */  							uri->pathHead = walker->next;  						} else { -							/* Middle segment */ +							/* Middle segment +							 * OLD: prev -> walker -> next +							 * NEW: prev -----------> next */  							prev->next = walker->next;  						} @@ -220,11 +222,16 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,  				removeSegment = URI_TRUE;  				if (relative) {  					if (prev == NULL) { +						/* We cannot remove traversal beyond because the +						 * URI is relative and may be resolved later. +						 * So we can simplify "a/../b/d" to "b/d" but +						 * we cannot simplify "../b/d" (outside of reference resolution). */  						removeSegment = URI_FALSE;  					} else if ((prev != NULL)  							&& ((prev->text.afterLast - prev->text.first) == 2)  							&& ((prev->text.first)[0] == _UT('.'))  							&& ((prev->text.first)[1] == _UT('.'))) { +						/* We need to protect against mis-simplifying "a/../../b" to "a/b". */  						removeSegment = URI_FALSE;  					}  				} @@ -234,9 +241,14 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,  						/* Not first segment */  						prevPrev = prev->reserved;  						if (prevPrev != NULL) { -							/* Not even prev is the first one */ +							/* Not even prev is the first one +							 * OLD: prevPrev -> prev -> walker -> (next|NULL) +							 * NEW: prevPrev -------------------> (next|NULL) */  							prevPrev->next = walker->next;  							if (walker->next != NULL) { +								/* Update parent relationship as well +								 * OLD: prevPrev <- prev <- walker <- next +								 * NEW: prevPrev <------------------- next */  								walker->next->reserved = prevPrev;  							} else {  								/* Last segment -> insert "" segment to represent trailing slash, update tail */ @@ -302,29 +314,58 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,  						}  					} else {  						URI_TYPE(PathSegment) * const anotherNextBackup = walker->next; -						/* First segment -> update head pointer */ -						uri->pathHead = walker->next; +						int freeWalker = URI_TRUE; + +						/* First segment */  						if (walker->next != NULL) { +							/* First segment of multiple -> update head +							 * OLD: head -> walker -> next +							 * NEW: head -----------> next */ +							uri->pathHead = walker->next; + +							/* Update parent link as well +							 * OLD: head <- walker <- next +							 * NEW: head <----------- next */  							walker->next->reserved = NULL;  						} else { -							/* Last segment -> update tail */ -							uri->pathTail = NULL; +							if (uri->absolutePath) { +								/* First and only segment -> update head +								 * OLD: head -> walker -> NULL +								 * NEW: head -----------> NULL */ +								uri->pathHead = NULL; + +								/* Last segment -> update tail +								 * OLD: tail -> walker +								 * NEW: tail -> NULL */ +								uri->pathTail = NULL; +							} else { +								/* Re-use segment for "" path segment to represent trailing slash, +								 * then update head and tail */ +								if (pathOwned && (walker->text.first != walker->text.afterLast)) { +									memory->free(memory, (URI_CHAR *)walker->text.first); +								} +								walker->text.first = URI_FUNC(SafeToPointTo); +								walker->text.afterLast = URI_FUNC(SafeToPointTo); +								freeWalker = URI_FALSE; +							}  						} -						if (pathOwned && (walker->text.first != walker->text.afterLast)) { -							memory->free(memory, (URI_CHAR *)walker->text.first); +						if (freeWalker) { +							if (pathOwned && (walker->text.first != walker->text.afterLast)) { +								memory->free(memory, (URI_CHAR *)walker->text.first); +							} +							memory->free(memory, walker);  						} -						memory->free(memory, walker);  						walker = anotherNextBackup;  					}  				}  			}  			break; - -		} +		} /* end of switch */  		if (!removeSegment) { +			/* .. then let's move to the next element, and start again. */  			if (walker->next != NULL) {  				walker->next->reserved = walker;  			} else { @@ -344,7 +385,10 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,  UriBool URI_FUNC(RemoveDotSegmentsAbsolute)(URI_TYPE(Uri) * uri,  		UriMemoryManager * memory) {  	const UriBool ABSOLUTE = URI_FALSE; -	return URI_FUNC(RemoveDotSegments)(uri, ABSOLUTE, memory); +	if (uri == NULL) { +		return URI_TRUE; +	} +	return URI_FUNC(RemoveDotSegmentsEx)(uri, ABSOLUTE, uri->owner, memory);  } | 
