diff options
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | lib/rss/0.9.rb | 2 | ||||
-rw-r--r-- | lib/rss/1.0.rb | 18 | ||||
-rw-r--r-- | lib/rss/content.rb | 6 | ||||
-rw-r--r-- | lib/rss/dublincore.rb | 5 | ||||
-rw-r--r-- | lib/rss/image.rb | 16 | ||||
-rw-r--r-- | lib/rss/parser.rb | 32 | ||||
-rw-r--r-- | lib/rss/rss.rb | 30 | ||||
-rw-r--r-- | lib/rss/syndication.rb | 6 | ||||
-rw-r--r-- | lib/rss/taxonomy.rb | 16 | ||||
-rw-r--r-- | lib/rss/trackback.rb | 6 | ||||
-rw-r--r-- | test/rss/rss-assertions.rb | 3 | ||||
-rw-r--r-- | test/rss/test_parser.rb | 51 |
13 files changed, 137 insertions, 71 deletions
@@ -1,3 +1,20 @@ +Sun Jun 18 18:13:25 2006 Kouhei Sutou <kou@cozmixng.org> + + * lib/rss/rss.rb: improved ignore_unknown_element + handling. RSS::NotExpectedTagError provides tag URI. + * lib/rss/parser.rb: ditto. + * lib/rss/0.9.rb: ditto. + * lib/rss/1.0.rb: ditto. + * lib/rss/content.rb: ditto. + * lib/rss/dublincore.rb: ditto. + * lib/rss/image.rb: ditto. + * lib/rss/syndication.rb: ditto. + * lib/rss/taxonomy.rb: ditto. + * lib/rss/trackback.rb: ditto. + + * test/rss/rss-assertions.rb: checked URI of not expected tag too. + * test/rss/test_parser.rb: ditto. + Sun Jun 18 18:08:36 2006 Kouhei Sutou <kou@cozmixng.org> * lib/rss/rss.rb: changed empty namespace URI representation to "" diff --git a/lib/rss/0.9.rb b/lib/rss/0.9.rb index c3df99a213..a5009f59ec 100644 --- a/lib/rss/0.9.rb +++ b/lib/rss/0.9.rb @@ -688,7 +688,7 @@ module RSS @rss.xml_stylesheets = @xml_stylesheets @last_element = @rss @proc_stack.push Proc.new { |text, tags| - @rss.validate_for_stream(tags) if @do_validate + @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate } end diff --git a/lib/rss/1.0.rb b/lib/rss/1.0.rb index 52cb2fb1ec..6e601d1a43 100644 --- a/lib/rss/1.0.rb +++ b/lib/rss/1.0.rb @@ -75,10 +75,6 @@ module RSS end private - def rdf_validate(tags) - _validate(tags, []) - end - def children [@channel, @image, @textinput, *@item] end @@ -181,8 +177,8 @@ module RSS @li end - def rdf_validate(tags) - _validate(tags, [["li", '*']]) + def rdf_validate(ignore_unknown_element, tags, uri) + _validate(ignore_unknown_element, tags, uri, [["li", '*']]) end def _tags @@ -241,8 +237,8 @@ module RSS @li end - def rdf_validate(tags) - _validate(tags, [["li", '*']]) + def rdf_validate(ignore_unknown_element, tags, uri) + _validate(ignore_unknown_element, tags, uri, [["li", '*']]) end def _tags @@ -471,8 +467,8 @@ module RSS rv end - def rdf_validate(tags) - _validate(tags, [["Seq", nil]]) + def rdf_validate(ignore_unknown_element, tags, uri) + _validate(ignore_unknown_element, tags, uri, [["Seq", nil]]) end end end @@ -710,7 +706,7 @@ module RSS @rss.xml_stylesheets = @xml_stylesheets @last_element = @rss @proc_stack.push Proc.new { |text, tags| - @rss.validate_for_stream(tags) if @do_validate + @rss.validate_for_stream(tags, @ignore_unknown_element) if @do_validate } end end diff --git a/lib/rss/content.rb b/lib/rss/content.rb index a732cec973..db96074a38 100644 --- a/lib/rss/content.rb +++ b/lib/rss/content.rb @@ -23,7 +23,7 @@ module RSS EOC end - def content_validate(tags) + def content_validate(ignore_unknown_element, tags, uri) counter = {} ELEMENTS.each do |name| counter[name] = 0 @@ -31,7 +31,9 @@ module RSS tags.each do |tag| key = "#{CONTENT_PREFIX}_#{tag}" - raise UnknownTagError.new(tag, CONTENT_URI) unless counter.has_key?(key) + if !ignore_unknown_element and !counter.has_key?(key) + raise UnknownTagError.new(tag, CONTENT_URI) + end counter[key] += 1 raise TooMuchTagError.new(tag, tag_name) if counter[key] > 1 end diff --git a/lib/rss/dublincore.rb b/lib/rss/dublincore.rb index 5571640bf2..646d1182d9 100644 --- a/lib/rss/dublincore.rb +++ b/lib/rss/dublincore.rb @@ -130,10 +130,11 @@ module RSS EOC end - def dc_validate(tags) + def dc_validate(ignore_unknown_element, tags, uri) tags.each do |tag| key = "#{DC_PREFIX}_#{tag}" - unless DublinCoreModel::ELEMENTS.include?(key) + if !ignore_unknown_element and + !DublinCoreModel::ELEMENTS.include?(key) raise UnknownTagError.new(tag, DC_URI) end end diff --git a/lib/rss/image.rb b/lib/rss/image.rb index f499a75a03..035df680cb 100644 --- a/lib/rss/image.rb +++ b/lib/rss/image.rb @@ -17,9 +17,11 @@ module RSS end module ImageModelUtils - def validate_one_tag_name(name, tags) - invalid = tags.find {|tag| tag != name} - raise UnknownTagError.new(invalid, IMAGE_URI) if invalid + def validate_one_tag_name(ignore_unknown_element, name, tags) + if !ignore_unknown_element + invalid = tags.find {|tag| tag != name} + raise UnknownTagError.new(invalid, IMAGE_URI) if invalid + end raise TooMuchTagError.new(name, tag_name) if tags.size > 1 end end @@ -34,8 +36,8 @@ module RSS klass.install_have_child_element("#{IMAGE_PREFIX}_item") end - def image_validate(tags) - validate_one_tag_name("item", tags) + def image_validate(ignore_unknown_element, tags, uri) + validate_one_tag_name(ignore_unknown_element, "item", tags) end class ImageItem < Element @@ -133,8 +135,8 @@ module RSS end end - def image_validate(tags) - validate_one_tag_name("favicon", tags) + def image_validate(ignore_unknown_element, tags, uri) + validate_one_tag_name(ignore_unknown_element, "favicon", tags) end class ImageFavicon < Element diff --git a/lib/rss/parser.rb b/lib/rss/parser.rb index 405bc87a63..ce9fff0b38 100644 --- a/lib/rss/parser.rb +++ b/lib/rss/parser.rb @@ -63,7 +63,8 @@ module RSS end end - def parse(rss, do_validate=true, ignore_unknown_element=true, parser_class=default_parser) + def parse(rss, do_validate=true, ignore_unknown_element=true, + parser_class=default_parser) parser = new(rss, parser_class) parser.do_validate = do_validate parser.ignore_unknown_element = ignore_unknown_element @@ -162,11 +163,6 @@ module RSS @@registered_uris = {} @@class_names = {} - def install_setter(uri, tag_name, setter) - @@setters[uri] ||= {} - @@setters[uri][tag_name] = setter - end - def setter(uri, tag_name) begin @@setters[uri][tag_name] @@ -215,6 +211,10 @@ module RSS end private + def install_setter(uri, tag_name, setter) + @@setters[uri] ||= {} + @@setters[uri][tag_name] = setter + end def def_get_text_element(uri, name, file, line) register_uri(uri, name) @@ -223,12 +223,6 @@ module RSS def start_#{name}(name, prefix, attrs, ns) uri = _ns(ns, prefix) if self.class.uri_registered?(uri, #{name.inspect}) - if @do_validate - tags = self.class.available_tags(uri) - unless tags.include?(name) - raise UnknownTagError.new(name, uri) - end - end start_get_text_element(name, prefix, ns, uri) else start_else_element(name, prefix, attrs, ns) @@ -337,14 +331,14 @@ module RSS next_class = current_class.const_get(class_name) start_have_something_element(local, prefix, attrs, ns, next_class) else - if @ignore_unknown_element + if !@do_validate or @ignore_unknown_element @proc_stack.push(nil) else parent = "ROOT ELEMENT???" if current_class.tag_name parent = current_class.tag_name end - raise NotExpectedTagError.new(local, parent) + raise NotExpectedTagError.new(local, _ns(ns, prefix), parent) end end end @@ -368,12 +362,12 @@ module RSS def start_get_text_element(tag_name, prefix, ns, required_uri) @proc_stack.push Proc.new {|text, tags| setter = self.class.setter(required_uri, tag_name) - setter ||= "#{tag_name}=" if @last_element.respond_to?(setter) @last_element.__send__(setter, text.to_s) else - if @do_validate and not @ignore_unknown_element - raise NotExpectedTagError.new(tag_name, @last_element.tag_name) + if @do_validate and !@ignore_unknown_element + raise NotExpectedTagError.new(tag_name, _ns(ns, prefix), + @last_element.tag_name) end end } @@ -424,7 +418,9 @@ module RSS @proc_stack.push Proc.new { |text, tags| p(@last_element.class) if DEBUG @last_element.content = text if klass.have_content? - @last_element.validate_for_stream(tags) if @do_validate + if @do_validate + @last_element.validate_for_stream(tags, @ignore_unknown_element) + end @last_element = previous } end diff --git a/lib/rss/rss.rb b/lib/rss/rss.rb index b079661ec0..b1e1b55e4e 100644 --- a/lib/rss/rss.rb +++ b/lib/rss/rss.rb @@ -87,10 +87,10 @@ module RSS end class NotExpectedTagError < InvalidRSSError - attr_reader :tag, :parent - def initialize(tag, parent) - @tag, @parent = tag, parent - super("tag <#{tag}> is not expected in tag <#{parent}>") + attr_reader :tag, :uri, :parent + def initialize(tag, uri, parent) + @tag, @uri, @parent = tag, uri, parent + super("tag <{#{uri}}#{tag}> is not expected in tag <#{parent}>") end end # For backward compatibility :X @@ -585,14 +585,14 @@ EOC end end - def validate + def validate(ignore_unknown_element=true) validate_attribute - __validate + __validate(ignore_unknown_element) end - def validate_for_stream(tags) + def validate_for_stream(tags, ignore_unknown_element=true) validate_attribute - __validate(tags, false) + __validate(ignore_unknown_element, tags, false) end def setup_maker(maker) @@ -744,7 +744,7 @@ EOC [] end - def __validate(tags=_tags, recursive=true) + def __validate(ignore_unknown_element, tags=_tags, recursive=true) if recursive children.compact.each do |child| child.validate @@ -756,11 +756,13 @@ EOC self.class::NSPOOL.each do |prefix, uri| if tags.has_key?(uri) and !must_call_validators.has_key?(uri) meth = "#{prefix}_validate" - __send__(meth, tags[uri]) if respond_to?(meth, true) + if respond_to?(meth, true) + __send__(meth, ignore_unknown_element, tags[uri], uri) + end end end must_call_validators.each do |uri, prefix| - __send__("#{prefix}_validate", tags[uri]) + __send__("#{prefix}_validate", ignore_unknown_element, tags[uri], uri) end end @@ -784,7 +786,7 @@ EOC rv.join("\n") end - def _validate(tags, model=self.class.model) + def _validate(ignore_unknown_element, tags, uri, model=self.class.model) count = 1 do_redo = false not_shift = false @@ -869,8 +871,8 @@ EOC end - if !tags.nil? and !tags.empty? - raise NotExpectedTagError.new(tag, tag_name) + if !ignore_unknown_element and !tags.nil? and !tags.empty? + raise NotExpectedTagError.new(tags.first, uri, tag_name) end end diff --git a/lib/rss/syndication.rb b/lib/rss/syndication.rb index 8791ec24fc..fc93d03832 100644 --- a/lib/rss/syndication.rb +++ b/lib/rss/syndication.rb @@ -38,7 +38,7 @@ module RSS EOC end - def sy_validate(tags) + def sy_validate(ignore_unknown_element, tags, uri) counter = {} ELEMENTS.each do |name| counter[name] = 0 @@ -46,7 +46,9 @@ module RSS tags.each do |tag| key = "#{SY_PREFIX}_#{tag}" - raise UnknownTagError.new(tag, SY_URI) unless counter.has_key?(key) + if ignore_unknown_element and !counter.has_key?(key) + raise UnknownTagError.new(tag, SY_URI) + end counter[key] += 1 raise TooMuchTagError.new(tag, tag_name) if counter[key] > 1 end diff --git a/lib/rss/taxonomy.rb b/lib/rss/taxonomy.rb index 93eeac7b98..5b7d33821d 100644 --- a/lib/rss/taxonomy.rb +++ b/lib/rss/taxonomy.rb @@ -32,7 +32,7 @@ module RSS klass.install_have_child_element(var_name) end - def taxo_validate(tags) + def taxo_validate(ignore_unknown_element, tags, uri) found_topics = false tags.each do |tag| if tag == "topics" @@ -41,7 +41,7 @@ module RSS else found_topics = true end - else + elsif !ignore_unknown_element raise UnknownTagError.new(tag, TAXO_URI) end end @@ -111,8 +111,8 @@ module RSS rv end - def rdf_validate(tags) - _validate(tags, [["Bag", nil]]) + def rdf_validate(ignore_unknown_element, tags, uri) + _validate(ignore_unknown_element, tags, uri, [["Bag", nil]]) end end end @@ -126,9 +126,9 @@ module RSS klass.install_have_children_element(var_name) end - def taxo_validate(tags) + def taxo_validate(ignore_unknown_element, tags, uri) tags.each do |tag| - if tag != "topic" + if !ignore_unknown_element and tag != "topic" raise UnknownTagError.new(tag, TAXO_URI) end end @@ -172,7 +172,7 @@ module RSS end end - def taxo_validate(tags) + def taxo_validate(ignore_unknown_element, tags, uri) elements = %w(link topics) counter = {} @@ -181,7 +181,7 @@ module RSS counter[tag] ||= 0 counter[tag] += 1 raise TooMuchTagError.new(tag, tag_name) if counter[tag] > 1 - else + elsif !ignore_unknown_element raise UnknownTagError.new(tag, TAXO_URI) end end diff --git a/lib/rss/trackback.rb b/lib/rss/trackback.rb index befeea1590..d782925c0b 100644 --- a/lib/rss/trackback.rb +++ b/lib/rss/trackback.rb @@ -11,7 +11,7 @@ module RSS module TrackBackUtils private - def trackback_validate(tags) + def trackback_validate(ignore_unknown_element, tags, uri) counter = {} %w(ping about).each do |name| counter["#{TRACKBACK_PREFIX}_#{name}"] = 0 @@ -19,7 +19,9 @@ module RSS tags.each do |tag| key = "#{TRACKBACK_PREFIX}_#{tag}" - raise UnknownTagError.new(tag, TRACKBACK_URI) unless counter.has_key?(key) + if !ignore_unknown_element and !counter.has_key?(key) + raise UnknownTagError.new(tag, TRACKBACK_URI) + end counter[key] += 1 if tag != "about" and counter[key] > 1 raise TooMuchTagError.new(tag, tag_name) diff --git a/test/rss/rss-assertions.rb b/test/rss/rss-assertions.rb index fc2cd3cbed..1e926bb84d 100644 --- a/test/rss/rss-assertions.rb +++ b/test/rss/rss-assertions.rb @@ -71,13 +71,14 @@ module RSS end end - def assert_not_expected_tag(tag, parent) + def assert_not_expected_tag(tag, uri, parent) _wrap_assertion do begin yield flunk("Not raise NotExpectedTagError") rescue ::RSS::NotExpectedTagError => e assert_equal(tag, e.tag) + assert_equal(uri, e.uri) assert_equal(parent, e.parent) end end diff --git a/test/rss/test_parser.rb b/test/rss/test_parser.rb index 47bbc2d9d9..f204b88933 100644 --- a/test/rss/test_parser.rb +++ b/test/rss/test_parser.rb @@ -603,19 +603,64 @@ EOR end def test_ignore - + name = "a" rss = make_RDF(<<-EOR) #{make_channel} #{make_item} -<a/> +<#{name}/> EOR + assert_not_expected_tag(name, ::RSS::URI, "RDF") do + Parser.parse(rss, true, false) + end + uri = "" + name = "a" + rss = make_RDF(<<-EOR) +#{make_channel} +#{make_item} +<#{name} xmlns=""/> +EOR assert_parse(rss, :nothing_raised) + assert_not_expected_tag(name, uri, "RDF") do + Parser.parse(rss, true, false) + end - assert_not_expected_tag("a", "RDF") do + uri = "http://example.com/" + name = "a" + rss = make_RDF(<<-EOR) +#{make_channel} +#{make_item} +<x:#{name} xmlns:x="#{uri}"/> +EOR + assert_parse(rss, :nothing_raised) + assert_not_expected_tag(name, uri, "RDF") do Parser.parse(rss, true, false) end + uri = ::RSS::URI + name = "a" + rss = make_RDF(<<-EOR) +#{make_channel} +#{make_item} +#{make_image("<#{name}/>")} +EOR + assert_parse(rss, :nothing_raised) + assert_not_expected_tag(name, uri, "image") do + Parser.parse(rss, true, false) + end + + uri = CONTENT_URI + name = "encoded" + elem = "<#{name} xmlns='#{uri}'/>" + rss = make_RDF(<<-EOR) +#{make_channel} +#{make_item} +#{make_image(elem)} +EOR + assert_parse(rss, :nothing_raised) + assert_not_expected_tag(name, uri, "image") do + Parser.parse(rss, true, false) + end end def test_default_parser |