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),
},
};
};