Skip to content

Commit 1685198

Browse files
authored
fix double escaping of & in Atom feed "self" URL (#206)
1 parent c55cfce commit 1685198

File tree

7 files changed

+68
-48
lines changed

7 files changed

+68
-48
lines changed

src/__tests__/__snapshots__/atom1.spec.ts.snap

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
exports[`atom 1.0 should generate a valid feed 1`] = `
44
"<?xml version=\\"1.0\\" encoding=\\"utf-8\\"?>
55
<feed xmlns=\\"http://www.w3.org/2005/Atom\\">
6-
<id>http://example.com/</id>
6+
<id>http://example.com/?link=sanitized&amp;value=4</id>
77
<title>Feed Title</title>
88
<updated>2013-07-13T23:00:00.000Z</updated>
99
<generator>https://github.com/jpmonette/feed</generator>
@@ -12,12 +12,12 @@ exports[`atom 1.0 should generate a valid feed 1`] = `
1212
<email>[email protected]</email>
1313
<uri>https://example.com/johndoe?link=sanitized&amp;value=2</uri>
1414
</author>
15-
<link rel=\\"alternate\\" href=\\"http://example.com/\\"/>
16-
<link rel=\\"self\\" href=\\"http://example.com/sampleFeed.rss\\"/>
15+
<link rel=\\"alternate\\" href=\\"http://example.com/?link=sanitized&amp;value=3\\"/>
16+
<link rel=\\"self\\" href=\\"http://example.com/sampleFeed.rss?link=sanitized&amp;value=2\\"/>
1717
<link rel=\\"hub\\" href=\\"wss://example.com/\\"/>
1818
<subtitle>This is my personnal feed!</subtitle>
19-
<logo>http://example.com/image.png</logo>
20-
<icon>http://example.com/image.ico</icon>
19+
<logo>http://example.com/image.png?link=sanitized&amp;value=6</logo>
20+
<icon>http://example.com/image.ico?link=sanitized&amp;value=7</icon>
2121
<rights>All rights reserved 2013, John Doe</rights>
2222
<category term=\\"Technology\\"/>
2323
<contributor>

src/__tests__/__snapshots__/json.spec.ts.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ exports[`json 1 should generate a valid feed 1`] = `
44
"{
55
\\"version\\": \\"https://jsonfeed.org/version/1\\",
66
\\"title\\": \\"Feed Title\\",
7-
\\"home_page_url\\": \\"http://example.com/\\",
8-
\\"feed_url\\": \\"http://example.com/sampleFeed.json\\",
7+
\\"home_page_url\\": \\"http://example.com/?link=sanitized&value=3\\",
8+
\\"feed_url\\": \\"http://example.com/sampleFeed.json?link=sanitized&value=5\\",
99
\\"description\\": \\"This is my personnal feed!\\",
10-
\\"icon\\": \\"http://example.com/image.png\\",
10+
\\"icon\\": \\"http://example.com/image.png?link=sanitized&value=6\\",
1111
\\"author\\": {
1212
\\"name\\": \\"John Doe\\",
1313
\\"url\\": \\"https://example.com/johndoe?link=sanitized&value=2\\"

src/__tests__/__snapshots__/rss2.spec.ts.snap

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ exports[`rss 2.0 should generate a valid feed 1`] = `
55
<rss version=\\"2.0\\" xmlns:dc=\\"http://purl.org/dc/elements/1.1/\\" xmlns:content=\\"http://purl.org/rss/1.0/modules/content/\\" xmlns:atom=\\"http://www.w3.org/2005/Atom\\">
66
<channel>
77
<title>Feed Title</title>
8-
<link>http://example.com/</link>
8+
<link>http://example.com/?link=sanitized&amp;value=3</link>
99
<description>This is my personnal feed!</description>
1010
<lastBuildDate>Sat, 13 Jul 2013 23:00:00 GMT</lastBuildDate>
1111
<docs>https://validator.w3.org/feed/docs/rss2.html</docs>
@@ -14,8 +14,8 @@ exports[`rss 2.0 should generate a valid feed 1`] = `
1414
<ttl>60</ttl>
1515
<image>
1616
<title>Feed Title</title>
17-
<url>http://example.com/image.png</url>
18-
<link>http://example.com/</link>
17+
<url>http://example.com/image.png?link=sanitized&amp;value=6</url>
18+
<link>http://example.com/?link=sanitized&amp;value=3</link>
1919
</image>
2020
<copyright>All rights reserved 2013, John Doe</copyright>
2121
<category>Technology</category>
@@ -54,7 +54,7 @@ exports[`rss 2.0 should generate a valid feed with audio 1`] = `
5454
<rss version=\\"2.0\\" xmlns:dc=\\"http://purl.org/dc/elements/1.1/\\" xmlns:content=\\"http://purl.org/rss/1.0/modules/content/\\" xmlns:atom=\\"http://www.w3.org/2005/Atom\\">
5555
<channel>
5656
<title>Feed Title</title>
57-
<link>http://example.com/</link>
57+
<link>http://example.com/?link=sanitized&amp;value=3</link>
5858
<description>This is my personnal feed!</description>
5959
<lastBuildDate>Sat, 13 Jul 2013 23:00:00 GMT</lastBuildDate>
6060
<docs>https://validator.w3.org/feed/docs/rss2.html</docs>
@@ -63,8 +63,8 @@ exports[`rss 2.0 should generate a valid feed with audio 1`] = `
6363
<ttl>60</ttl>
6464
<image>
6565
<title>Feed Title</title>
66-
<url>http://example.com/image.png</url>
67-
<link>http://example.com/</link>
66+
<url>http://example.com/image.png?link=sanitized&amp;value=6</url>
67+
<link>http://example.com/?link=sanitized&amp;value=3</link>
6868
</image>
6969
<copyright>All rights reserved 2013, John Doe</copyright>
7070
<category>Technology</category>
@@ -166,7 +166,7 @@ exports[`rss 2.0 should generate a valid feed with enclosure 1`] = `
166166
<rss version=\\"2.0\\" xmlns:dc=\\"http://purl.org/dc/elements/1.1/\\" xmlns:content=\\"http://purl.org/rss/1.0/modules/content/\\" xmlns:atom=\\"http://www.w3.org/2005/Atom\\">
167167
<channel>
168168
<title>Feed Title</title>
169-
<link>http://example.com/</link>
169+
<link>http://example.com/?link=sanitized&amp;value=3</link>
170170
<description>This is my personnal feed!</description>
171171
<lastBuildDate>Sat, 13 Jul 2013 23:00:00 GMT</lastBuildDate>
172172
<docs>https://validator.w3.org/feed/docs/rss2.html</docs>
@@ -175,8 +175,8 @@ exports[`rss 2.0 should generate a valid feed with enclosure 1`] = `
175175
<ttl>60</ttl>
176176
<image>
177177
<title>Feed Title</title>
178-
<url>http://example.com/image.png</url>
179-
<link>http://example.com/</link>
178+
<url>http://example.com/image.png?link=sanitized&amp;value=6</url>
179+
<link>http://example.com/?link=sanitized&amp;value=3</link>
180180
</image>
181181
<copyright>All rights reserved 2013, John Doe</copyright>
182182
<category>Technology</category>
@@ -257,7 +257,7 @@ exports[`rss 2.0 should generate a valid feed with image properties 1`] = `
257257
<rss version=\\"2.0\\" xmlns:dc=\\"http://purl.org/dc/elements/1.1/\\" xmlns:content=\\"http://purl.org/rss/1.0/modules/content/\\" xmlns:atom=\\"http://www.w3.org/2005/Atom\\">
258258
<channel>
259259
<title>Feed Title</title>
260-
<link>http://example.com/</link>
260+
<link>http://example.com/?link=sanitized&amp;value=3</link>
261261
<description>This is my personnal feed!</description>
262262
<lastBuildDate>Sat, 13 Jul 2013 23:00:00 GMT</lastBuildDate>
263263
<docs>https://validator.w3.org/feed/docs/rss2.html</docs>
@@ -266,8 +266,8 @@ exports[`rss 2.0 should generate a valid feed with image properties 1`] = `
266266
<ttl>60</ttl>
267267
<image>
268268
<title>Feed Title</title>
269-
<url>http://example.com/image.png</url>
270-
<link>http://example.com/</link>
269+
<url>http://example.com/image.png?link=sanitized&amp;value=6</url>
270+
<link>http://example.com/?link=sanitized&amp;value=3</link>
271271
</image>
272272
<copyright>All rights reserved 2013, John Doe</copyright>
273273
<category>Technology</category>
@@ -371,7 +371,7 @@ exports[`rss 2.0 should generate a valid podcast feed with audio 1`] = `
371371
<rss version=\\"2.0\\" xmlns:dc=\\"http://purl.org/dc/elements/1.1/\\" xmlns:content=\\"http://purl.org/rss/1.0/modules/content/\\" xmlns:atom=\\"http://www.w3.org/2005/Atom\\" xmlns:googleplay=\\"http://www.google.com/schemas/play-podcasts/1.0\\" xmlns:itunes=\\"http://www.itunes.com/dtds/podcast-1.0.dtd\\">
372372
<channel>
373373
<title>Feed Title</title>
374-
<link>http://example.com/</link>
374+
<link>http://example.com/?link=sanitized&amp;value=3</link>
375375
<description>This is my personnal feed!</description>
376376
<lastBuildDate>Sat, 13 Jul 2013 23:00:00 GMT</lastBuildDate>
377377
<docs>https://validator.w3.org/feed/docs/rss2.html</docs>
@@ -380,8 +380,8 @@ exports[`rss 2.0 should generate a valid podcast feed with audio 1`] = `
380380
<ttl>60</ttl>
381381
<image>
382382
<title>Feed Title</title>
383-
<url>http://example.com/image.png</url>
384-
<link>http://example.com/</link>
383+
<url>http://example.com/image.png?link=sanitized&amp;value=6</url>
384+
<link>http://example.com/?link=sanitized&amp;value=3</link>
385385
</image>
386386
<copyright>All rights reserved 2013, John Doe</copyright>
387387
<category>Technology</category>
@@ -398,6 +398,14 @@ exports[`rss 2.0 should generate a valid podcast feed with audio 1`] = `
398398
<category>Grateful Dead</category>
399399
<category domain=\\"http://www.fool.com/cusips\\">MSFT</category>
400400
<enclosure url=\\"https://example.com/hello-world.jpg\\" length=\\"0\\" type=\\"image/jpg\\"/>
401+
<_item_extension_1>
402+
<about>just an item extension example</about>
403+
<dummy1>example</dummy1>
404+
</_item_extension_1>
405+
<_item_extension_2>
406+
<about>just a second item extension example</about>
407+
<dummy1>example</dummy1>
408+
</_item_extension_2>
401409
</item>
402410
<item>
403411
<title><![CDATA[Hello World]]></title>
@@ -412,14 +420,26 @@ exports[`rss 2.0 should generate a valid podcast feed with audio 1`] = `
412420
<category domain=\\"http://www.fool.com/cusips\\">MSFT</category>
413421
<enclosure length=\\"12665\\" type=\\"audio/mpeg\\" url=\\"https://example.com/hello-world.mp3\\"/>
414422
<itunes:duration>50:00</itunes:duration>
423+
<_item_extension_1>
424+
<about>just an item extension example</about>
425+
<dummy1>example</dummy1>
426+
</_item_extension_1>
427+
<_item_extension_2>
428+
<about>just a second item extension example</about>
429+
<dummy1>example</dummy1>
430+
</_item_extension_2>
415431
</item>
432+
<_example_extension>
433+
<about>just an extension example</about>
434+
<dummy>example</dummy>
435+
</_example_extension>
416436
<googleplay:owner>[email protected]</googleplay:owner>
417437
<itunes:owner>
418438
<itunes:email>[email protected]</itunes:email>
419439
</itunes:owner>
420440
<googleplay:author>John Doe</googleplay:author>
421441
<itunes:author>John Doe</itunes:author>
422-
<googleplay:image href=\\"http://example.com/image.png\\"/>
442+
<googleplay:image href=\\"http://example.com/image.png?link=sanitized&amp;value=6\\"/>
423443
</channel>
424444
</rss>"
425445
`;

src/__tests__/setup.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,25 @@ export const createSampleFeed = () => {
77
var feed = new Feed({
88
title: "Feed Title",
99
description: "This is my personnal feed!",
10-
link: "http://example.com/",
11-
id: "http://example.com/",
12-
feed: "http://example.com/sampleFeed.rss",
10+
link: "http://example.com/?link=sanitized&value=3",
11+
id: "http://example.com/?link=sanitized&value=4",
12+
feed: "http://example.com/sampleFeed.rss?link=sanitized&value=2",
1313
feedLinks: {
14-
json: "http://example.com/sampleFeed.json",
14+
json: "http://example.com/sampleFeed.json?link=sanitized&value=5",
1515
},
1616
language: "en",
1717
ttl: 60,
18-
image: "http://example.com/image.png",
19-
favicon: "http://example.com/image.ico",
18+
image: "http://example.com/image.png?link=sanitized&value=6",
19+
favicon: "http://example.com/image.ico?link=sanitized&value=7",
2020
copyright: "All rights reserved 2013, John Doe",
2121
hub: "wss://example.com/",
2222
updated, // optional, default = today
2323

2424
author: {
2525
name: "John Doe",
2626
27-
link: "https://example.com/johndoe?link=sanitized&value=2"
28-
}
27+
link: "https://example.com/johndoe?link=sanitized&value=2",
28+
},
2929
});
3030

3131
feed.addCategory("Technology");
@@ -55,7 +55,7 @@ export const createSampleFeed = () => {
5555
},
5656
{
5757
name: "Joe Smith, Name Only",
58-
}
58+
},
5959
],
6060
contributor: [
6161
{
@@ -109,6 +109,6 @@ export const createSampleFeed = () => {
109109
});
110110

111111
return feed;
112-
}
112+
};
113113

114-
export const sampleFeed = createSampleFeed();
114+
export const sampleFeed = createSampleFeed();

src/atom1.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ export default (ins: Feed) => {
1818
id: options.id,
1919
title: options.title,
2020
updated: options.updated ? options.updated.toISOString() : new Date().toISOString(),
21-
generator: sanitize(options.generator || generator)
22-
}
21+
generator: sanitize(options.generator || generator),
22+
},
2323
};
2424

2525
if (options.author) {
@@ -34,7 +34,7 @@ export default (ins: Feed) => {
3434
}
3535

3636
// link (rel="self")
37-
const atomLink = sanitize(options.feed || (options.feedLinks && options.feedLinks.atom));
37+
const atomLink = options.feed || (options.feedLinks && options.feedLinks.atom);
3838

3939
if (atomLink) {
4040
base.feed.link.push({ _attributes: { rel: "self", href: sanitize(atomLink) } });
@@ -93,7 +93,7 @@ export default (ins: Feed) => {
9393
title: { _attributes: { type: "html" }, _cdata: item.title },
9494
id: sanitize(item.id || item.link),
9595
link: [{ _attributes: { href: sanitize(item.link) } }],
96-
updated: item.date.toISOString()
96+
updated: item.date.toISOString(),
9797
};
9898

9999
//
@@ -193,7 +193,7 @@ export default (ins: Feed) => {
193193
const formatAuthor = (author: Author) => {
194194
const { name, email, link } = author;
195195

196-
const out: { name?: string, email?: string, uri?: string } = { name };
196+
const out: { name?: string; email?: string; uri?: string } = { name };
197197
if (email) {
198198
out.email = email;
199199
}

src/rss2.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ export default (ins: Feed) => {
187187

188188
if (entry.audio) {
189189
let duration = undefined;
190-
if (options.podcast && typeof entry.audio !== 'string' && entry.audio.duration) {
190+
if (options.podcast && typeof entry.audio !== "string" && entry.audio.duration) {
191191
duration = entry.audio.duration;
192192
entry.audio.duration = undefined;
193193
}
@@ -240,7 +240,7 @@ export default (ins: Feed) => {
240240
if (options.author?.email) {
241241
base.rss.channel["googleplay:owner"] = options.author.email;
242242
base.rss.channel["itunes:owner"] = {
243-
'itunes:email': options.author.email
243+
"itunes:email": options.author.email,
244244
};
245245
}
246246
if (options.author?.name) {
@@ -249,7 +249,7 @@ export default (ins: Feed) => {
249249
}
250250
if (options.image) {
251251
base.rss.channel["googleplay:image"] = {
252-
_attributes: { href: sanitize(options.image) }
252+
_attributes: { href: sanitize(options.image) },
253253
};
254254
}
255255
}
@@ -264,11 +264,11 @@ export default (ins: Feed) => {
264264
*/
265265
const formatEnclosure = (enclosure: string | Enclosure, mimeCategory = "image") => {
266266
if (typeof enclosure === "string") {
267-
const type = new URL(sanitize(enclosure)).pathname.split(".").slice(-1)[0];
267+
const type = new URL(sanitize(enclosure)!).pathname.split(".").slice(-1)[0];
268268
return { _attributes: { url: enclosure, length: 0, type: `${mimeCategory}/${type}` } };
269269
}
270270

271-
const type = new URL(sanitize(enclosure.url)).pathname.split(".").slice(-1)[0];
271+
const type = new URL(sanitize(enclosure.url)!).pathname.split(".").slice(-1)[0];
272272
return { _attributes: { length: 0, type: `${mimeCategory}/${type}`, ...enclosure } };
273273
};
274274

@@ -297,4 +297,4 @@ const formatDuration = (duration: number) => {
297297
const hours = Math.floor(totalMinutes / 60);
298298
const notHours = ("0" + minutes).substr(-2) + ":" + ("0" + seconds).substr(-2);
299299
return hours > 0 ? hours + ":" + notHours : notHours;
300-
}
300+
};

src/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export function sanitize(url: string | undefined): string | undefined {
2-
if (typeof (url) === 'undefined') {
2+
if (typeof url === "undefined") {
33
return;
44
}
5-
return url.replace(/&/g, '&amp;');
5+
return url.replace(/&/g, "&amp;");
66
}

0 commit comments

Comments
 (0)