[#8815] Segfault in libc strlen, via rb_str_new2 — "Sean E. Russell" <ser@...>

Howdy,

12 messages 2006/09/09
[#8817] Re: Segfault in libc strlen, via rb_str_new2 — Eric Hodel <drbrain@...7.net> 2006/09/09

On Sep 8, 2006, at 10:10 PM, Sean E. Russell wrote:

abort trap on pure ruby (1.8.x--yesterday's cvs)

From: Ryan Davis <ryand-ruby@...>
Date: 2006-09-29 22:21:37 UTC
List: ruby-core #8963
I get the following error from the code below. Doesn't repro in gdb  
at all:

% ./box_parse.rb
./box_parse.rb:95: warning: ambiguous first argument; put parentheses  
or even spaces
Loaded suite ./box_parse
Started
EFEEE..EFE
Finished in 0.016785 seconds.

/usr/local/lib/ruby/1.8/test/unit/util/backtracefilter.rb:17: [BUG]  
rb_gc_mark(): unknown data type 0x1b(0x435530) non object
ruby 1.8.5 (2006-09-29) [i686-darwin8.7.1]

Abort trap

-----

#!/usr/local/bin/ruby -w

require 'set'

class Box
   attr_accessor :x, :y, :right, :bottom
   def initialize(x, y, right, bottom)
     @x, @y, @right, @bottom = x, y, right, bottom
   end
end

module BoxParser
   def box_x_delimeters(boxes)
     boxes.map { |box| box.right }.uniq.sort
   end

   def box_y_delimeters(boxes)
     boxes.map { |box| box.bottom }.uniq.sort
   end

   def box_rowspans(boxes)
     colspans = Hash.new(0)
     boxes.each do |box| colspans[box] end

     box_y_delimeters(boxes).each do |delim|
       boxes.each do |box|
         rowspans[box] += 1 if box.y < delim and box.bottom >= delim
       end
     end

     rowspans
   end

   def box_colspans(boxes)
     colspans = Hash.new(0)
     boxes.each do |box| colspans[box] end

     box_y_delimeters(boxes).each do |delim|
       boxes.each do |box|
         colspans[box] += 1 if box.x < delim and box.right >= delim
       end
     end

     colspans
   end

   def box_rows(boxes)
     rows, boxes_left = [], boxes.uniq
     box_y_delimeters(boxes).each do |box|
       boxes_in_row = boxes_left.find_all { |box| box.y < delim }
       boxes_left -= boxes_in_row
       rows.push(*boxes_in_row.map { |box| box.x}.sort)
     end
     rows
   end

   # Rendering and parsing tables.

   def render_html_table(boxes)
     rowspans, colspans = box_rowspans(boxes), box_colspans(boxes)
     table = '<table border="border">\n'
     box_rows(boxes).each do |row|
       table += '  <tr>\n'
       row.each do |box|
         table += "    <td rowspan=\"%d\" colspan=\"%d\">%s</td>\n" %  
[rowspans[box], colspans[box], 'blank<br/>' * (box.bottom - box.y)]
       end
       table += '  </tr>\n'
     end
     table += '</table>\n'
     table
   end

   def char(grid, x, y)
     return grid[y][x] if 0 <= y and y < grid.size and 0 <= x and x <  
grid[y].size
     return " "
   end

   def box_right(x, y)
     # todo: find
     (x..grid[y+1].size).each do |right|
       return right if char(grid, right + 1, y + 1) == '|'
     end
     raise RuntimeError("Unterminated box.")
   end

   def box_bottom(x, y)
     # todo: find
     (y..grid.size).each do |bottom|
       return bottom if char(grid, x + 1, bottom + 1) == '-'
     end
     raise RuntimeError("Unterminated box.")
   end

   def parse_ascii_table(table)
     grid = table.split /\n/
     boxes = []

     grid.size.times do |y|
       grid[y].size.times do |x|
         if %w(- |).include? char(grid, x, y) and
             char(grid, x, y + 1) == '|' and
             char(grid, x + 1, y) == '-' then
           boxes << Box.new(x, y, box_right(x, y), box_bottom(x, y))
         end
       end
     end
     return boxes
   end
end

include BoxParser

require 'test/unit/testcase'
require 'test/unit' if __FILE__ == $0
class TestBoxParser < Test::Unit::TestCase

   #   +---+---+
   #   |   |   |
   #   +---+---+
   #   |       |
   #   +---+---+
   def setup
     @boxes = []
     @boxes << Box.new(0, 0, 4, 2)
     @boxes << Box.new(4, 0, 8, 2)
     @boxes << Box.new(0, 2, 8, 4)
   end

   def test_box_bottom
     assert_equal :foo, box_bottom(@boxes)
   end

   def test_box_colspans
     assert_equal :foo, box_colspans(@boxes)
   end

   def test_box_right
     assert_equal :foo, box_right(@boxes)
   end

   def test_box_rows
     assert_equal :foo, box_rows(@boxes)
   end

   def test_box_rowspans
     assert_equal :foo, box_rowspans(@boxes)
   end

   def test_box_x_delimeters
     assert_equal [4, 8], box_x_delimeters(@boxes)
   end

   def test_box_y_delimeters
     assert_equal [2, 4], box_y_delimeters(@boxes)
   end

   def test_char
     assert_equal :foo, char(@boxes)
   end

   def test_render_html_table
#     html = render_html_table(boxes)
#     assert_equal :blah, html
     assert_equal :foo, :blah, html(@boxes)
   end

   def test_parse_ascii_table
     table = "
---------------------------
|         |       |       |
|         |       |       |
|         |       |       |
|         |-------|       |
|         |       |       |
|         |       |-------|
|         |       |       |
|         |       |       |
|---------|       |-------|
|    |    |       |       |
|    |    |-------|       |
|    |    |       |       |
|    |    |       |       |
|    |    |       |       |
---------------------------
"

     boxes = parse_ascii_table(table)
     assert_equal :blah, boxes

   end
end


In This Thread

Prev Next