feedjira 4.0.2 → 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile +5 -5
- data/Rakefile +1 -1
- data/lib/feedjira/feed_entry_utilities.rb +1 -2
- data/lib/feedjira/feed_utilities.rb +1 -1
- data/lib/feedjira/rss_entry_utilities.rb +1 -2
- data/lib/feedjira/sax_nokogiri_handler_patch.rb +24 -0
- data/lib/feedjira/version.rb +1 -1
- data/lib/feedjira.rb +1 -0
- data/spec/feedjira/parser/atom_spec.rb +2 -2
- data/spec/feedjira/preprocessor_spec.rb +2 -2
- data/spec/feedjira/sax_nokogiri_handler_patch_spec.rb +65 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3f87fde64ce148ec9ebbd1da344070d1e9bb381904b377e030d9aae56b602aa3
|
|
4
|
+
data.tar.gz: 82282b9e5c0b03acd93b5a7e11f697793ef1d2bd34014178fcde7f632d3259ec
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 83b305a7cd33379b384ef8fe60928ba02cf7f64b0f49793d989c2a37a61ebf4a70d424b15709bd4b441de1b6bb2e170db1b646e590998bd31279b599d238fbc1
|
|
7
|
+
data.tar.gz: ae3c9076b1ae95dd943be0e4903ceaade5c955dde3a8af6bb45b8da9e94390b5a0a4607e469537a090246762febd4dcb68da8c56659cacf198da8db79af4a585
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
|
@@ -4,18 +4,18 @@ source "https://rubygems.org/"
|
|
|
4
4
|
|
|
5
5
|
gemspec
|
|
6
6
|
|
|
7
|
-
gem "faraday", "~> 2.
|
|
7
|
+
gem "faraday", "~> 2.15.0"
|
|
8
8
|
gem "pry", "~> 0.16.0"
|
|
9
9
|
gem "rspec", "~> 3.13.0"
|
|
10
|
-
gem "rubocop", "~> 1.
|
|
11
|
-
gem "rubocop-performance", "~> 1.
|
|
10
|
+
gem "rubocop", "~> 1.92.0"
|
|
11
|
+
gem "rubocop-performance", "~> 1.27.0"
|
|
12
12
|
gem "rubocop-rake", "~> 0.7.1"
|
|
13
|
-
gem "rubocop-rspec", "~> 3.
|
|
13
|
+
gem "rubocop-rspec", "~> 3.10.2"
|
|
14
14
|
gem "simplecov", "~> 0.22.0"
|
|
15
15
|
gem "yard", "~> 0.9.34"
|
|
16
16
|
|
|
17
17
|
group :test do
|
|
18
18
|
gem "oga", "~> 3.4"
|
|
19
19
|
gem "ox", "~> 2.14.17", platforms: %i[mri rbx]
|
|
20
|
-
gem "rake", "~> 13.
|
|
20
|
+
gem "rake", "~> 13.4.2"
|
|
21
21
|
end
|
data/Rakefile
CHANGED
|
@@ -19,11 +19,10 @@ module Feedjira
|
|
|
19
19
|
##
|
|
20
20
|
# Returns the id of the entry or its url if not id is present, as some
|
|
21
21
|
# formats don't support it
|
|
22
|
-
# rubocop:disable Naming/MemoizedInstanceVariableName
|
|
22
|
+
# rubocop:disable-next Naming/MemoizedInstanceVariableName
|
|
23
23
|
def id
|
|
24
24
|
@entry_id ||= @url
|
|
25
25
|
end
|
|
26
|
-
# rubocop:enable Naming/MemoizedInstanceVariableName
|
|
27
26
|
|
|
28
27
|
##
|
|
29
28
|
# Writer for published. By default, we keep the "oldest" publish time found.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Feedjira
|
|
4
4
|
module RSSEntryUtilities
|
|
5
|
-
# rubocop:todo Metrics/MethodLength
|
|
5
|
+
# rubocop:todo-next Metrics/MethodLength
|
|
6
6
|
def self.included(mod) # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
|
|
7
7
|
mod.class_exec do
|
|
8
8
|
element :title
|
|
@@ -40,7 +40,6 @@ module Feedjira
|
|
|
40
40
|
elements :category, as: :categories
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
|
-
# rubocop:enable Metrics/MethodLength
|
|
44
43
|
|
|
45
44
|
def entry_id
|
|
46
45
|
@entry_id&.guid
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "sax-machine/handlers/sax_nokogiri_handler"
|
|
4
|
+
|
|
5
|
+
module Feedjira
|
|
6
|
+
# sax-machine's Nokogiri handler turns on entity replacement, which makes
|
|
7
|
+
# libxml2 load external entities declared in a feed's DOCTYPE (XXE). This
|
|
8
|
+
# parses with Nokogiri's default instead, which still decodes predefined
|
|
9
|
+
# entities, character references, and internal entities in text.
|
|
10
|
+
module SAXNokogiriHandlerPatch
|
|
11
|
+
# Parse without entity replacement so external entities are never loaded.
|
|
12
|
+
def sax_parse(xml_input)
|
|
13
|
+
::Nokogiri::XML::SAX::Parser.new(self).parse(xml_input)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Without entity replacement, libxml2 returns "&" in attribute values as
|
|
17
|
+
# "&", so we turn it back into "&".
|
|
18
|
+
def start_element(name, attrs = [])
|
|
19
|
+
super(name, attrs.map { |key, value| [key, value.gsub("&", "&")] })
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
::SAXMachine::SAXNokogiriHandler.prepend(::Feedjira::SAXNokogiriHandlerPatch)
|
data/lib/feedjira/version.rb
CHANGED
data/lib/feedjira.rb
CHANGED
|
@@ -133,10 +133,10 @@ module Feedjira
|
|
|
133
133
|
feed = Atom.parse sample_atom_xhtml_feed
|
|
134
134
|
entry = feed.entries.first
|
|
135
135
|
|
|
136
|
-
expect(entry.raw_title).to
|
|
136
|
+
expect(entry.raw_title).to include("<i")
|
|
137
137
|
expect(entry.title).to eq("Sentry Calming Collar for dogs")
|
|
138
138
|
expect(entry.title_type).to eq("xhtml")
|
|
139
|
-
expect(entry.summary).to
|
|
139
|
+
expect(entry.summary).to include("<b")
|
|
140
140
|
expect(entry.content).to match(/\A<p/)
|
|
141
141
|
end
|
|
142
142
|
|
|
@@ -17,8 +17,8 @@ describe Feedjira::Preprocessor do
|
|
|
17
17
|
escaped = processor.to_xml
|
|
18
18
|
escaped_parts = escaped.split "\n"
|
|
19
19
|
|
|
20
|
-
expect(escaped_parts[10]).to
|
|
21
|
-
expect(escaped_parts[16]).to
|
|
20
|
+
expect(escaped_parts[10]).to include("<i>dogs</i>") # title
|
|
21
|
+
expect(escaped_parts[16]).to include("<b>XHTML</b>") # summary
|
|
22
22
|
expect(escaped_parts[26]).to match(/<p>$/) # content
|
|
23
23
|
end
|
|
24
24
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
require "tempfile"
|
|
5
|
+
|
|
6
|
+
::RSpec.describe(::Feedjira::SAXNokogiriHandlerPatch) do
|
|
7
|
+
around do |example|
|
|
8
|
+
original_handler = ::SAXMachine.handler
|
|
9
|
+
::SAXMachine.handler = :nokogiri
|
|
10
|
+
example.run
|
|
11
|
+
ensure
|
|
12
|
+
::SAXMachine.handler = original_handler
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def rss_with_entry(title: "Title", link: "https://example.com", doctype: "")
|
|
16
|
+
<<~XML
|
|
17
|
+
<?xml version="1.0"?>
|
|
18
|
+
#{doctype}
|
|
19
|
+
<rss version="2.0">
|
|
20
|
+
<channel>
|
|
21
|
+
<title>Feed</title>
|
|
22
|
+
<item>
|
|
23
|
+
<title>#{title}</title>
|
|
24
|
+
<enclosure url="#{link}" type="audio/mpeg"/>
|
|
25
|
+
</item>
|
|
26
|
+
</channel>
|
|
27
|
+
</rss>
|
|
28
|
+
XML
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "does not load external entities" do
|
|
32
|
+
secret = ::Tempfile.new
|
|
33
|
+
secret.write("secret contents")
|
|
34
|
+
secret.flush
|
|
35
|
+
doctype = %(<!DOCTYPE rss [<!ENTITY file SYSTEM "file://#{secret.path}">]>)
|
|
36
|
+
|
|
37
|
+
feed = ::Feedjira.parse(rss_with_entry(title: "&file;", doctype:))
|
|
38
|
+
|
|
39
|
+
expect(feed.entries.first.title.to_s).not_to(include("secret contents"))
|
|
40
|
+
ensure
|
|
41
|
+
secret.close!
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "decodes predefined entities and character references in text" do
|
|
45
|
+
feed = ::Feedjira.parse(rss_with_entry(title: "a & b < c ’"))
|
|
46
|
+
|
|
47
|
+
expect(feed.entries.first.title).to(eq("a & b < c ’"))
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "expands internal entities in text" do
|
|
51
|
+
doctype = '<!DOCTYPE rss [<!ENTITY co "Acme Inc">]>'
|
|
52
|
+
|
|
53
|
+
feed = ::Feedjira.parse(rss_with_entry(title: "by &co;", doctype:))
|
|
54
|
+
|
|
55
|
+
expect(feed.entries.first.title).to(eq("by Acme Inc"))
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "decodes ampersands in attribute values" do
|
|
59
|
+
xml = rss_with_entry(link: "https://example.com/?a=1&b=2&c=&#38;")
|
|
60
|
+
|
|
61
|
+
feed = ::Feedjira.parse(xml, parser: ::Feedjira::Parser::ITunesRSS)
|
|
62
|
+
|
|
63
|
+
expect(feed.entries.first.enclosure_url).to(eq("https://example.com/?a=1&b=2&c=&"))
|
|
64
|
+
end
|
|
65
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: feedjira
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.0.
|
|
4
|
+
version: 4.0.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Adam Hess
|
|
@@ -127,6 +127,7 @@ files:
|
|
|
127
127
|
- lib/feedjira/parser/rss_image.rb
|
|
128
128
|
- lib/feedjira/preprocessor.rb
|
|
129
129
|
- lib/feedjira/rss_entry_utilities.rb
|
|
130
|
+
- lib/feedjira/sax_nokogiri_handler_patch.rb
|
|
130
131
|
- lib/feedjira/util.rb
|
|
131
132
|
- lib/feedjira/util/parse_time.rb
|
|
132
133
|
- lib/feedjira/version.rb
|
|
@@ -157,6 +158,7 @@ files:
|
|
|
157
158
|
- spec/feedjira/parser/rss_feed_burner_spec.rb
|
|
158
159
|
- spec/feedjira/parser/rss_spec.rb
|
|
159
160
|
- spec/feedjira/preprocessor_spec.rb
|
|
161
|
+
- spec/feedjira/sax_nokogiri_handler_patch_spec.rb
|
|
160
162
|
- spec/feedjira/util/parse_time_spec.rb
|
|
161
163
|
- spec/feedjira_spec.rb
|
|
162
164
|
- spec/sample_feeds.rb
|
|
@@ -227,7 +229,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
227
229
|
- !ruby/object:Gem::Version
|
|
228
230
|
version: '0'
|
|
229
231
|
requirements: []
|
|
230
|
-
rubygems_version: 4.0.
|
|
232
|
+
rubygems_version: 4.0.20
|
|
231
233
|
specification_version: 4
|
|
232
234
|
summary: A feed parsing library
|
|
233
235
|
test_files: []
|