فهرست منبع

feat(jsonfeed): support malformed feeds with author object in authors array

Frédéric Guillot 2 ماه پیش
والد
کامیت
a2a5244387
2فایلهای تغییر یافته به همراه58 افزوده شده و 2 حذف شده
  1. 25 2
      internal/reader/json/json.go
  2. 33 0
      internal/reader/json/parser_test.go

+ 25 - 2
internal/reader/json/json.go

@@ -3,6 +3,8 @@
 
 package json // import "miniflux.app/v2/internal/reader/json"
 
+import "encoding/json"
+
 // JSON Feed specs:
 // https://www.jsonfeed.org/version/1.1/
 // https://www.jsonfeed.org/version/1/
@@ -31,7 +33,7 @@ type JSONFeed struct {
 	FaviconURL string `json:"favicon"`
 
 	// Authors specifies one or more feed authors. The author object has several members.
-	Authors []JSONAuthor `json:"authors"` // JSON Feed v1.1
+	Authors JSONAuthors `json:"authors"` // JSON Feed v1.1
 
 	// Author specifies the feed author. The author object has several members.
 	// JSON Feed v1 (deprecated)
@@ -62,6 +64,27 @@ type JSONAuthor struct {
 	AvatarURL string `json:"avatar"`
 }
 
+// JSONAuthors unmarshals either an array or a single author object.
+// Some feeds incorrectly use an object for "authors"; we accept it to avoid failing the whole feed.
+type JSONAuthors []JSONAuthor
+
+func (a *JSONAuthors) UnmarshalJSON(data []byte) error {
+	var authors []JSONAuthor
+	if err := json.Unmarshal(data, &authors); err == nil {
+		*a = authors
+		return nil
+	}
+
+	var author JSONAuthor
+	if err := json.Unmarshal(data, &author); err == nil {
+		*a = []JSONAuthor{author}
+		return nil
+	}
+
+	// Ignore invalid formats silently; the caller can still use other fields.
+	return nil
+}
+
 type JSONHub struct {
 	// Type defines the protocol used to talk with the hub: "rssCloud" or "WebSub".
 	Type string `json:"type"`
@@ -112,7 +135,7 @@ type JSONItem struct {
 	Language string `json:"language"`
 
 	// Authors is an array of JSONAuthor.
-	Authors []JSONAuthor `json:"authors"`
+	Authors JSONAuthors `json:"authors"`
 
 	// Author is a JSONAuthor.
 	// JSON Feed v1 (deprecated)

+ 33 - 0
internal/reader/json/parser_test.go

@@ -598,6 +598,39 @@ func TestParseItemWithMultipleDuplicateAuthors(t *testing.T) {
 	}
 }
 
+func TestParseItemWithAuthorsObject(t *testing.T) {
+	data := `{
+		"version": "https://jsonfeed.org/version/1.1",
+		"title": "Example",
+		"home_page_url": "https://example.org/",
+		"feed_url": "https://example.org/feed.json",
+		"items": [
+			{
+				"id": "1",
+				"title": "Example Item",
+				"url": "https://example.org/item",
+				"date_published": "2020-01-02T03:04:05Z",
+				"authors": {
+					"name": "Example Author"
+				}
+			}
+		]
+	}`
+
+	feed, err := Parse("https://example.org/feed.json", bytes.NewBufferString(data))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(feed.Entries) != 1 {
+		t.Fatalf("Incorrect number of entries, got: %d", len(feed.Entries))
+	}
+
+	if feed.Entries[0].Author != "Example Author" {
+		t.Errorf("Incorrect entry author, got: %s", feed.Entries[0].Author)
+	}
+}
+
 func TestParseItemWithInvalidDate(t *testing.T) {
 	data := `{
 		"version": "https://jsonfeed.org/version/1",