diff options
author | Sebastian Pipping <sebastian@pipping.org> | 2021-02-25 18:51:43 +0100 |
---|---|---|
committer | Sebastian Pipping <sebastian@pipping.org> | 2021-02-26 22:26:51 +0100 |
commit | caad64784704b22b3556d8b33feeaf635173b4fe (patch) | |
tree | 7d72c536f8e7f0974a3ddff35019765c2e87d22a | |
parent | a40b585f70ce22d9ad78a08da75df700cd1d148c (diff) | |
download | uriparser-caad64784704b22b3556d8b33feeaf635173b4fe.tar.gz |
UriCommon.c: Add more in-code comments to RemoveDotSegmentsEx
-rw-r--r-- | src/UriCommon.c | 48 |
1 files changed, 39 insertions, 9 deletions
diff --git a/src/UriCommon.c b/src/UriCommon.c index 6603110..1afa679 100644 --- a/src/UriCommon.c +++ b/src/UriCommon.c @@ -138,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; @@ -151,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; } @@ -209,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; } } @@ -223,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 */ @@ -291,12 +314,19 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri, } } else { URI_TYPE(PathSegment) * const anotherNextBackup = walker->next; - /* First segment -> update head pointer */ + /* First segment -> update head pointer + * OLD: head -> walker -> (next|NULL) + * NEW: head -----------> (next|NULL) */ uri->pathHead = walker->next; if (walker->next != NULL) { + /* Update parent link as well + * OLD: head <- walker <- next + * NEW: head <----------- next */ walker->next->reserved = NULL; } else { - /* Last segment -> update tail */ + /* Last segment -> update tail + * OLD: tail -> walker + * NEW: tail -> NULL */ uri->pathTail = NULL; } @@ -310,10 +340,10 @@ UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri, } } 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 { |