[ruby-dev:31851] Re: huge `if' dumps core

From: Nobuyoshi Nakada <nobu@...>
Date: 2007-09-24 18:12:12 UTC
List: ruby-dev #31851
なかだです。

At Tue, 25 Sep 2007 02:24:48 +0900,
Yusuke ENDOH wrote in [ruby-dev:31848]:
> 以下のようにすると 1.8 、1.9 共に落ちます。
> 
> 
> $ ./ruby -ve 'eval("if false then;" + "elsif false then;" * 1000000 + "end")'
> ruby 1.8.6 (2007-09-23 patchlevel 5000) [i686-linux]
> セグメンテーション違反です
> 
> $ ./ruby -ve 'eval("if false then;" + "elsif false then;" * 1000000 + "end")'
> ruby 1.9.0 (2007-09-24 patchlevel 0) [i686-linux]
> セグメンテーション違反です
> 
> 
> ALLOCA_N が原因のようです。

さすがに、1MBを越えるエラーメッセージが出てくれてもあまりうれし
くないのでは。


Index: parse.y
===================================================================
--- parse.y	(リビジョン 13509)
+++ parse.y	(作業コピー)
@@ -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


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread