REXML (1.8.6-p110) backwards compatibility problem with rcov

B

Brian Candler

When I upgraded my Ubuntu 6.06.1 system from its stock ruby-1.8.4 to
ruby-1.8.6-p110, I found that the previously working rcov-0.8.0.2 was
raising REXML exceptions when it tried to generate its output (*)

I needed to make a couple of patches to REXML to fix this. The first patch
is because rcov passes Fixnums as attribute values, e.g.

table_:)cellpadding => 0, :cellspacing => 0, :align => "right")

This could have been fixed at the rcov side, but since it *did* used to work
with rexml, I consider this a backwards-compatibility failure. The fix is
trivial:

--- rexml/text.rb.orig 2007-10-22 08:00:04.000000000 +0100
+++ rexml/text.rb 2007-10-22 08:00:33.000000000 +0100
@@ -286,7 +286,7 @@
EREFERENCE = /&(?!#{Entity::NAME};)/
# Escapes all possible entities
def Text::normalize( input, doctype=nil, entity_filter=nil )
- copy = input
+ copy = input.to_s
# Doing it like this rather than in a loop improves the speed
#copy = copy.gsub( EREFERENCE, '&' )
copy = copy.gsub( "&", "&" )

(Note that there are other places in this file which might benefit from a
to_s as well)

The second is almost certainly a bug in REXML: it's a misnamed local
variable.

--- rexml/document.rb.orig 2007-10-22 08:02:36.000000000 +0100
+++ rexml/document.rb 2007-10-22 08:03:01.000000000 +0100
@@ -183,7 +183,7 @@
output = Output.new( output, xml_decl.encoding )
end
formatter = if indent > -1
- if transitive
+ if trans
REXML::Formatters::Transitive.new( indent, ie_hack )
else
REXML::Formatters::pretty.new( indent, ie_hack )

After these changes, rcov seems to run happily.

I wasn't sure where best to post this problem and its solution: ruby-core
(since REXML is in the ruby standard library), the REXML home site, or the
rcov home site. So I'm posting it here instead :)

Regards,

Brian.

(*) The exception I saw initially was:

/usr/local/lib/ruby/1.8/rexml/text.rb:292:in `normalize': private method `gsub' called for 0:Fixnum (NoMethodError)
from /usr/local/lib/ruby/1.8/rexml/element.rb:1084:in `[]='
from /usr/local/lib/ruby/1.8/rexml/element.rb:586:in `add_attribute'
from (eval):490:in `table_'
from (eval):490:in `each'
from (eval):490:in `table_'
from (eval):490:in `each'
from (eval):490:in `table_'
from /usr/local/lib/ruby/gems/1.8/gems/rcov-0.8.0.2/lib/rcov/report.rb:702:in `format_overview'
... 61 levels...

After I fixed this by adding to_s in Text::normalize, I got

/usr/local/lib/ruby/1.8/rexml/document.rb:186:in `write': undefined local variable or method `transitive' for <UNDEFINED> ... </>:REXML::Document (NameError)
from (eval):93:in `pretty'
from /usr/local/lib/ruby/gems/1.8/gems/rcov-0.8.0.2/lib/rcov/report.rb:727:in `format_overview'
from /usr/local/lib/ruby/gems/1.8/gems/rcov-0.8.0.2/lib/rcov/report.rb:758:in `create_index'
from (eval):104:in `create'
from (eval):80:in `tracking_additions'
from (eval):103:in `create'
from (eval):372:in `x_'
from /usr/local/lib/ruby/gems/1.8/gems/rcov-0.8.0.2/lib/rcov/report.rb:758:in `create_index'
... 21 levels...
 
S

Sean Hussey

Nice catch!

After applying both fixes, I now get this:

/usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `[]': no
implicit conversion from nil to integer (TypeError)
from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `wrap'
from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `wrap'
from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:90:in
`write_text'
from /usr/local/lib/ruby/1.8/rexml/formatters/default.rb:50:in `write'
from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:75:in
`write_element'
from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:73:in `each'
from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:73:in
`write_element'
from /usr/local/lib/ruby/1.8/rexml/formatters/default.rb:31:in `write'
... 16 levels...

rcov outputs the index.html file and the first few controller files,
so I can trace it to which file it's getting choked on, but were there
any other fixes you had to put in?

Thanks,

Sean
 
D

dlawlor

Ive also applied both fixes and Im seeing exactly the same problem.
Any updates on this?

/usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `[]': no
implicit conversion from nil to integer (TypeError)
from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `wrap'
from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `wrap'
from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:90:in
`write_text'
from /usr/local/lib/ruby/1.8/rexml/formatters/default.rb:50:in `write'
from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:75:in
`write_element'
from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:73:in `each'
from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:73:in
`write_element'
from /usr/local/lib/ruby/1.8/rexml/formatters/default.rb:31:in `write'
... 16 levels...

Thanks,

Nice catch!

After applying both fixes, I now get this:

/usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `[]': no
implicit conversion from nil to integer (TypeError)
from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `wrap'
from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `wrap'
from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:90:in
`write_text'
from /usr/local/lib/ruby/1.8/rexml/formatters/default.rb:50:in `write'
from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:75:in
`write_element'
from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:73:in `each'
from /usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:73:in
`write_element'
from /usr/local/lib/ruby/1.8/rexml/formatters/default.rb:31:in `write'
... 16 levels...

rcov outputs the index.html file and the first few controller files,
so I can trace it to which file it's getting choked on, but were there
any other fixes you had to put in?

Thanks,

Sean

Oh, I see there's a fix for this in trunk already, committed 9 days ago:
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/rexml/document....
(but I don't think it has been merged to branches/ruby_1_8_6)
I can't see a fix for Fixnum attribute values though.

Brian.
 
M

mbbx6spp

I got these string of errors in the order reported also. I solved this
by editing the following files:

...prefix.../ruby/gems/1.8/gems/rspec-1.0.8/lib/spec/rake/verify_rcov.rb
...prefix.../ruby/1.8/rexml/formatters/pretty.rb

Plus the files already patched by this point. It seems like if your
stack trace says formatters/default.rb instead of formatters/pretty.rb
then that is the file you need to patch.

My formatters/pretty.rb patch looks like the following:
place = string.rindex(' ', width) || width # Position in string with last ' ' before cutoff
< place = string.rindex(' ', width) # Position in string with last ' '
before cutoff

My rake/verify_rcov.rb patch looks like:
if line =~ /<tt class='coverage_total'> (\d+\.\d+)% <\/tt> &nbsp; <\/td>/
< if line =~ /<tt.*?>(\d+\.\d+)%<\/tt>&nbsp;<\/td>/

Hope that helps someone,
Susan
Ive also applied both fixes and Im seeing exactly the same problem.
Any updates on this?

/usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `[]': no
`write_element'
from /usr/local/lib/ruby/1.8/rexml/formatters/default.rb:31:in `write'
... 16 levels...

Thanks,
 
J

Jim Flanagan

Thanks Susan.

For the record, I'm running "rake test:functionals" on a Rails 2.1
project using:

ruby 1.8.7-p22 from Macports 1.600 on OS X (Tiger)
rcov 0.8.1.2.0

and getting the error:
/opt/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `[]': no
implicit conversion from nil to integer (TypeError)

until I applied the patch below to pretty.rb
 
J

Jeff Mr

S. Potter said:
I got these string of errors in the order reported also. I solved this
by editing the following files:

...prefix.../ruby/gems/1.8/gems/rspec-1.0.8/lib/spec/rake/verify_rcov.rb
...prefix.../ruby/1.8/rexml/formatters/pretty.rb

Plus the files already patched by this point. It seems like if your
stack trace says formatters/default.rb instead of formatters/pretty.rb
then that is the file you need to patch.

My formatters/pretty.rb patch looks like the following:
place = string.rindex(' ', width) || width # Position in string with last ' ' before cutoff
< place = string.rindex(' ', width) # Position in string with last ' '
before cutoff

My rake/verify_rcov.rb patch looks like:
if line =~ /<tt class='coverage_total'> (\d+\.\d+)% <\/tt> &nbsp; <\/td>/
< if line =~ /<tt.*?>(\d+\.\d+)%<\/tt>&nbsp;<\/td>/

Hope that helps someone,
Susan
Ive also applied both fixes and Im seeing exactly the same problem.
Any updates on this?

/usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `[]': no
`write_element'
from /usr/local/lib/ruby/1.8/rexml/formatters/default.rb:31:in `write'
... 16 levels...

Thanks,

I have done all the fixes except for the fix to:
...prefix.../ruby/gems/1.8/gems/rspec-1.0.8/lib/spec/rake/verify_rcov.rb


Cant find the right file to modify to try that fix...

After doing the fix to:
...prefix.../ruby/1.8/rexml/formatters/pretty.rb
I am now getting this for an error:
572 tests, 115117 assertions, 0 failures, 0 errors
/usr/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `wrap': stack level
too deep (SystemStackError)
from /usr/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `wrap'
from /usr/lib/ruby/1.8/rexml/formatters/pretty.rb:90:in `write_text'
from /usr/lib/ruby/1.8/rexml/formatters/default.rb:50:in `write'
from /usr/lib/ruby/1.8/rexml/formatters/pretty.rb:75:in
`write_element'
from /usr/lib/ruby/1.8/rexml/formatters/pretty.rb:73:in `each'
from /usr/lib/ruby/1.8/rexml/formatters/pretty.rb:73:in
`write_element'
from /usr/lib/ruby/1.8/rexml/formatters/default.rb:31:in `write'
from /usr/lib/ruby/1.8/rexml/formatters/pretty.rb:75:in
`write_element'
... 12 levels...
from /usr/lib/ruby/1.8/rcov.rb:628:in `each'
from /usr/lib/ruby/1.8/rcov.rb:628:in `dump_coverage_info'
from /usr/bin/rcov:405
from /usr/lib/ruby/1.8/test/unit.rb:278


Any suggestions or help you guys can give me?
 
R

Roy Truelove

Sean said:
Nice catch!

After applying both fixes, I now get this:

/usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `[]': no
implicit conversion from nil to integer (TypeError)

Hey Sean, it looks like the rexml code is assuming that there'll be a '
' somewhere in the code to wrap on. I was able to fix this with the
following patch to the pretty.rb file :

--- /opt/ruby-1.8.7-p72/lib/ruby/1.8/rexml/formatters/pretty.rb.OLD
2009-02-15 14:47:32.000000000 -0600
+++ /opt/ruby-1.8.7-p72/lib/ruby/1.8/rexml/formatters/pretty.rb
2009-02-15 14:48:50.000000000 -0600
@@ -126,10 +126,11 @@

def wrap(string, width)
# Recursively wrap string at width.
return string if string.length <= width
place = string.rindex(' ', width) # Position in string with
last ' ' before cutoff
+ return string if place.nil? # there aren't any ' 's before
cutoff, nothing to split on.
return string[0,place] + "\n" + wrap(string[place+1..-1],
width)
end

end
end
 
J

John Doxey

Roy said:
Sean said:
Nice catch!

After applying both fixes, I now get this:

/usr/local/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in `[]': no
implicit conversion from nil to integer (TypeError)

Hey Sean, it looks like the rexml code is assuming that there'll be a '
' somewhere in the code to wrap on. I was able to fix this with the
following patch to the pretty.rb file :

--- /opt/ruby-1.8.7-p72/lib/ruby/1.8/rexml/formatters/pretty.rb.OLD
2009-02-15 14:47:32.000000000 -0600
+++ /opt/ruby-1.8.7-p72/lib/ruby/1.8/rexml/formatters/pretty.rb
2009-02-15 14:48:50.000000000 -0600
@@ -126,10 +126,11 @@

def wrap(string, width)
# Recursively wrap string at width.
return string if string.length <= width
place = string.rindex(' ', width) # Position in string with
last ' ' before cutoff
+ return string if place.nil? # there aren't any ' 's before
cutoff, nothing to split on.
return string[0,place] + "\n" + wrap(string[place+1..-1],
width)
end

end
end

There might still be spaces in the string, how about,

--- pretty.rb.old 2009-05-06 10:50:37.000000000 +1000
+++ pretty.rb 2009-05-06 10:55:37.000000000 +1000
@@ -128,6 +128,8 @@
# Recursively wrap string at width.
return string if string.length <= width
place = string.rindex(' ', width) # Position in string with
last ' ' before cutoff
+ place = string.index(' ') if place.nil?
+ return string if place.nil? # there aren't any ' 's before
cutoff, nothing to split on.
return string[0,place] + "\n" + wrap(string[place+1..-1],
width)
end
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top