Skip to content

Commit 1a7a735

Browse files
authored
Properly URI decode wildcard paths from URL endpoints (#1484)
* fix: properly decode wildcard paths from URL endpoints * apply fix to more generic method * add unit test for files containing whitespace * fix: flaky cache service test by clearing cached before each test
1 parent cd2486f commit 1a7a735

File tree

4 files changed

+38
-2
lines changed

4 files changed

+38
-2
lines changed

server/src/main/java/org/eclipse/openvsx/util/UrlUtil.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,12 @@ public static String extractWildcardPath(HttpServletRequest request) {
238238
*/
239239
public static String extractWildcardPath(HttpServletRequest request, String pattern) {
240240
String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
241+
242+
if (path != null) {
243+
// need to decode the path as it is part of the URL and thus URI encoded.
244+
path = UriUtils.decode(path, StandardCharsets.UTF_8);
245+
}
246+
241247
return path != null && pattern != null
242248
? new AntPathMatcher().extractPathWithinPattern(pattern, path)
243249
: "";

server/src/test/java/org/eclipse/openvsx/adapter/VSCodeAPITest.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,27 @@ void testBrowseIcon() throws Exception {
647647
.andDo(result -> Files.delete(path));
648648
}
649649

650+
@Test
651+
void testBrowseFilenameWithWhitespace() throws Exception {
652+
var namespaceName = "editorconfig";
653+
var extensionName = "editorconfig";
654+
var version = "0.16.6-1";
655+
var path = mockExtensionBrowse(namespaceName, extensionName, version);
656+
var bytes = new byte[0];
657+
try(var zip = new ZipFile(path.toFile())) {
658+
var entry = zip.getEntry("extension/EditorConfig icon.png");
659+
try(var in = zip.getInputStream(entry)) {
660+
bytes = in.readAllBytes();
661+
}
662+
}
663+
mockMvc.perform(get("/vscode/unpkg/{namespaceName}/{extensionName}/{version}/{path}", namespaceName, extensionName, version, "extension/EditorConfig icon.png"))
664+
.andExpect(request().asyncStarted())
665+
.andDo(MvcResult::getAsyncResult)
666+
.andExpect(status().isOk())
667+
.andExpect(content().bytes(bytes))
668+
.andDo(result -> Files.delete(path));
669+
}
670+
650671
@Test
651672
void testDownload() throws Exception {
652673
mockExtensionVersion();
@@ -977,13 +998,14 @@ private Path mockExtensionBrowse(String namespaceName, String extensionName, Str
977998
var resource = new FileResource();
978999
resource.setId(3L);
9791000
resource.setExtension(extVersion);
980-
resource.setName("EditorConfig.EditorConfig-0.16.6.vsix");
1001+
var vsixFileName = namespaceName + "." + extensionName + "-" + version + ".vsix";
1002+
resource.setName(vsixFileName);
9811003
resource.setType(DOWNLOAD);
9821004
resource.setStorageType(STORAGE_LOCAL);
9831005

9841006
var path = Path.of("/tmp", namespaceName, extensionName, (!TargetPlatform.isUniversal(targetPlatform) ? targetPlatform : ""), version, resource.getName());
9851007
path.toFile().mkdirs();
986-
try (var in = getClass().getResourceAsStream("../EditorConfig.EditorConfig-0.16.6.vsix")) {
1008+
try (var in = getClass().getResourceAsStream("../" + vsixFileName)) {
9871009
Files.copy(in, path, StandardCopyOption.REPLACE_EXISTING);
9881010
}
9891011

server/src/test/java/org/eclipse/openvsx/cache/CacheServiceTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.eclipse.openvsx.security.IdPrincipal;
2323
import org.eclipse.openvsx.util.TempFile;
2424
import org.eclipse.openvsx.util.TimeUtil;
25+
import org.junit.jupiter.api.BeforeEach;
2526
import org.junit.jupiter.api.Test;
2627
import org.springframework.beans.factory.annotation.Autowired;
2728
import org.springframework.boot.test.context.SpringBootTest;
@@ -70,6 +71,13 @@ class CacheServiceTest {
7071
@Autowired
7172
RepositoryService repositories;
7273

74+
@BeforeEach
75+
public void clearCaches() {
76+
for (var name : cache.getCacheNames()) {
77+
cache.getCache(name).clear();
78+
}
79+
}
80+
7381
@Test
7482
@Transactional
7583
void testGetExtension() throws IOException {
Binary file not shown.

0 commit comments

Comments
 (0)