From a4f5793a07e3400eca5be9c7ae3359e9cb16b579 Mon Sep 17 00:00:00 2001 From: greymoth <246701683+greymoth-jp@users.noreply.github.com> Date: Tue, 30 Jun 2026 19:05:29 +0900 Subject: [PATCH] fix(atom): escape & in category attribute values --- src/__tests__/atom1.spec.ts | 22 ++++++++++++++++++++++ src/atom1.ts | 8 ++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/__tests__/atom1.spec.ts b/src/__tests__/atom1.spec.ts index e178103..0423765 100644 --- a/src/__tests__/atom1.spec.ts +++ b/src/__tests__/atom1.spec.ts @@ -41,4 +41,26 @@ describe("atom 1.0", () => { expect(actual).toMatchSnapshot(); expect(actual).toContain(' { + const feed = new Feed({ + title: "Feed Title", + id: "http://example.com/", + link: "http://example.com/", + updated, + }); + feed.addCategory("Arts & Crafts"); + feed.addItem({ + title: "Hello World", + link: "http://example.org/2013/12/14", + date: updated, + category: [{ name: "R&D", scheme: "https://example.com/s?a=1&b=2" }], + }); + const actual = feed.atom1(); + // unlike a text node, xml-js does not escape `&` inside an attribute value, + // so it must be escaped before being handed to the serializer + expect(actual).toContain(''); + expect(actual).toContain(''); + expect(actual).not.toContain("Arts & Crafts"); + }); }); diff --git a/src/atom1.ts b/src/atom1.ts index 36b034a..f91aefc 100644 --- a/src/atom1.ts +++ b/src/atom1.ts @@ -82,7 +82,7 @@ export default (ins: Feed) => { base.feed.category = []; ins.categories.forEach((category: string) => { - base.feed.category.push({ _attributes: { term: category } }); + base.feed.category.push({ _attributes: { term: sanitize(category) } }); }); base.feed.contributor = []; @@ -253,9 +253,9 @@ const formatCategory = (category: Category) => { return { _attributes: { - label: name, - scheme, - term, + label: sanitize(name), + scheme: sanitize(scheme), + term: sanitize(term), }, }; };