Browse Source

fix: check for nil link to avoid runtime panic #95 (#103)

## What type of PR is this? (check all applicable)
- [x] Bug Fix

## Description
Check for nil link in feed to avoid runtime panic

## Related Issue
- Closes #95

## Added/updated tests?
- [x] Yes
pull/104/head
Meir Blumenfeld 1 year ago committed by GitHub
parent
commit
3bdeb10cc2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 23
      atom.go
  2. 52
      feed_test.go
  3. 6
      rss.go

23
atom.go

@ -89,13 +89,16 @@ type Atom struct {
func newAtomEntry(i *Item) *AtomEntry {
id := i.Id
link := i.Link
if link == nil {
link = &Link{}
}
if len(id) == 0 {
// if there's no id set, try to create one, either from data or just a uuid
if len(i.Link.Href) > 0 && (!i.Created.IsZero() || !i.Updated.IsZero()) {
if len(link.Href) > 0 && (!i.Created.IsZero() || !i.Updated.IsZero()) {
dateStr := anyTimeFormat("2006-01-02", i.Updated, i.Created)
host, path := i.Link.Href, "/invalid.html"
if url, err := url.Parse(i.Link.Href); err == nil {
host, path := link.Href, "/invalid.html"
if url, err := url.Parse(link.Href); err == nil {
host, path = url.Host, url.Path
}
id = fmt.Sprintf("tag:%s,%s:%s", host, dateStr, path)
@ -108,13 +111,13 @@ func newAtomEntry(i *Item) *AtomEntry {
name, email = i.Author.Name, i.Author.Email
}
link_rel := i.Link.Rel
link_rel := link.Rel
if link_rel == "" {
link_rel = "alternate"
}
x := &AtomEntry{
Title: i.Title,
Links: []AtomLink{{Href: i.Link.Href, Rel: link_rel, Type: i.Link.Type}},
Links: []AtomLink{{Href: link.Href, Rel: link_rel, Type: link.Type}},
Id: id,
Updated: anyTimeFormat(time.RFC3339, i.Updated, i.Created),
}
@ -142,12 +145,16 @@ func newAtomEntry(i *Item) *AtomEntry {
// create a new AtomFeed with a generic Feed struct's data
func (a *Atom) AtomFeed() *AtomFeed {
updated := anyTimeFormat(time.RFC3339, a.Updated, a.Created)
link := a.Link
if link == nil {
link = &Link{}
}
feed := &AtomFeed{
Xmlns: ns,
Title: a.Title,
Link: &AtomLink{Href: a.Link.Href, Rel: a.Link.Rel},
Link: &AtomLink{Href: link.Href, Rel: link.Rel},
Subtitle: a.Description,
Id: a.Link.Href,
Id: link.Href,
Updated: updated,
Rights: a.Copyright,
}

52
feed_test.go

@ -504,6 +504,58 @@ func TestFeedSorted(t *testing.T) {
}
}
func TestFeedNil(t *testing.T) {
now, err := time.Parse(time.RFC3339, "2013-01-16T21:52:35-05:00")
if err != nil {
t.Error(err)
}
tz := time.FixedZone("EST", -5*60*60)
now = now.In(tz)
feed := &Feed{
Title: "jmoiron.net blog",
Link: nil,
Description: "discussion about tech, footie, photos",
Author: nil,
Created: now,
Copyright: "This work is copyright © Benjamin Button",
}
feed.Items = []*Item{
{
Title: "Limiting Concurrency in Go",
Link: nil,
Description: "A discussion on controlled parallelism in golang",
Author: nil,
Created: now,
Content: `<p>Go's goroutines make it easy to make <a href="http://collectiveidea.com/blog/archives/2012/12/03/playing-with-go-embarrassingly-parallel-scripts/">embarrassingly parallel programs</a>, but in many &quot;real world&quot; cases resources can be limited and attempting to do everything at once can exhaust your access to them.</p>`,
}}
if _, err := feed.ToAtom(); err != nil {
t.Errorf("unexpected error encoding Atom: %v", err)
}
var buf bytes.Buffer
if err := feed.WriteAtom(&buf); err != nil {
t.Errorf("unexpected error writing Atom: %v", err)
}
if _, err := feed.ToRss(); err != nil {
t.Errorf("unexpected error encoding RSS: %v", err)
}
buf.Reset()
if err := feed.WriteRss(&buf); err != nil {
t.Errorf("unexpected error writing RSS: %v", err)
}
if _, err := feed.ToJSON(); err != nil {
t.Errorf("unexpected error encoding JSON: %v", err)
}
buf.Reset()
if err := feed.WriteJSON(&buf); err != nil {
t.Errorf("unexpected error writing JSON: %v", err)
}
}
var jsonOutputHub = `{
"version": "https://jsonfeed.org/version/1",
"title": "feed title",

6
rss.go

@ -137,9 +137,13 @@ func (r *Rss) RssFeed() *RssFeed {
image = &RssImage{Url: r.Image.Url, Title: r.Image.Title, Link: r.Image.Link, Width: r.Image.Width, Height: r.Image.Height}
}
var href string
if r.Link != nil {
href = r.Link.Href
}
channel := &RssFeed{
Title: r.Title,
Link: r.Link.Href,
Link: href,
Description: r.Description,
ManagingEditor: author,
PubDate: pub,

Loading…
Cancel
Save