$ gem list -r -d --sourcehttp://gems.github.com-V andreasronge-neo4j
comparison of String with 3 failed (ArgumentError)
end; Marshal.load File.read(“neo4j.gemspec”)’
286 # Load custom marshal format, re-initializing defaults as
→ 296 field_count = if spec.specification_version >
305 raise TypeError, "invalid Gem::Specification format
array[3]
commit 0e10242e2ef63addf3ac294bb2e932202fa900fc
released as 0.0.3. Updated documentation
s.bindir = “bin”
s.name = “neo4j”
require_paths.
value = spec.instance_variable_get(ivar)
result << " s.#{name} = #{value}\n"
of Gem::Specification#to_ruby which had RDoc all the way back to 0.8.11!
So if you own one of these, please delete that code!
Fortunately, I now have new things to protect gem repositories from!
(Ryan hit me for not protecting RubyGems enough)
And again, a gemspec is not something that you just dump something on.
It’s not a big truck.- Hide quoted text -
Show quoted text -
Is there a workaround to this problem, which would allow me to
obtain the name & description for gems starting with “a”.
$ ruby -rubygems -e ‘Marshal.load
Gem.inflate(File.read(“neo4j.gemspec.rz”))’
/Library/Ruby/Site/1.8/rubygems/specification.rb:296:in >': comparison of String with 3 failed (ArgumentError) from /Library/Ruby/Site/1.8/rubygems/specification.rb:296:in _load’
from -e:1:in `load’
from -e:1
Yup, still fails, heavy artillery time! Need to fake out the
Gem::Specification stuff and dump the spec:
$ ruby -e ‘module Gem; class Requirement; def marshal_load(arr) @arr =
arr; end; def inspect() @arr end; end; Version = Requirement; class
Specification; def self._load(str) p Marshal.load(str); nil end end;
end; Marshal.load File.read(“neo4j.gemspec”)’
[“1.2.0”, “2”, “andreasronge-neo4j”, 0.0.4, Wed Oct 22 15:00:00 -0700
2008, “A graph database for JRuby”, >=#Gem::Requirement:0x34c60,
So, specification_version is what’s broken with the gem. RubyGems
expects it to be a number, but we can clearly see in the above dump
that the second item is a String. The version of the gem is stored in
the fourth field, 0.0.4
Pulling down this project and looking through the history we find:
$ git log --grep=release
[…]
commit 0e10242e2ef63addf3ac294bb2e932202fa900fc
Author: Andreas R. [email protected]
Date: Mon Nov 17 23:05:26 2008 +0100
release 0.0.5, added CHANGELOG
commit 0b283793ee2c8e0689274d85f049bb8c2cf4250c
Author: andreas [email protected]
Date: Thu Oct 23 16:19:27 2008 +0200
released to rubyforge gem repository
commit 22bd9de5a5a6874ec4903af60fb5a95606f229ee
Author: andreas [email protected]
Date: Thu Oct 23 10:38:33 2008 +0200
prepare for rubyforge release of gem. Added license file
commit 715e4384f0cc34a56580c2c52054e2756c5d06ac
Author: andreas [email protected]
Date: Mon Oct 20 12:13:00 2008 +0200
released as 0.0.3. Updated documentation
So it looks like 0b283793ee2c8e0689274d85f049bb8c2cf4250c is release
0.0.4.
$ git checkout 0b283793
$ cat neo4j.gemspec
WARNING : RAKE AUTO-GENERATED FILE. DO NOT MANUALLY EDIT!
LAST UPDATED : Thu Oct 23 15:05:22 +0200 2008
RUN : ‘rake gem:update_gemspec’
Gem::Specification.new do |s|
s.description = “A graph database for JRuby”
s.files = [
So the gemspec has a String for specification_version. Also, why is
the date a String? It should be a Time object! It seems that this
was hand-built.
There’s a bunch of extra fields set here that RubyGems has defaults
for, like required_rubygems_version, required_ruby_version,
require_paths.
Hrm, what’s that Rake task look like?
$ cat Rakefile
[…]
Thanks to the Merb project for this code.
desc “Update Github Gemspec”
task :update_gemspec do
[…]
spec.instance_variables.each do |ivar|
value = spec.instance_variable_get(ivar)
name = ivar.split("@").last
[…]
case value
when Array
value = # ...
when String
value = # ...
else
value = value.to_s.inspect # WHAT?
end
result << " s.#{name} = #{value}\n"
end
end
result << "end"
File.open(File.join(File.dirname(__FILE__),
“#{spec.name}.gemspec”), “w”){|f
| f << result}
end
So the author of this gem isn’t entirely to blame here. What’s
especially strange is that this is an especially broken implementation
of Gem::Specification#to_ruby which had RDoc all the way back to 0.8.11!
Looking in the merb source, it seems this code was added here:
So it looks like Daniel Neighman is to blame. (He may not actually
be, since he doesn’t say where he got this code from.)
I’m not sure how this code was written without looking through
Gem::Specification, nor how the author missed
Gem::Specification#to_ruby (which is exactly what they wanted).
It appears that there are other projects infected by this code: