ruby-rdf / rdf-turtle

Turtle reader/writer for Ruby
http://rubygems.org/gems/rdf-turtle
The Unlicense
31 stars 9 forks source link

Nil pointer in Turtle::Writer#preprocess_statement #11

Closed jcoyne closed 9 years ago

jcoyne commented 10 years ago
g = RDF::Graph.new
g.insert([RDF::URI.new('http://example.com/x'), RDF::DC.title, nil])
g.dump(:ttl)

NoMethodError: undefined method `literal?' for nil:NilClass
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-turtle-1.1.4/lib/rdf/turtle/writer.rb:378:in `preprocess_statement'
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-turtle-1.1.4/lib/rdf/turtle/writer.rb:359:in `block in preprocess'
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-1.1.4.2/lib/rdf/repository.rb:341:in `call'
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-1.1.4.2/lib/rdf/repository.rb:341:in `block (4 levels) in query_pattern'
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-1.1.4.2/lib/rdf/repository.rb:339:in `each'
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-1.1.4.2/lib/rdf/repository.rb:339:in `block (3 levels) in query_pattern'
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-1.1.4.2/lib/rdf/repository.rb:336:in `each'
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-1.1.4.2/lib/rdf/repository.rb:336:in `block (2 levels) in query_pattern'
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-1.1.4.2/lib/rdf/repository.rb:333:in `each'
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-1.1.4.2/lib/rdf/repository.rb:333:in `block in query_pattern'
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-1.1.4.2/lib/rdf/repository.rb:330:in `each'
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-1.1.4.2/lib/rdf/repository.rb:330:in `query_pattern'
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-1.1.4.2/lib/rdf/mixin/queryable.rb:83:in `query'
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-1.1.4.2/lib/rdf/model/graph.rb:248:in `each'
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-turtle-1.1.4/lib/rdf/turtle/writer.rb:359:in `preprocess'
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-turtle-1.1.4/lib/rdf/turtle/writer.rb:161:in `write_epilogue'
... 5 levels...
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-1.1.4.2/lib/rdf/writer.rb:150:in `buffer'
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-1.1.4.2/lib/rdf/writer.rb:130:in `dump'
    from /Users/justin/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/rdf-1.1.4.2/lib/rdf/mixin/enumerable.rb:678:in `dump'
    from (irb):5
jcoyne commented 10 years ago

I'm not certain how you want to handle this @gkellogg. Should we just strip statements with a nil object in preprocess_statement? Or should that raise an exception when you do an insert?

gkellogg commented 10 years ago

It should already raise an error if the :validate option is set. Handling this in rdf.rb Writable#insert is probably of greater benefit. In general, I think bad data should just be dropped. Rdf-turtle can probably issue a warning. Validate mode is the way to ensure that such invalid data is identified.

Thanks for handling this. Just pushed out a patch release of rdf.rb, could push out a minor release for this.

jcoyne commented 10 years ago

@gkellogg it seems that fixing Writable would require changing this spec (https://github.com/ruby-rdf/rdf-spec/blob/develop/lib/rdf/spec/writable.rb#L65-L71) are you okay with that?

gkellogg commented 10 years ago

It should be okay to add an invalid statement, but statements containing nil elements are somewhat difference. This could be changed to something like the following:

  it "inserts an invalid statement" do
    skip("writability") unless subject.writable?
    s = statement.clone
    s.object = RDF::Literal("non-bool", datatype: RDF::XSD.boolean)
    expect(s).not_to  be_valid
    subject << s
    expect(subject.count).to eq 1
  end

We might want to consider statements with nil members incomplete, in addition to being invalid. Note that a Query::Pattern subclasses Statement, and it's okay for Pattern elements to be nil.

gkellogg commented 9 years ago

Fixed in ruby-rdf/rdf/issues#226; incomplete statements always raise an error now, not just when validating.

jcoyne commented 9 years ago

Cool!