Huge `if' dumps core

e$B1sF#$H?=$7$^$9!#e(B

e$B0J2<$N$h$&$K$9$k$He(B 1.8 e$B!"e(B1.9 e$B6&$KMn$A$^$9!#e(B

$ ./ruby -ve ‘eval(“if false then;” + “elsif false then;” * 1000000 +
“end”)’
ruby 1.8.6 (2007-09-23 patchlevel 5000) [i686-linux]
e$B%;%0%a%s%F!<%7%g%s0cH?$G$9e(B

$ ./ruby -ve ‘eval(“if false then;” + “elsif false then;” * 1000000 +
“end”)’
ruby 1.9.0 (2007-09-24 patchlevel 0) [i686-linux]
e$B%;%0%a%s%F!<%7%g%s0cH?$G$9e(B

ALLOCA_N e$B$,860x$N$h$&$G$9!#e(B

Index: parse.y

— parse.y (revision 13509)
+++ parse.y (working copy)
@@ -4593,7 +4593,7 @@
len = pe - p;
if (len > 4) {
char *p2;

  • buf = ALLOCA_N(char, len+2);
  • buf = ALLOC_N(char, len+2);
    MEMCPY(buf, p, char, len);
    buf[len] = ‘\0’;
    rb_compile_error_append("%s", buf);
    @@ -4608,6 +4608,7 @@
    buf[i] = ‘^’;
    buf[i+1] = ‘\0’;
    rb_compile_error_append("%s", buf);
  • free(buf);
    }
    #else
    dispatch1(parse_error, STR_NEW2(msg));

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

At Tue, 25 Sep 2007 02:24:48 +0900,
Yusuke ENDOH wrote in [ruby-dev:31848]:

ALLOCA_N e$B$,860x$N$h$&$G$9!#e(B

e$B$5$9$,$K!“e(B1MBe$B$r1[$($k%(%i!<%a%C%;!<%8$,=P$F$/$l$F$b$”$^$j$&$l$7e(B
e$B$/$J$$$N$G$O!#e(B

Index: parse.y

— parse.y (e$B%j%S%8%g%se(B 13509)
+++ parse.y (e$B:n6H%3%T!<e(B)
@@ -4573,4 +4573,5 @@ parser_yyerror(struct parser_params *par
{
#ifndef RIPPER

  • const int max_line_margin = 30;
    const char *p, *pe;
    char *buf;
    @@ -4594,8 +4595,21 @@ parser_yyerror(struct parser_params *par
    if (len > 4) {
    char *p2;
  • const char *pre = “”, *post = “”;
  • if (len > max_line_margin * 2 + 10) {
  •  if (lex_p - p > max_line_margin) {
    
  • p = rb_enc_prev_char(p, lex_p - max_line_margin,
    rb_enc_get(lex_lastline));
  • pre = “…”;
  •  }
    
  •  if (pe - lex_p > max_line_margin) {
    
  • pe = rb_enc_prev_char(lex_p, lex_p + max_line_margin,
    rb_enc_get(lex_lastline));
  • post = “…”;
  •  }
    
  •  len = pe - p;
    
  • }
    buf = ALLOCA_N(char, len+2);
    MEMCPY(buf, p, char, len);
    buf[len] = ‘\0’;
  • rb_compile_error_append("%s", buf);
  • rb_compile_error_append("%s%s%s", pre, buf, post);

    i = lex_p - p;
    @@ -4608,5 +4622,5 @@ parser_yyerror(struct parser_params *par
    buf[i] = ‘^’;
    buf[i+1] = ‘\0’;

  • rb_compile_error_append("%s", buf);
  • rb_compile_error_append("%s%s", pre, buf);
    }
    #else

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

In message “Re: [ruby-dev:31851] Re: huge `if’ dumps core”
on Tue, 25 Sep 2007 03:12:12 +0900, Nobuyoshi N.
[email protected] writes:

|At Tue, 25 Sep 2007 02:24:48 +0900,
|Yusuke ENDOH wrote in [ruby-dev:31848]:
|> e$B0J2<$N$h$&$K$9$k$He(B 1.8 e$B!"e(B1.9 e$B6&$KMn$A$^$9!#e(B

|> ALLOCA_N e$B$,860x$N$h$&$G$9!#e(B
|
|e$B$5$9$,$K!“e(B1MBe$B$r1[$($k%(%i!<%a%C%;!<%8$,=P$F$/$l$F$b$”$^$j$&$l$7e(B
|e$B$/$J$$$N$G$O!#e(B

e$B$G$7$g$&$M!#$J$+$@$5$s$N%Q%C%A$r%3%_%C%H$7$F$/$@$5$$$^$;$s$+!)e(B

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

In message “Re: [ruby-dev:31862] Re: huge `if’ dumps core”
on Wed, 26 Sep 2007 04:16:16 +0900, Nobuyoshi N.
[email protected] writes:

|1.8e$B$N$[$&$O$I$&$7$^$7$g$&$+!#e(Brb_enc_prev_char()e$BAjEv$,$J$$$N$G!"e(B
|re_adjust_startpos()e$B$+$iN.MQ$9$k$J$i0J2<$N$h$&$J46$8$G$9!#e(B

e$B$&$`!#$8$c$“!”$3$N%Q%C%A$rEv$F$kJ}8~$G!#e(B

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

At Tue, 25 Sep 2007 21:12:42 +0900,
Yukihiro M. wrote in [ruby-dev:31855]:

|> e$B0J2<$N$h$&$K$9$k$He(B 1.8 e$B!"e(B1.9 e$B6&$KMn$A$^$9!#e(B

|> ALLOCA_N e$B$,860x$N$h$&$G$9!#e(B
|
|e$B$5$9$,$K!“e(B1MBe$B$r1[$($k%(%i!<%a%C%;!<%8$,=P$F$/$l$F$b$”$^$j$&$l$7e(B
|e$B$/$J$$$N$G$O!#e(B

e$B$G$7$g$&$M!#$J$+$@$5$s$N%Q%C%A$r%3%_%C%H$7$F$/$@$5$$$^$;$s$+!)e(B

1.8e$B$N$[$&$O$I$&$7$^$7$g$&$+!#e(Brb_enc_prev_char()e$BAjEv$,$J$$$N$G!"e(B
re_adjust_startpos()e$B$+$iN.MQ$9$k$J$i0J2<$N$h$&$J46$8$G$9!#e(B

e$B$H$$$&$+!"<j85$G$Oe(B[ruby-talk:247595]e$B$,Ev$?$C$?$^$^$@$C$?$N$G!"$=e(B
e$B$b$=$be(B"memory exhausted"e$B<+BN$,H/@8$7$J$+$C$?$N$G$9$,!#e(B

Index: parse.y

— parse.y (revision 13508)
+++ parse.y (working copy)
@@ -2517,5 +2517,7 @@ yyerror(msg)
const char *msg;
{

  • char *p, *pe, *buf;
  • const int max_line_margin = 30;
  • const char *p, *pe;
  • char *buf;
    int len, i;

@@ -2536,15 +2538,30 @@ yyerror(msg)
len = pe - p;
if (len > 4) {

  • char *p2;
  • const char *pre = “”, *post = “”;
  • if (len > max_line_margin * 2 + 10) {
  •  int re_mbc_startpos _((const char *, int, int, int));
    
  •  if ((len = lex_p - p) > max_line_margin) {
    
  • p = p + re_mbc_startpos(p, len, len - max_line_margin, 0);
  • pre = “…”;
  •  }
    
  •  if ((len = pe - lex_p) > max_line_margin) {
    
  • pe = lex_p + re_mbc_startpos(lex_p, len, max_line_margin, 1);
  • post = “…”;
  •  }
    
  •  len = pe - p;
    
  • }
    buf = ALLOCA_N(char, len+2);
    MEMCPY(buf, p, char, len);
    buf[len] = ‘\0’;
  • rb_compile_error_append("%s", buf);
  • rb_compile_error_append("%s%s%s", pre, buf, post);

    i = lex_p - p;

  • p = buf; pe = p + len;
  • p2 = buf; pe = buf + len;
  • while (p < pe) {
  •  if (*p != '\t') *p = ' ';
    
  •  p++;
    
  • while (p2 < pe) {
  •  if (*p2 != '\t') *p2 = ' ';
    
  •  p2++;
    
    }
    buf[i] = ‘^’;
    Index: regex.c
    ===================================================================
    — regex.c (revision 13508)
    +++ regex.c (working copy)
    @@ -3110,4 +3110,26 @@ re_compile_fastmap(bufp)
    /* adjust startpos value to the position between characters. */
    int
    +re_mbc_startpos(string, size, startpos, range)
  • const char *string;
    
  • int size, startpos, range;
    

+{

  • int i = mbc_startpos(string, startpos);
  • if (i < startpos) {
  • if (range > 0) {
  •  startpos = i + mbclen(string[i]);
    
  • }
  • else {
  •  int len = mbclen(string[i]);
    
  •  if (i + len <= startpos)
    
  • startpos = i + len;
  •  else
    
  • startpos = i;
  • }
  • }
  • return startpos;
    +}

+int
re_adjust_startpos(bufp, string, size, startpos, range)
struct re_pattern_buffer bufp;
@@ -3122,18 +3144,5 @@ re_adjust_startpos(bufp, string, size, s
/
Adjust startpos for mbc string */
if (current_mbctype && startpos>0 &&
!(bufp->options&RE_OPTIMIZE_BMATCH)) {

  • int i = mbc_startpos(string, startpos);
  • if (i < startpos) {
  •  if (range > 0) {
    
  • startpos = i + mbclen(string[i]);
  •  }
    
  •  else {
    
  • int len = mbclen(string[i]);
  • if (i + len <= startpos)
  • startpos = i + len;
  • else
  • startpos = i;
  •  }
    
  • }
  • startpos = re_mbc_startpos(string, size, startpos, range);
    }
    return startpos;