diff --git a/gradle/changelog/percentage_in_path.yaml b/gradle/changelog/percentage_in_path.yaml new file mode 100644 index 0000000000..83395c767f --- /dev/null +++ b/gradle/changelog/percentage_in_path.yaml @@ -0,0 +1,2 @@ +- type: Fixed + description: Bugs in svn and source tree for folders with a % in the name ([#1817](https://github.com/scm-manager/scm-manager/issues/1817) and [#1818](https://github.com/scm-manager/scm-manager/pull/1818)) diff --git a/scm-plugins/scm-svn-plugin/build.gradle b/scm-plugins/scm-svn-plugin/build.gradle index ec018050c0..0796670577 100644 --- a/scm-plugins/scm-svn-plugin/build.gradle +++ b/scm-plugins/scm-svn-plugin/build.gradle @@ -27,7 +27,7 @@ plugins { id 'org.scm-manager.smp' version '0.8.5' } -def svnkitVersion = '1.10.1-scm2' +def svnkitVersion = '1.10.3-scm1' dependencies { implementation("sonia.svnkit:svnkit:${svnkitVersion}") { diff --git a/scm-ui/ui-components/src/Breadcrumb.tsx b/scm-ui/ui-components/src/Breadcrumb.tsx index 76970bc6de..7a43ef5bbc 100644 --- a/scm-ui/ui-components/src/Breadcrumb.tsx +++ b/scm-ui/ui-components/src/Breadcrumb.tsx @@ -128,7 +128,7 @@ const Breadcrumb: FC = ({ if (path) { const paths = path.split("/"); return paths.map((pathFragment, index) => { - let currPath = paths.slice(0, index + 1).join("/"); + let currPath = paths.slice(0, index + 1).map(encodeURIComponent).join("/"); if (!currPath.endsWith("/")) { currPath = currPath + "/"; } diff --git a/scm-ui/ui-webapp/src/repos/sources/components/content/FileLink.test.ts b/scm-ui/ui-webapp/src/repos/sources/components/content/FileLink.test.ts index 77dbff0867..34a30aa8f3 100644 --- a/scm-ui/ui-webapp/src/repos/sources/components/content/FileLink.test.ts +++ b/scm-ui/ui-webapp/src/repos/sources/components/content/FileLink.test.ts @@ -22,7 +22,8 @@ * SOFTWARE. */ -import { createRelativeLink, createFolderLink } from "./FileLink"; +import { createRelativeLink, createFolderLink, encodePart } from "./FileLink"; +import { createLocation } from "history"; import { File } from "@scm-manager/ui-types"; describe("create relative link tests", () => { @@ -47,8 +48,8 @@ describe("create folder link tests", () => { revision: "1a", _links: {}, _embedded: { - children: [] - } + children: [], + }, }; } @@ -61,4 +62,20 @@ describe("create folder link tests", () => { it("should return base url if the directory path is empty", () => { expect(createFolderLink("src", dir(""))).toBe("src/"); }); + + it("should double encode folder names with percent", () => { + expect(createFolderLink("src", dir("a%20b"))).toBe("src/a%252520b/"); + }); +}); + +describe("link should keep encoded percentages", () => { + it("history should create a location with encoded pathname", () => { + // For version 4.x of history we have to double encode uri components with a '%', + // because of the following issue https://github.com/remix-run/history/issues/505 + // The issue is fixed with 5.x, but react-router-dom seams not to work with 5.x. + // So we have to stick with 4.x and the double encoding, until react-router-dom uses version 5.x. + // This test is mainly to remind us to remove the double encoding after update to 5.x. + const location = createLocation(encodePart("a%20b")); + expect(location.pathname).toBe("a%2520b"); + }); }); diff --git a/scm-ui/ui-webapp/src/repos/sources/components/content/FileLink.tsx b/scm-ui/ui-webapp/src/repos/sources/components/content/FileLink.tsx index 6ac71a3f9d..36d8705f99 100644 --- a/scm-ui/ui-webapp/src/repos/sources/components/content/FileLink.tsx +++ b/scm-ui/ui-webapp/src/repos/sources/components/content/FileLink.tsx @@ -46,6 +46,14 @@ const isLocalRepository = (repositoryUrl: string) => { return host === window.location.hostname; }; +export const encodePart = (part: string) => { + const encoded = encodeURIComponent(part); + if (part.includes("%")) { + return encodeURIComponent(encoded); + } + return encoded; +}; + export const createRelativeLink = (repositoryUrl: string) => { const paths = repositoryUrl.split("/"); return "/" + paths.slice(3).join("/"); @@ -54,7 +62,7 @@ export const createRelativeLink = (repositoryUrl: string) => { export const createFolderLink = (base: string, file: File) => { let link = base; if (file.path) { - let path = file.path.split("/").map(encodeURIComponent).join("/"); + let path = file.path.split("/").map(encodePart).join("/"); if (path.startsWith("/")) { path = path.substring(1); }