summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Pipping <sebastian@pipping.org>2021-02-25 18:51:43 +0100
committerSebastian Pipping <sebastian@pipping.org>2021-02-26 22:26:51 +0100
commitcaad64784704b22b3556d8b33feeaf635173b4fe (patch)
tree7d72c536f8e7f0974a3ddff35019765c2e87d22a
parenta40b585f70ce22d9ad78a08da75df700cd1d148c (diff)
downloaduriparser-caad64784704b22b3556d8b33feeaf635173b4fe.tar.gz
UriCommon.c: Add more in-code comments to RemoveDotSegmentsEx
-rw-r--r--src/UriCommon.c48
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 {