diff --git a/app/src/main/java/run/halo/feed/RssXmlBuilder.java b/app/src/main/java/run/halo/feed/RssXmlBuilder.java index 01f714d..58d05b0 100644 --- a/app/src/main/java/run/halo/feed/RssXmlBuilder.java +++ b/app/src/main/java/run/halo/feed/RssXmlBuilder.java @@ -7,6 +7,7 @@ import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.util.List; +import java.util.Optional; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.dom4j.Document; @@ -146,9 +147,13 @@ private void createItemElementsToChannel(Element channel, List items) private void createItemElementToChannel(Element channel, RSS2.Item item) { Element itemElement = channel.addElement("item"); - itemElement.addElement("title").addCDATA(item.getTitle()); + itemElement.addElement("title") + .addCDATA(XmlCharUtils.removeInvalidXmlChar(item.getTitle())); itemElement.addElement("link").addText(item.getLink()); - var description = getDescriptionWithTelemetry(item); + + var description = Optional.of(getDescriptionWithTelemetry(item)) + .map(XmlCharUtils::removeInvalidXmlChar) + .orElseThrow(); itemElement.addElement("description").addCDATA(description); itemElement.addElement("guid") .addAttribute("isPermaLink", "false") diff --git a/app/src/test/java/run/halo/feed/RSS2Test.java b/app/src/test/java/run/halo/feed/RSS2Test.java index a8773b1..c350485 100644 --- a/app/src/test/java/run/halo/feed/RSS2Test.java +++ b/app/src/test/java/run/halo/feed/RSS2Test.java @@ -4,6 +4,7 @@ import java.time.Instant; import java.util.Arrays; +import java.util.Collections; import org.junit.jupiter.api.Test; class RSS2Test { @@ -130,4 +131,58 @@ void extractRssTagsTest() { """.formatted(lastBuildDate); assertThat(rssXml).isEqualToIgnoringWhitespace(expected); } + + @Test + void invalidCharTest() { + var rss = RSS2.builder() + .title("title") + .description("description") + .link("link") + .items(Collections.singletonList( + RSS2.Item.builder() + .title("title1") + .description(""" +

并且会保留处理后的图片以供后面的访问。

+ """) + .link("link1") + .pubDate(Instant.EPOCH) + .guid("guid1") + .build() + )) + .build(); + var instant = Instant.now(); + var rssXml = new RssXmlBuilder() + .withRss2(rss) + .withGenerator("Halo") + .withLastBuildDate(instant) + .toXmlString(); + + var lastBuildDate = RssXmlBuilder.instantToString(instant); + // language=xml + var expected = """ + + + + title + link + description + Halo + zh-cn + %s + + + <![CDATA[title1]]> + + link1 + + 并且会保留处理后的图片以供后面的访问。

]]> +
+ guid1 + Thu, 1 Jan 1970 00:00:00 GMT +
+
+
+ """.formatted(lastBuildDate); + assertThat(rssXml).isEqualToIgnoringWhitespace(expected); + } } \ No newline at end of file