mirror of
https://github.com/ruby/ruby.git
synced 2025-09-17 09:33:59 +02:00
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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_2@51134 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
8ff3a728ae
commit
72fa2ec34a
7 changed files with 58 additions and 15 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
Sat Jul 4 04:46:51 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* 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.
|
||||
|
||||
Sat Jul 4 04:35:51 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* vm_eval.c (rb_method_call_status): resolve refined method entry
|
||||
|
|
|
@ -4855,6 +4855,10 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||
}
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -1158,6 +1158,7 @@ VALUE rb_setup_fake_str(struct RString *fake_str, const char *name, long len, rb
|
|||
|
||||
/* util.c (export) */
|
||||
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 (export) */
|
||||
void rb_gc_mark_global_tbl(void);
|
||||
|
|
27
parse.y
27
parse.y
|
@ -692,9 +692,7 @@ new_args_tail_gen(struct parser_params *parser, VALUE k, VALUE kr, VALUE b)
|
|||
# define rb_warningV(fmt,a) ripper_warningV(parser, (fmt), (a))
|
||||
static void ripper_warn0(struct parser_params*, const char*);
|
||||
static void ripper_warnI(struct parser_params*, const char*, int);
|
||||
#if 0 /* not in use right now */
|
||||
static void ripper_warnS(struct parser_params*, const char*, const char*);
|
||||
#endif
|
||||
static void ripper_warnV(struct parser_params*, const char*, VALUE);
|
||||
static void ripper_warning0(struct parser_params*, const char*);
|
||||
static void ripper_warningS(struct parser_params*, const char*, const char*);
|
||||
|
@ -7607,6 +7605,27 @@ tokenize_ident(struct parser_params *parser, const enum lex_state_e last_state)
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
parse_gvar(struct parser_params *parser, const enum lex_state_e last_state)
|
||||
{
|
||||
|
@ -7685,7 +7704,7 @@ parse_gvar(struct parser_params *parser, const enum lex_state_e last_state)
|
|||
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:
|
||||
|
@ -11053,14 +11072,12 @@ ripper_warnI(struct parser_params *parser, const char *fmt, int a)
|
|||
STR_NEW2(fmt), INT2NUM(a));
|
||||
}
|
||||
|
||||
#if 0 /* not in use right now */
|
||||
static void
|
||||
ripper_warnS(struct parser_params *parser, const char *fmt, const char *str)
|
||||
{
|
||||
rb_funcall(parser->value, id_warn, 2,
|
||||
STR_NEW2(fmt), STR_NEW2(str));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
ripper_warnV(struct parser_params *parser, const char *fmt, VALUE v)
|
||||
|
|
|
@ -570,6 +570,13 @@ eom
|
|||
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
|
||||
|
|
22
util.c
22
util.c
|
@ -74,21 +74,25 @@ const signed char ruby_digit36_to_number_table[] = {
|
|||
/*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;
|
||||
|
@ -97,7 +101,7 @@ scan_digits(const char *str, int base, size_t *retlen, int *overflow)
|
|||
ret += d;
|
||||
if (ret < x)
|
||||
*overflow = 1;
|
||||
}
|
||||
} while (len < 0 || --len);
|
||||
*retlen = (str-1) - start;
|
||||
return ret;
|
||||
}
|
||||
|
@ -149,7 +153,7 @@ ruby_strtoul(const char *str, char **endptr, int base)
|
|||
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;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#define RUBY_VERSION "2.2.3"
|
||||
#define RUBY_RELEASE_DATE "2015-07-04"
|
||||
#define RUBY_PATCHLEVEL 144
|
||||
#define RUBY_PATCHLEVEL 145
|
||||
|
||||
#define RUBY_RELEASE_YEAR 2015
|
||||
#define RUBY_RELEASE_MONTH 7
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue