Skip to content

Commit

Permalink
Merge pull request #364 from susnux/fix/xml-entities-file-names
Browse files Browse the repository at this point in the history
fix: Do not double decode XML entities in filenames
  • Loading branch information
perry-mitchell committed Feb 5, 2024
2 parents e41a805 + 3f27a60 commit bf3c79b
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 3 deletions.
2 changes: 1 addition & 1 deletion source/operations/directoryContents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ function getDirectoryFiles(

// Map all items to a consistent output structure (results)
const nodes = responseItems.map(item => {
// HREF is the file path (in full)
// HREF is the file path (in full) - The href is already XML entities decoded (e.g. foo&bar is reverted to foo&bar)
const href = normaliseHREF(item.href);
// Each item should contain a stat object
const {
Expand Down
3 changes: 1 addition & 2 deletions source/tools/dav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export function parseXML(xml: string): Promise<DAVResult> {

export function prepareFileFromProps(
props: DAVResultResponseProps,
rawFilename: string,
filename: string,
isDetailed: boolean = false
): FileStat {
// Last modified time, raw size, item type and mime
Expand All @@ -129,7 +129,6 @@ export function prepareFileFromProps(
typeof resourceType.collection !== "undefined"
? "directory"
: "file";
const filename = decodeHTMLEntities(rawFilename);
const stat: FileStat = {
filename,
basename: path.basename(filename),
Expand Down
31 changes: 31 additions & 0 deletions test/node/operations/getDirectoryContents.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import {
createWebDAVClient,
createWebDAVServer,
restoreRequests,
returnFakeResponse,
useCustomXmlResponse,
useRequestSpy
} from "../../helpers.node.js";
import { readFileSync } from "fs";

describe("getDirectoryContents", function () {
beforeEach(async function () {
Expand Down Expand Up @@ -105,6 +107,35 @@ describe("getDirectoryContents", function () {
});
});

it("returns correct file results for files with HTML entities in their names", function () {
returnFakeResponse(
readFileSync(
new URL("../../responses/propfind-href-html-entities.xml", import.meta.url)
).toString()
);

return this.client.getDirectoryContents("/files").then(function (contents) {
const file = contents.find(function (item) {
return item.basename === "&amp;.md";
});
expect(file).not.to.equal(undefined, "Expected file does not exist");
expect(file.filename).to.match(/\/files\/&amp;\.md$/);
});
});

it("returns correct file results for files with query in href", function () {
returnFakeResponse(
readFileSync(
new URL("../../responses/propfind-href-with-query.xml", import.meta.url)
).toString()
);

return this.client.getDirectoryContents("/files").then(function (contents) {
expect(contents).to.have.length(1);
expect(contents[0].filename).to.match(/\/files\/some file\?foo=1&bar=2$/);
});
});

it("returns the contents of a directory with repetitive naming", function () {
return this.client.getDirectoryContents("/webdav/server").then(function (contents) {
expect(contents).to.be.an("array");
Expand Down
22 changes: 22 additions & 0 deletions test/responses/propfind-href-html-entities.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0"?>
<d:multistatus xmlns:d="DAV:">
<d:response>
<d:href>http://example.com/files/%26amp%3b.md</d:href>
<d:propstat>
<d:prop>
<d:getcontentlength>0</d:getcontentlength>
<d:getcontenttype>text/markdown</d:getcontenttype>
<d:getetag>&quot;e9fb0c7d776a0607e2277aad4cc74a08&quot;</d:getetag>
<d:getlastmodified>Sun, 04 Feb 2024 14:09:50 GMT</d:getlastmodified>
<d:resourcetype/>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
<d:propstat>
<d:prop>
<d:quota-available-bytes/>
</d:prop>
<d:status>HTTP/1.1 404 Not Found</d:status>
</d:propstat>
</d:response>
</d:multistatus>
16 changes: 16 additions & 0 deletions test/responses/propfind-href-with-query.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<d:multistatus xmlns:d="DAV:">
<d:response>
<d:href>/files/some%20file?foo=1&amp;bar=2</d:href>
<d:propstat>
<d:prop>
<d:getcontentlength>0</d:getcontentlength>
<d:getcontenttype>text/markdown</d:getcontenttype>
<d:getetag>&quot;e9fb0c7d776a0607e2277aad4cc74a08&quot;</d:getetag>
<d:getlastmodified>Sun, 04 Feb 2024 14:09:50 GMT</d:getlastmodified>
<d:resourcetype/>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
</d:multistatus>

0 comments on commit bf3c79b

Please sign in to comment.