diff --git a/src/__tests__/__snapshots__/atom1.spec.ts.snap b/src/__tests__/__snapshots__/atom1.spec.ts.snap index dc41f7b..0700209 100644 --- a/src/__tests__/__snapshots__/atom1.spec.ts.snap +++ b/src/__tests__/__snapshots__/atom1.spec.ts.snap @@ -83,3 +83,74 @@ exports[`atom 1.0 should generate a valid feed with stylesheet 1`] = ` All rights reserved 2013, John Doe " `; + +exports[`atom 1.0 should sanitize enclosure url 1`] = ` +" + + http://example.com/?link=sanitized&value=4 + Feed Title + 2013-07-13T23:00:00.000Z + https://github.com/jpmonette/feed + + John Doe + johndoe@example.com + https://example.com/johndoe?link=sanitized&value=2 + + + + + This is my personnal feed! + http://example.com/image.png?link=sanitized&value=6 + http://example.com/image.ico?link=sanitized&value=7 + All rights reserved 2013, John Doe + + + Johan Cruyff + johancruyff@example.com + https://example.com/johancruyff + + + <![CDATA[Hello World]]> + https://example.com/hello-world?id=this&that=true + + + + 2013-07-13T23:00:00.000Z + + + + Jane Doe + janedoe@example.com + https://example.com/janedoe?link=sanitized&value=2 + + + Joe Smith + joesmith@example.com + https://example.com/joesmith + + + Joe Smith, Name Only + + + + + Shawn Kemp + shawnkemp@example.com + https://example.com/shawnkemp + + + Reggie Miller + reggiemiller@example.com + https://example.com/reggiemiller + + 2013-07-10T23:00:00.000Z + + + <![CDATA[Hello World]]> + http://example.org/sanitize + + + 2013-07-13T23:00:00.000Z + +" +`; diff --git a/src/__tests__/__snapshots__/rss2.spec.ts.snap b/src/__tests__/__snapshots__/rss2.spec.ts.snap index a995956..54fca64 100644 --- a/src/__tests__/__snapshots__/rss2.spec.ts.snap +++ b/src/__tests__/__snapshots__/rss2.spec.ts.snap @@ -863,3 +863,145 @@ exports[`rss 2.0 should generate a valid podcast feed with audio 1`] = ` " `; + +exports[`rss 2.0 should sanitize enclosure url 1`] = ` +" + + + Feed Title + http://example.com/?link=sanitized&value=3 + This is my personnal feed! + Sat, 13 Jul 2013 23:00:00 GMT + https://validator.w3.org/feed/docs/rss2.html + https://github.com/jpmonette/feed + en + 60 + + Feed Title + http://example.com/image.png?link=sanitized&value=6 + http://example.com/?link=sanitized&value=3 + + All rights reserved 2013, John Doe + Technology + + + + <![CDATA[Hello World]]> + https://example.com/hello-world?link=sanitized&value=2 + https://example.com/hello-world?id=this&that=true + Wed, 10 Jul 2013 23:00:00 GMT + + + janedoe@example.com (Jane Doe) + joesmith@example.com (Joe Smith) + Joe Smith, Name Only + Grateful Dead + MSFT + + <_item_extension_1> + just an item extension example + example + + <_item_extension_2> + just a second item extension example + example + + + + <![CDATA[Hello World]]> + https://example.com/hello-world2 + 419c523a-28f4-489c-877e-9604be64c001 + Wed, 10 Jul 2013 23:00:00 GMT + + + janedoe@example.com (Jane Doe) + joesmith@example.com (Joe Smith) + Grateful Dead + MSFT + + <_item_extension_1> + just an item extension example + example + + <_item_extension_2> + just a second item extension example + example + + + + <![CDATA[Hello World]]> + https://example.com/hello-world2 + 419c523a-28f4-489c-877e-9604be64c001 + Wed, 10 Jul 2013 23:00:00 GMT + + + janedoe@example.com (Jane Doe) + joesmith@example.com (Joe Smith) + Grateful Dead + MSFT + + <_item_extension_1> + just an item extension example + example + + <_item_extension_2> + just a second item extension example + example + + + + <![CDATA[Hello World]]> + https://example.com/hello-world3 + https://example.com/hello-world3 + Wed, 10 Jul 2013 23:00:00 GMT + + + janedoe@example.com (Jane Doe) + joesmith@example.com (Joe Smith) + Grateful Dead + MSFT + + <_item_extension_1> + just an item extension example + example + + <_item_extension_2> + just a second item extension example + example + + + + <![CDATA[Hello World]]> + http://example.org/guid + 50e14f43-dd4e-412f-864d-78943ea28d91 + Wed, 10 Jul 2013 23:00:00 GMT + + + <![CDATA[Hello World]]> + http://example.org/id + 67e32b59-3348-4dc3-9645-75c60b6f50cc + Wed, 10 Jul 2013 23:00:00 GMT + + + <![CDATA[Hello World]]> + http://example.org/link + http://example.org/link + Wed, 10 Jul 2013 23:00:00 GMT + + + <![CDATA[Hello World]]> + http://example.org/sanitize + http://example.org/sanitize + Wed, 10 Jul 2013 23:00:00 GMT + + + <_example_extension> + just an extension example + example + + + just an extension example + + +" +`; diff --git a/src/__tests__/atom1.spec.ts b/src/__tests__/atom1.spec.ts index d68f70d..e178103 100644 --- a/src/__tests__/atom1.spec.ts +++ b/src/__tests__/atom1.spec.ts @@ -30,4 +30,15 @@ describe("atom 1.0", () => { const actual = sampleFeed.atom1(); expect(actual).toMatchSnapshot(); }); + it("should sanitize enclosure url", () => { + sampleFeed.addItem({ + title: "Hello World", + link: "http://example.org/sanitize", + enclosure: { url: "https://example.com/hello&world.png" }, + date: updated, + }); + const actual = sampleFeed.atom1(); + expect(actual).toMatchSnapshot(); + expect(actual).toContain(' { const actual = sampleFeed.rss2(); expect(actual).toMatchSnapshot(); }); + it("should sanitize enclosure url", () => { + sampleFeed.addItem({ + title: "Hello World", + link: "http://example.org/sanitize", + enclosure: { url: "https://example.com/hello&world.png" }, + date: published, + }); + const actual = sampleFeed.rss2(); + expect(actual).toMatchSnapshot(); + expect(actual).toContain(''); + }); }); diff --git a/src/atom1.ts b/src/atom1.ts index 121635e..36b034a 100644 --- a/src/atom1.ts +++ b/src/atom1.ts @@ -226,15 +226,17 @@ const formatAuthor = (author: Author) => { */ const formatEnclosure = (enclosure: string | Enclosure, mimeCategory = "image") => { if (typeof enclosure === "string") { - const type = new URL(enclosure).pathname.split(".").slice(-1)[0]; - return { _attributes: { rel: "enclosure", href: enclosure, type: `${mimeCategory}/${type}` } }; + const sanitizedUrl = sanitize(enclosure); + const type = new URL(sanitizedUrl!).pathname.split(".").slice(-1)[0]; + return { _attributes: { rel: "enclosure", href: sanitizedUrl, type: `${mimeCategory}/${type}` } }; } - const type = new URL(enclosure.url).pathname.split(".").slice(-1)[0]; + const sanitizedUrl = sanitize(enclosure.url); + const type = new URL(sanitizedUrl!).pathname.split(".").slice(-1)[0]; return { _attributes: { rel: "enclosure", - href: enclosure.url, + href: sanitizedUrl, title: enclosure.title, type: `${mimeCategory}/${type}`, length: enclosure.length, diff --git a/src/rss2.ts b/src/rss2.ts index 513c51c..e311f05 100644 --- a/src/rss2.ts +++ b/src/rss2.ts @@ -281,12 +281,14 @@ export default (ins: Feed) => { */ const formatEnclosure = (enclosure: string | Enclosure, mimeCategory = "image") => { if (typeof enclosure === "string") { - const type = new URL(sanitize(enclosure)!).pathname.split(".").slice(-1)[0]; - return { _attributes: { url: enclosure, length: 0, type: `${mimeCategory}/${type}` } }; + const sanitizedUrl = sanitize(enclosure); + const type = new URL(sanitizedUrl!).pathname.split(".").slice(-1)[0]; + return { _attributes: { url: sanitizedUrl, length: 0, type: `${mimeCategory}/${type}` } }; } - const type = new URL(sanitize(enclosure.url)!).pathname.split(".").slice(-1)[0]; - return { _attributes: { length: 0, type: `${mimeCategory}/${type}`, ...enclosure } }; + const sanitizedUrl = sanitize(enclosure.url); + const type = new URL(sanitizedUrl!).pathname.split(".").slice(-1)[0]; + return { _attributes: { length: 0, type: `${mimeCategory}/${type}`, ...enclosure, url: sanitizedUrl } }; }; /**