|
@@ -8174,14 +8174,11 @@ remove_dot_segments(char *inout)
|
|
/* Windows backend protection
|
|
/* Windows backend protection
|
|
* (https://tools.ietf.org/html/rfc3986#section-7.3): Replace backslash
|
|
* (https://tools.ietf.org/html/rfc3986#section-7.3): Replace backslash
|
|
* in URI by slash */
|
|
* in URI by slash */
|
|
- char *in_copy = inout ? mg_strdup(inout) : NULL;
|
|
|
|
- char *out_begin = inout;
|
|
|
|
char *out_end = inout;
|
|
char *out_end = inout;
|
|
- char *in = in_copy;
|
|
|
|
- int replaced;
|
|
|
|
|
|
+ char *in = inout;
|
|
|
|
|
|
if (!in) {
|
|
if (!in) {
|
|
- /* Param error or OOM. */
|
|
|
|
|
|
+ /* Param error. */
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -8198,11 +8195,13 @@ remove_dot_segments(char *inout)
|
|
* The input buffer is initialized.
|
|
* The input buffer is initialized.
|
|
* The output buffer is initialized to the empty string.
|
|
* The output buffer is initialized to the empty string.
|
|
*/
|
|
*/
|
|
- in = in_copy;
|
|
|
|
|
|
+ in = inout;
|
|
|
|
|
|
/* Step 2:
|
|
/* Step 2:
|
|
* While the input buffer is not empty, loop as follows:
|
|
* While the input buffer is not empty, loop as follows:
|
|
*/
|
|
*/
|
|
|
|
+ /* Less than out_end of the inout buffer is used as output, so keep
|
|
|
|
+ * condition: out_end <= in */
|
|
while (*in) {
|
|
while (*in) {
|
|
/* Step 2a:
|
|
/* Step 2a:
|
|
* If the input buffer begins with a prefix of "../" or "./",
|
|
* If the input buffer begins with a prefix of "../" or "./",
|
|
@@ -8234,21 +8233,19 @@ remove_dot_segments(char *inout)
|
|
*/
|
|
*/
|
|
else if (!strncmp(in, "/../", 4)) {
|
|
else if (!strncmp(in, "/../", 4)) {
|
|
in += 3;
|
|
in += 3;
|
|
- if (out_begin != out_end) {
|
|
|
|
|
|
+ if (inout != out_end) {
|
|
/* remove last segment */
|
|
/* remove last segment */
|
|
do {
|
|
do {
|
|
out_end--;
|
|
out_end--;
|
|
- } while ((out_begin != out_end) && (*out_end != '/'));
|
|
|
|
- *out_end = 0;
|
|
|
|
|
|
+ } while ((inout != out_end) && (*out_end != '/'));
|
|
}
|
|
}
|
|
} else if (!strcmp(in, "/..")) {
|
|
} else if (!strcmp(in, "/..")) {
|
|
in[1] = 0;
|
|
in[1] = 0;
|
|
- if (out_begin != out_end) {
|
|
|
|
|
|
+ if (inout != out_end) {
|
|
/* remove last segment */
|
|
/* remove last segment */
|
|
do {
|
|
do {
|
|
out_end--;
|
|
out_end--;
|
|
- } while ((out_begin != out_end) && (*out_end != '/'));
|
|
|
|
- *out_end = 0;
|
|
|
|
|
|
+ } while ((inout != out_end) && (*out_end != '/'));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/* otherwise */
|
|
/* otherwise */
|
|
@@ -8287,42 +8284,40 @@ remove_dot_segments(char *inout)
|
|
* the end. Also replace all "//" by "/". Repeat until there is no "./"
|
|
* the end. Also replace all "//" by "/". Repeat until there is no "./"
|
|
* or "//" anymore.
|
|
* or "//" anymore.
|
|
*/
|
|
*/
|
|
- do {
|
|
|
|
- replaced = 0;
|
|
|
|
-
|
|
|
|
- /* replace ./ by / */
|
|
|
|
- out_end = out_begin;
|
|
|
|
- while (*out_end) {
|
|
|
|
- if ((*out_end == '.')
|
|
|
|
- && ((out_end[1] == '/') || (out_end[1] == 0))) {
|
|
|
|
- char *r = out_end;
|
|
|
|
- do {
|
|
|
|
- r[0] = r[1];
|
|
|
|
- r++;
|
|
|
|
- replaced = 1;
|
|
|
|
- } while (r[0] != 0);
|
|
|
|
- }
|
|
|
|
- out_end++;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* replace ./ by / */
|
|
|
|
- out_end = out_begin;
|
|
|
|
- while (*out_end) {
|
|
|
|
- if ((out_end[0] == '/') && (out_end[1] == '/')) {
|
|
|
|
- char *c = out_end;
|
|
|
|
- while (*c) {
|
|
|
|
- c[0] = c[1];
|
|
|
|
- c++;
|
|
|
|
|
|
+ out_end = in = inout;
|
|
|
|
+ while (*in) {
|
|
|
|
+ if (*in == '.') {
|
|
|
|
+ /* remove . at the end or preceding of / */
|
|
|
|
+ char *in_ahead = in;
|
|
|
|
+ do {
|
|
|
|
+ in_ahead++;
|
|
|
|
+ } while (*in_ahead == '.');
|
|
|
|
+ if (*in_ahead == '/') {
|
|
|
|
+ in = in_ahead;
|
|
|
|
+ if ((out_end != inout) && (out_end[-1] == '/')) {
|
|
|
|
+ /* remove generated // */
|
|
|
|
+ out_end--;
|
|
}
|
|
}
|
|
- replaced = 1;
|
|
|
|
|
|
+ } else if (*in_ahead == 0) {
|
|
|
|
+ in = in_ahead;
|
|
|
|
+ } else {
|
|
|
|
+ do {
|
|
|
|
+ *out_end++ = '.';
|
|
|
|
+ in++;
|
|
|
|
+ } while (in != in_ahead);
|
|
}
|
|
}
|
|
- out_end++;
|
|
|
|
|
|
+ } else if (*in == '/') {
|
|
|
|
+ /* replace // by / */
|
|
|
|
+ *out_end++ = '/';
|
|
|
|
+ do {
|
|
|
|
+ in++;
|
|
|
|
+ } while (*in == '/');
|
|
|
|
+ } else {
|
|
|
|
+ *out_end++ = *in;
|
|
|
|
+ in++;
|
|
}
|
|
}
|
|
-
|
|
|
|
- } while (replaced);
|
|
|
|
-
|
|
|
|
- /* Free temporary copies */
|
|
|
|
- mg_free(in_copy);
|
|
|
|
|
|
+ }
|
|
|
|
+ *out_end = 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|