Skip to content

Commit 5b67f5d

Browse files
committed
Fix a bug in the removeDotSegments implementation.
Motivation: RFC3986#removeDotSegments does not properly handle the C. rule of section 5.2.4 of RFC3986. When the output buffer does not contain a / it should discard the entire content of the buffer. Changes: When handling rule C in RFC3986#removeDotSegments, discard the output buffer when no / is present.
1 parent f6f1e3f commit 5b67f5d

2 files changed

Lines changed: 71 additions & 6 deletions

File tree

vertx-core/src/main/java/io/vertx/core/internal/net/RFC3986.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,16 +157,12 @@ public static String removeDotSegments(CharSequence path) {
157157
// preserve last slash
158158
i += 3;
159159
int pos = obuf.lastIndexOf("/");
160-
if (pos != -1) {
161-
obuf.delete(pos, obuf.length());
162-
}
160+
obuf.setLength(pos == -1 ? 0 : pos);
163161
} else if (matches(path, i, "/..", true)) {
164162
path = "/";
165163
i = 0;
166164
int pos = obuf.lastIndexOf("/");
167-
if (pos != -1) {
168-
obuf.delete(pos, obuf.length());
169-
}
165+
obuf.setLength(pos == -1 ? 0 : pos);
170166
} else if (matches(path, i, ".", true) || matches(path, i, "..", true)) {
171167
break;
172168
} else {
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright (c) 2011-2026 Contributors to the Eclipse Foundation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7+
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
8+
*
9+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10+
*/
11+
package io.vertx.tests.net;
12+
13+
import io.vertx.core.internal.net.RFC3986;
14+
import org.junit.ComparisonFailure;
15+
import org.junit.Test;
16+
17+
import static org.junit.Assert.assertEquals;
18+
19+
public class RFC3986Test {
20+
21+
@Test
22+
public void testRemoveDotSegmentsRuleA() {
23+
assertDotSegments("", "../");
24+
assertDotSegments("", "./");
25+
26+
assertDotSegments("foo", "../foo");
27+
assertDotSegments("foo", "./foo");
28+
}
29+
30+
@Test
31+
public void testRemoveDotSegmentsRuleB() {
32+
assertDotSegments("/", "/./");
33+
assertDotSegments("/", "/.");
34+
35+
assertDotSegments("/foo", "/./foo");
36+
}
37+
38+
@Test
39+
public void testRemoveDotSegmentsRuleC() {
40+
assertDotSegments("/", "/../");
41+
assertDotSegments("/foo", "/../foo");
42+
assertDotSegments("/", "/..");
43+
assertDotSegments("/", "/foo/../");
44+
assertDotSegments("/", "/foo/..");
45+
assertDotSegments("/", "foo/../");
46+
assertDotSegments("/", "foo/..");
47+
assertDotSegments("/foo/", "/foo/bar/../");
48+
assertDotSegments("/foo/", "/foo/bar/..");
49+
assertDotSegments("foo/", "foo/bar/../");
50+
assertDotSegments("foo/", "foo/bar/..");
51+
}
52+
53+
@Test
54+
public void testRemoveDotSegmentsRuleD() {
55+
assertDotSegments("", ".");
56+
assertDotSegments("", "..");
57+
}
58+
59+
@Test
60+
public void testRemoveDotSegmentsRuleE() {
61+
assertDotSegments("/foo", "/foo");
62+
assertDotSegments("foo", "foo");
63+
}
64+
65+
private static void assertDotSegments(String expected, String test) {
66+
String actual = RFC3986.removeDotSegments(test);
67+
assertEquals(expected, actual);
68+
}
69+
}

0 commit comments

Comments
 (0)