ruby-changes:39041
From: usa <ko1@a...>
Date: Fri, 3 Jul 2015 18:39:51 +0900 (JST)
Subject: [ruby-changes:39041] usa:r51122 (ruby_2_1): merge revision(s) 50671: [Backport #11192]
usa 2015-07-03 18:39:18 +0900 (Fri, 03 Jul 2015) New Revision: 51122 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=51122 Log: merge revision(s) 50671: [Backport #11192] * compile.c (iseq_compile_each): out of range NTH_REF is always nil. * parse.y (parse_numvar): check overflow of NTH_REF and range. [ruby-core:69393] [Bug #11192] * util.c (ruby_scan_digits): make public and add length parameter. Modified directories: branches/ruby_2_1/ Modified files: branches/ruby_2_1/ChangeLog branches/ruby_2_1/compile.c branches/ruby_2_1/internal.h branches/ruby_2_1/parse.y branches/ruby_2_1/test/ruby/test_syntax.rb branches/ruby_2_1/util.c branches/ruby_2_1/version.h Index: ruby_2_1/ChangeLog =================================================================== --- ruby_2_1/ChangeLog (revision 51121) +++ ruby_2_1/ChangeLog (revision 51122) @@ -1,3 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/ChangeLog#L1 +Fri Jul 3 18:32:37 2015 Nobuyoshi Nakada <nobu@r...> + + * compile.c (iseq_compile_each): out of range NTH_REF is always + nil. + + * parse.y (parse_numvar): check overflow of NTH_REF and range. + [ruby-core:69393] [Bug #11192] + + * util.c (ruby_scan_digits): make public and add length parameter. + Fri Jul 3 17:53:43 2015 Nobuyoshi Nakada <nobu@r...> * vm_eval.c (rb_method_call_status): resolve refined method entry Index: ruby_2_1/compile.c =================================================================== --- ruby_2_1/compile.c (revision 51121) +++ ruby_2_1/compile.c (revision 51122) @@ -4795,6 +4795,10 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/compile.c#L4795 } case NODE_NTH_REF:{ if (!poped) { + if (!node->nd_nth) { + ADD_INSN(ret, line, putnil); + break; + } ADD_INSN2(ret, line, getspecial, INT2FIX(1) /* '~' */, INT2FIX(node->nd_nth << 1)); } Index: ruby_2_1/parse.y =================================================================== --- ruby_2_1/parse.y (revision 51121) +++ ruby_2_1/parse.y (revision 51122) @@ -6958,6 +6958,27 @@ parser_prepare(struct parser_params *par https://github.com/ruby/ruby/blob/trunk/ruby_2_1/parse.y#L6958 (ambiguous_operator(op, syn), 0))) static int +parse_numvar(struct parser_params *parser) +{ + size_t len; + int overflow; + unsigned long n = ruby_scan_digits(tok()+1, toklen()-1, 10, &len, &overflow); + const unsigned long nth_ref_max = + (FIXNUM_MAX / 2 < INT_MAX) ? FIXNUM_MAX / 2 : INT_MAX; + /* NTH_REF is left-shifted to be ORed with back-ref flag and + * turned into a Fixnum, in compile.c */ + + if (overflow || n > nth_ref_max) { + /* compile_error()? */ + rb_warnS("`%s' is too big for a number variable, always nil", tok()); + return 0; /* $0 is $PROGRAM_NAME, not NTH_REF */ + } + else { + return (int)n; + } +} + +static int parser_yylex(struct parser_params *parser) { register int c; @@ -8053,7 +8074,7 @@ parser_yylex(struct parser_params *parse https://github.com/ruby/ruby/blob/trunk/ruby_2_1/parse.y#L8074 pushback(c); if (IS_lex_state_for(last_state, EXPR_FNAME)) goto gvar; tokfix(); - set_yylval_node(NEW_NTH_REF(atoi(tok()+1))); + set_yylval_node(NEW_NTH_REF(parse_numvar(parser))); return tNTH_REF; default: Index: ruby_2_1/util.c =================================================================== --- ruby_2_1/util.c (revision 51121) +++ ruby_2_1/util.c (revision 51122) @@ -75,21 +75,25 @@ const signed char ruby_digit36_to_number https://github.com/ruby/ruby/blob/trunk/ruby_2_1/util.c#L75 /*f*/ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, }; -static unsigned long -scan_digits(const char *str, int base, size_t *retlen, int *overflow) +unsigned long +ruby_scan_digits(const char *str, ssize_t len, int base, size_t *retlen, int *overflow) { const char *start = str; unsigned long ret = 0, x; unsigned long mul_overflow = (~(unsigned long)0) / base; - int c; + *overflow = 0; - while ((c = (unsigned char)*str++) != '\0') { - int d = ruby_digit36_to_number_table[c]; + if (!len) { + *retlen = 0; + return 0; + } + + do { + int d = ruby_digit36_to_number_table[(unsigned char)*str++]; if (d == -1 || base <= d) { - *retlen = (str-1) - start; - return ret; + break; } if (mul_overflow < ret) *overflow = 1; @@ -98,7 +102,7 @@ scan_digits(const char *str, int base, s https://github.com/ruby/ruby/blob/trunk/ruby_2_1/util.c#L102 ret += d; if (ret < x) *overflow = 1; - } + } while (len < 0 || --len); *retlen = (str-1) - start; return ret; } @@ -150,7 +154,7 @@ ruby_strtoul(const char *str, char **end https://github.com/ruby/ruby/blob/trunk/ruby_2_1/util.c#L154 b = base == 0 ? 10 : base; } - ret = scan_digits(str, b, &len, &overflow); + ret = ruby_scan_digits(str, -1, b, &len, &overflow); if (0 < len) subject_found = str+len; Index: ruby_2_1/internal.h =================================================================== --- ruby_2_1/internal.h (revision 51121) +++ ruby_2_1/internal.h (revision 51122) @@ -867,6 +867,7 @@ VALUE rb_gcd_gmp(VALUE x, VALUE y); https://github.com/ruby/ruby/blob/trunk/ruby_2_1/internal.h#L867 /* util.c */ extern const signed char ruby_digit36_to_number_table[]; +extern unsigned long ruby_scan_digits(const char *str, ssize_t len, int base, size_t *retlen, int *overflow); /* variable.c */ void rb_gc_mark_global_tbl(void); Index: ruby_2_1/version.h =================================================================== --- ruby_2_1/version.h (revision 51121) +++ ruby_2_1/version.h (revision 51122) @@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_1/version.h#L1 #define RUBY_VERSION "2.1.7" #define RUBY_RELEASE_DATE "2015-07-03" -#define RUBY_PATCHLEVEL 372 +#define RUBY_PATCHLEVEL 373 #define RUBY_RELEASE_YEAR 2015 #define RUBY_RELEASE_MONTH 7 Index: ruby_2_1/test/ruby/test_syntax.rb =================================================================== --- ruby_2_1/test/ruby/test_syntax.rb (revision 51121) +++ ruby_2_1/test/ruby/test_syntax.rb (revision 51122) @@ -421,6 +421,13 @@ eom https://github.com/ruby/ruby/blob/trunk/ruby_2_1/test/ruby/test_syntax.rb#L421 assert_syntax_error('0...%w.', /unterminated string/, bug10957) end + def test_too_big_nth_ref + bug11192 = '[ruby-core:69393] [Bug #11192]' + assert_warn(/too big/, bug11192) do + eval('$99999999999999999') + end + end + private def not_label(x) @result = x; @not_label ||= nil end Property changes on: ruby_2_1 ___________________________________________________________________ Modified: svn:mergeinfo Merged /trunk:r50671 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/