Segmentation fault in Float("very very long string")

e$B$3$s$P$s$O!#:XF#$H?=$7$^$9!#e(B

e$B$U$J$P$5$s$K462=$5$l$Fe(B(?)trunke$B$Ne(BFloat()e$B$r$$$8$a$F$$$?$i!“e(BSEGVe$B$K$J$C$Fe(B
e$BMn$A$^$7$?$N$GJs9p$5$;$F$$$?$@$-$^$9!#$^$?e(B1.8e$B$N:G?7HG$G$b!”<c43;w$?e(B
e$B46$8$G$d$O$jMn$A$^$9!#e(B

in trunk

$ ruby-trunk -ve ‘Float(“1”*10000)’
ruby 1.9.0 (2006-07-18) [i686-linux]
-e:1: warning: Float 111111111111111(…e$B!"L5BL$J$N$Ge(Bsnip)
-e:1: [BUG] Segmentation fault
ruby 1.9.0 (2006-07-18) [i686-linux]

e$B%"%!<%H$7$^$7$?e(B
$ gdb ruby-trunk
GNU gdb 6.3-debian
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you
are
welcome to change it and/or distribute copies of it under certain
conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB. Type “show warranty” for
details.
This GDB was configured as “i386-linux”…Using host libthread_db
library “/lib/tls/libthread_db.so.1”.

(gdb) run -e ‘Float(“1”*10000)’
Starting program: /usr/local/bin/ruby-trunk -e ‘Float(“1”*10000)’
-e:1: warning: Float 111111111111111(…e$B!"L5BL$J$N$Ge(Bsnip)

Program received signal SIGSEGV, Segmentation fault.
0x08089689 in rb_cstr_to_dbl (p=0x81528c8 ‘1’ <repeats 200 times>…,
badcheck=2) at …/object.c:2082
2082 if (*end) {
(gdb) bt
#0 0x08089689 in rb_cstr_to_dbl (p=0x81528c8 ‘1’ <repeats 200
times>…,
badcheck=2) at …/object.c:2082
#1 0x080898c3 in rb_str_to_dbl (str=1075615260, badcheck=2)
at …/object.c:2140
#2 0x08089987 in rb_Float (val=0) at …/object.c:2157
#3 0x0806c17c in call_cfunc (func=0x80899f9 <rb_f_float>,
recv=1075681820,
len=0, argc=0, argv=0xbfffedb0) at …/eval.c:5540
#4 0x0805fe30 in rb_call0 (klass=1075686360, recv=1075681820, id=3325,
oid=3325, argc=1, argv=0xbfffedb0, block=0x0, body=0x401da520,
flags=18)
at …/eval.c:5766
#5 0x080601ba in rb_call (klass=1075686360, recv=1075681820, mid=3325,
argc=1, argv=0xbfffedb0, block=0x0, scope=CALLING_FCALL, iter=0)
at …/eval.c:5970
#6 0x0805a660 in rb_eval (self=1075681820, n=0x0) at ruby.h:703
#7 0x08056629 in ruby_exec_internal () at …/eval.c:1593
#8 0x08056646 in ruby_exec () at …/eval.c:1608
#9 0x08056684 in ruby_run () at …/eval.c:1624
#10 0x080545f4 in main (argc=0, argv=0x0, envp=0xbffff8b4) at
…/main.c:43

in ruby_1_8

$ ruby-1.8 -ve ‘Float(“1”*10000)’
ruby 1.8.5 (2006-07-18) [i686-linux]
-e:1: warning: Float
-e:1: [BUG] Segmentation fault
ruby 1.8.5 (2006-07-18) [i686-linux]

e$B%"%!<%H$7$^$7$?e(B
$ gdb ruby-1.8
GNU gdb 6.3-debian
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you
are
welcome to change it and/or distribute copies of it under certain
conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB. Type “show warranty” for
details.
This GDB was configured as “i386-linux”…Using host libthread_db
library “/lib/tls/libthread_db.so.1”.

(gdb) run -e ‘Float(“1”*10000)’
Starting program: /home/tadashi/cvs/ruby-1.8/o/ruby-1.8 -e
‘Float(“1”*10000)’
-e:1: warning: Float

Program received signal SIGSEGV, Segmentation fault.
0x400afb63 in ruby_strtod (string=0x0, endPtr=0x0) at …/util.c:768
768 while (ISSPACE(*p)) p++;
(gdb) bt
#0 0x400afb63 in ruby_strtod (string=0x0, endPtr=0x0) at …/util.c:768
#1 0x40073fc9 in rb_cstr_to_dbl (p=0x807b898 “”, badcheck=2)
at …/object.c:2259
#2 0x400741de in rb_str_to_dbl (str=1076440860, badcheck=2)
at …/object.c:2300
#3 0x400742f1 in rb_Float (val=0) at …/object.c:2318
#4 0x4007436f in rb_f_float (obj=1076505080, arg=0) at …/object.c:2351
#5 0x4005221b in call_cfunc (func=0x40074350 <rb_f_float>,
recv=1076505080,
len=0, argc=1076306048, argv=0xbffff038) at …/eval.c:5653
#6 0x40044760 in rb_call0 (klass=1076509860, recv=1076505080, id=3301,
oid=0,
argc=1, argv=0xbffff038, body=0x402a34d4, flags=2) at …/eval.c:5812
#7 0x400451f6 in rb_call (klass=1076509860, recv=1076505080, mid=3301,
argc=1, argv=0xbffff038, scope=1) at …/eval.c:6042
#8 0x4003f77d in rb_eval (self=1076505080, n=0x0) at ruby.h:645
#9 0x4003b6dc in ruby_exec_internal () at …/eval.c:1606
#10 0x4003b734 in ruby_exec () at …/eval.c:1626
#11 0x4003b771 in ruby_run () at …/eval.c:1636
#12 0x080486f3 in main (argc=0, argv=0x0, envp=0xbffff894) at
…/main.c:46

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:29043] Re: Segmentation fault in Float(“very
very long string”)”
on Tue, 18 Jul 2006 01:58:58 +0900, [email protected] writes:

|At Tue, 18 Jul 2006 01:06:34 +0900,
|Tadashi S. wrote in [ruby-dev:29041]:
|> e$B$U$J$P$5$s$K462=$5$l$Fe(B(?)trunke$B$Ne(BFloat()e$B$r$$$8$a$F$$$?$i!“e(BSEGVe$B$K$J$C$Fe(B
|> e$BMn$A$^$7$?$N$GJs9p$5$;$F$$$?$@$-$^$9!#$^$?e(B1.8e$B$N:G?7HG$G$b!”<c43;w$?e(B
|> e$B46$8$G$d$O$jMn$A$^$9!#e(B
|
|e$B7Y9p$ND9$5$b@)8B$9$k$h$&$K$7$F$_$^$7$?!#e(B
|
|
|* object.c (rb_cstr_to_dbl): limit out-of-range message.
|
|* util.c (ruby_strtod): return end pointer even if ERANGE occurred.
| fixed: [ruby-dev:29041]

e$B%3%_%C%H$7$F$/$@$5$$e(B

e$B$J$+$@$G$9!#e(B

At Tue, 18 Jul 2006 01:06:34 +0900,
Tadashi S. wrote in [ruby-dev:29041]:

e$B$U$J$P$5$s$K462=$5$l$Fe(B(?)trunke$B$Ne(BFloat()e$B$r$$$8$a$F$$$?$i!“e(BSEGVe$B$K$J$C$Fe(B
e$BMn$A$^$7$?$N$GJs9p$5$;$F$$$?$@$-$^$9!#$^$?e(B1.8e$B$N:G?7HG$G$b!”<c43;w$?e(B
e$B46$8$G$d$O$jMn$A$^$9!#e(B

e$B7Y9p$ND9$5$b@)8B$9$k$h$&$K$7$F$_$^$7$?!#e(B

  • object.c (rb_cstr_to_dbl): limit out-of-range message.

  • util.c (ruby_strtod): return end pointer even if ERANGE occurred.
    fixed: [ruby-dev:29041]

Index: object.c

RCS file: /cvs/ruby/src/ruby/object.c,v
retrieving revision 1.189
diff -p -u -2 -r1.189 object.c
— object.c 28 Jun 2006 14:28:11 -0000 1.189
+++ object.c 17 Jul 2006 16:53:12 -0000
@@ -2064,4 +2064,7 @@ rb_cstr_to_dbl(const char *p, int badche
char *end;
double d;

  • const char *ellipsis = “”;

  • int w;
    +#define OutOfRange() (((w = end - p) > 20) ? (w = 20, ellipsis = “…”)
    : (ellipsis = “”))

    if (!p) return 0.0;
    @@ -2070,5 +2073,6 @@ rb_cstr_to_dbl(const char *p, int badche
    d = strtod(p, &end);
    if (errno == ERANGE) {

  • rb_warn(“Float %*s out of range”, end-p, p);
  • OutOfRange();
  • rb_warn(“Float %.*s%s out of range”, w, p, ellipsis);
    errno = 0;
    }
    @@ -2101,9 +2105,10 @@ rb_cstr_to_dbl(const char *p, int badche
    d = strtod(p, &end);
    if (errno == ERANGE) {
  •   rb_warn("Float %*s out of range", end-p, p);
    
  •   OutOfRange();
    
  •   rb_warn("Float %.*s%s out of range", w, p, ellipsis);
      errno = 0;
    
    }
    if (badcheck) {
  •   if (p == end) goto bad;
    
  •   if (!end || p == end) goto bad;
      while (*end && ISSPACE(*end)) end++;
      if (*end) goto bad;
    

@@ -2112,5 +2117,6 @@ rb_cstr_to_dbl(const char *p, int badche
if (errno == ERANGE) {
errno = 0;

  • rb_raise(rb_eArgError, “Float %s out of range”, q);
  • OutOfRange();
  • rb_raise(rb_eArgError, “Float %.*s%s out of range”, w, q, ellipsis);
    }
    return d;
    Index: util.c
    ===================================================================
    RCS file: /cvs/ruby/src/ruby/util.c,v
    retrieving revision 1.53
    diff -p -u -2 -r1.53 util.c
    — util.c 17 Jul 2006 15:43:05 -0000 1.53
    +++ util.c 17 Jul 2006 16:40:06 -0000
    @@ -875,9 +875,11 @@ ruby_strtod(
    if (exp >= MDMAXEXPT) {
    errno = ERANGE;
  •   return HUGE_VAL * (sign ? -1.0 : 1.0);
    
  •   fraction = HUGE_VAL;
    
  •   goto ret;
    
    }
    else if (exp < MDMINEXPT) {
    errno = ERANGE;
  •   return 0.0 * (sign ? -1.0 : 1.0);
    
  •   fraction = 0.0;
    
  •   goto ret;
    

    }
    fracExp = exp;
    @@ -925,4 +927,5 @@ ruby_strtod(
    }

  • ret:
    if (endPtr != NULL) {
    *endPtr = (char *)p;