зеркало из https://github.com/github/ruby.git
* eval.c (rb_add_method): preserve safe level in the environment
where a method is defined . * eval.c (rb_call0): restore preserved safe level in the method execution. * parse.y (lambda): need separate block variable stack manipulation and lpar_beg maintenance. based on a patch found in [ruby-core:05551] from Mauricio Fernandez <mfp@acm.org>. * parse.y (parser_yylex): adjust lpar_beg after tLAMBEG and kDO_LAMBDA. [ruby-core:05551] * parse.y (yycompile): remove unreachable code. [yarv-dev:570] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8994 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
e6a104131a
Коммит
17957e0dfc
20
ChangeLog
20
ChangeLog
|
@ -1,3 +1,18 @@
|
||||||
|
Wed Aug 17 00:05:46 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* eval.c (rb_add_method): preserve safe level in the environment
|
||||||
|
where a method is defined .
|
||||||
|
|
||||||
|
* eval.c (rb_call0): restore preserved safe level in the method
|
||||||
|
execution.
|
||||||
|
|
||||||
|
* parse.y (lambda): need separate block variable stack
|
||||||
|
manipulation and lpar_beg maintenance. based on a patch found
|
||||||
|
in [ruby-core:05551] from Mauricio Fernandez <mfp@acm.org>.
|
||||||
|
|
||||||
|
* parse.y (parser_yylex): adjust lpar_beg after tLAMBEG and
|
||||||
|
kDO_LAMBDA. [ruby-core:05551]
|
||||||
|
|
||||||
Mon Aug 15 07:24:38 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Mon Aug 15 07:24:38 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* intern.h (rb_check_to_integer): add declaration.
|
* intern.h (rb_check_to_integer): add declaration.
|
||||||
|
@ -11,6 +26,10 @@ Mon Aug 15 00:38:51 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* range.c (range_check, range_init): reduce uselse exceptions.
|
* range.c (range_check, range_init): reduce uselse exceptions.
|
||||||
|
|
||||||
|
Mon Aug 15 00:34:11 2005 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* parse.y (yycompile): remove unreachable code. [yarv-dev:570]
|
||||||
|
|
||||||
Sat Aug 13 22:16:12 2005 Minero Aoki <aamine@loveruby.net>
|
Sat Aug 13 22:16:12 2005 Minero Aoki <aamine@loveruby.net>
|
||||||
|
|
||||||
* lib/fileutils.rb (remove_entry_secure): forgot final chdir.
|
* lib/fileutils.rb (remove_entry_secure): forgot final chdir.
|
||||||
|
@ -28,6 +47,7 @@ Sat Aug 13 21:11:05 2005 Masaki Suketa <masaki.suketa@nifty.ne.jp>
|
||||||
|
|
||||||
* ext/win32ole/tests/testOLEVARIANT.rb: ditto.
|
* ext/win32ole/tests/testOLEVARIANT.rb: ditto.
|
||||||
|
|
||||||
|
>>>>>>> 1.4488
|
||||||
Sat Aug 13 18:51:26 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Sat Aug 13 18:51:26 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* eval.c (rb_block_pass): distinguish current block from others.
|
* eval.c (rb_block_pass): distinguish current block from others.
|
||||||
|
|
45
eval.c
45
eval.c
|
@ -377,6 +377,9 @@ static ID init, eqq, each, aref, aset, match, missing;
|
||||||
static ID added, singleton_added;
|
static ID added, singleton_added;
|
||||||
static ID __id__, __send__, respond_to;
|
static ID __id__, __send__, respond_to;
|
||||||
|
|
||||||
|
#define NOEX_WITH_SAFE(n) ((n) | ruby_safe_level << 4)
|
||||||
|
#define NOEX_SAFE(n) ((n) >> 4)
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_add_method(klass, mid, node, noex)
|
rb_add_method(klass, mid, node, noex)
|
||||||
VALUE klass;
|
VALUE klass;
|
||||||
|
@ -403,7 +406,7 @@ rb_add_method(klass, mid, node, noex)
|
||||||
}
|
}
|
||||||
if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
|
if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
|
||||||
rb_clear_cache_by_id(mid);
|
rb_clear_cache_by_id(mid);
|
||||||
body = NEW_METHOD(node, noex);
|
body = NEW_METHOD(node, NOEX_WITH_SAFE(noex));
|
||||||
st_insert(RCLASS(klass)->m_tbl, mid, (st_data_t)body);
|
st_insert(RCLASS(klass)->m_tbl, mid, (st_data_t)body);
|
||||||
if (node && mid != ID_ALLOCATOR && ruby_running) {
|
if (node && mid != ID_ALLOCATOR && ruby_running) {
|
||||||
if (FL_TEST(klass, FL_SINGLETON)) {
|
if (FL_TEST(klass, FL_SINGLETON)) {
|
||||||
|
@ -5796,20 +5799,21 @@ formal_assign(recv, node, argc, argv, local_vars)
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_call0(klass, recv, id, oid, argc, argv, body, nosuper)
|
rb_call0(klass, recv, id, oid, argc, argv, body, flags)
|
||||||
VALUE klass, recv;
|
VALUE klass, recv;
|
||||||
ID id;
|
ID id;
|
||||||
ID oid;
|
ID oid;
|
||||||
int argc; /* OK */
|
int argc; /* OK */
|
||||||
VALUE *argv; /* OK */
|
VALUE *argv; /* OK */
|
||||||
NODE * volatile body;
|
NODE * volatile body;
|
||||||
int nosuper;
|
int flags;
|
||||||
{
|
{
|
||||||
NODE *b2; /* OK */
|
NODE *b2; /* OK */
|
||||||
volatile VALUE result = Qnil;
|
volatile VALUE result = Qnil;
|
||||||
int itr;
|
int itr;
|
||||||
static int tick;
|
static int tick;
|
||||||
volatile VALUE args;
|
volatile VALUE args;
|
||||||
|
volatile int safe = -1;
|
||||||
TMP_PROTECT;
|
TMP_PROTECT;
|
||||||
|
|
||||||
switch (ruby_iter->iter) {
|
switch (ruby_iter->iter) {
|
||||||
|
@ -5838,7 +5842,7 @@ rb_call0(klass, recv, id, oid, argc, argv, body, nosuper)
|
||||||
PUSH_FRAME();
|
PUSH_FRAME();
|
||||||
ruby_frame->callee = id;
|
ruby_frame->callee = id;
|
||||||
ruby_frame->this_func = oid;
|
ruby_frame->this_func = oid;
|
||||||
ruby_frame->this_class = nosuper?0:klass;
|
ruby_frame->this_class = (flags & NOEX_NOSUPER)?0:klass;
|
||||||
ruby_frame->self = recv;
|
ruby_frame->self = recv;
|
||||||
ruby_frame->argc = argc;
|
ruby_frame->argc = argc;
|
||||||
|
|
||||||
|
@ -5902,7 +5906,6 @@ rb_call0(klass, recv, id, oid, argc, argv, body, nosuper)
|
||||||
NODE *saved_cref = 0;
|
NODE *saved_cref = 0;
|
||||||
|
|
||||||
PUSH_SCOPE();
|
PUSH_SCOPE();
|
||||||
|
|
||||||
if (body->nd_rval) {
|
if (body->nd_rval) {
|
||||||
saved_cref = ruby_cref;
|
saved_cref = ruby_cref;
|
||||||
ruby_cref = (NODE*)body->nd_rval;
|
ruby_cref = (NODE*)body->nd_rval;
|
||||||
|
@ -5923,7 +5926,10 @@ rb_call0(klass, recv, id, oid, argc, argv, body, nosuper)
|
||||||
|
|
||||||
PUSH_VARS();
|
PUSH_VARS();
|
||||||
PUSH_TAG(PROT_FUNC);
|
PUSH_TAG(PROT_FUNC);
|
||||||
|
if (NOEX_SAFE(flags) > ruby_safe_level) {
|
||||||
|
safe = ruby_safe_level;
|
||||||
|
ruby_safe_level = NOEX_SAFE(flags);
|
||||||
|
}
|
||||||
if ((state = EXEC_TAG()) == 0) {
|
if ((state = EXEC_TAG()) == 0) {
|
||||||
NODE *node = 0;
|
NODE *node = 0;
|
||||||
|
|
||||||
|
@ -5953,6 +5959,7 @@ rb_call0(klass, recv, id, oid, argc, argv, body, nosuper)
|
||||||
POP_CLASS();
|
POP_CLASS();
|
||||||
POP_SCOPE();
|
POP_SCOPE();
|
||||||
ruby_cref = saved_cref;
|
ruby_cref = saved_cref;
|
||||||
|
if (safe > 0) ruby_safe_level = safe;
|
||||||
if (event_hooks) {
|
if (event_hooks) {
|
||||||
EXEC_EVENT_HOOK(RUBY_EVENT_RETURN, body, recv, id, klass);
|
EXEC_EVENT_HOOK(RUBY_EVENT_RETURN, body, recv, id, klass);
|
||||||
}
|
}
|
||||||
|
@ -6035,7 +6042,7 @@ rb_call(klass, recv, mid, argc, argv, scope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rb_call0(klass, recv, mid, id, argc, argv, body, noex & NOEX_NOSUPER);
|
return rb_call0(klass, recv, mid, id, argc, argv, body, noex);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
@ -8825,10 +8832,9 @@ rb_block_pass(func, arg, proc)
|
||||||
proc = b;
|
proc = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ruby_safe_level >= 1 && OBJ_TAINTED(proc)) {
|
if (ruby_safe_level >= 1 && OBJ_TAINTED(proc) &&
|
||||||
if (ruby_safe_level > proc_get_safe_level(proc)) {
|
ruby_safe_level > proc_get_safe_level(proc)) {
|
||||||
rb_raise(rb_eSecurityError, "Insecure: tainted block value");
|
rb_raise(rb_eSecurityError, "Insecure: tainted block value");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ruby_block && ruby_block->block_obj == proc) {
|
if (ruby_block && ruby_block->block_obj == proc) {
|
||||||
|
@ -8914,6 +8920,7 @@ struct METHOD {
|
||||||
VALUE klass, rklass;
|
VALUE klass, rklass;
|
||||||
VALUE recv;
|
VALUE recv;
|
||||||
ID id, oid;
|
ID id, oid;
|
||||||
|
int safe_level;
|
||||||
NODE *body;
|
NODE *body;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8961,6 +8968,7 @@ mnew(klass, obj, id, mklass)
|
||||||
data->body = body;
|
data->body = body;
|
||||||
data->rklass = rklass;
|
data->rklass = rklass;
|
||||||
data->oid = oid;
|
data->oid = oid;
|
||||||
|
data->safe_level = NOEX_WITH_SAFE(0);
|
||||||
OBJ_INFECT(method, klass);
|
OBJ_INFECT(method, klass);
|
||||||
|
|
||||||
return method;
|
return method;
|
||||||
|
@ -9189,26 +9197,15 @@ rb_method_call(argc, argv, method)
|
||||||
{
|
{
|
||||||
VALUE result = Qnil; /* OK */
|
VALUE result = Qnil; /* OK */
|
||||||
struct METHOD *data;
|
struct METHOD *data;
|
||||||
int state;
|
|
||||||
volatile int safe = -1;
|
|
||||||
|
|
||||||
Data_Get_Struct(method, struct METHOD, data);
|
Data_Get_Struct(method, struct METHOD, data);
|
||||||
if (data->recv == Qundef) {
|
if (data->recv == Qundef) {
|
||||||
rb_raise(rb_eTypeError, "can't call unbound method; bind first");
|
rb_raise(rb_eTypeError, "can't call unbound method; bind first");
|
||||||
}
|
}
|
||||||
PUSH_ITER(rb_block_given_p()?ITER_PRE:ITER_NOT);
|
PUSH_ITER(rb_block_given_p()?ITER_PRE:ITER_NOT);
|
||||||
PUSH_TAG(PROT_NONE);
|
result = rb_call0(data->klass,data->recv,data->id,data->oid,argc,argv,data->body,
|
||||||
if (OBJ_TAINTED(method)) {
|
data->safe_level);
|
||||||
safe = ruby_safe_level;
|
|
||||||
if (ruby_safe_level < 4) ruby_safe_level = 4;
|
|
||||||
}
|
|
||||||
if ((state = EXEC_TAG()) == 0) {
|
|
||||||
result = rb_call0(data->klass,data->recv,data->id,data->oid,argc,argv,data->body,0);
|
|
||||||
}
|
|
||||||
POP_TAG();
|
|
||||||
POP_ITER();
|
POP_ITER();
|
||||||
if (safe >= 0) ruby_safe_level = safe;
|
|
||||||
if (state) JUMP_TAG(state);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
37
parse.y
37
parse.y
|
@ -2606,8 +2606,7 @@ primary : literal
|
||||||
$$ = dispatch2(iter_block, $1, $2);
|
$$ = dispatch2(iter_block, $1, $2);
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
| tLAMBDA
|
| tLAMBDA lambda
|
||||||
lambda
|
|
||||||
{
|
{
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
|
@ -3178,13 +3177,15 @@ bv_decl : tIDENTIFIER
|
||||||
;
|
;
|
||||||
|
|
||||||
lambda : {
|
lambda : {
|
||||||
$<num>$ = lpar_beg;
|
|
||||||
lpar_beg = ++paren_nest;
|
|
||||||
/*%%%*/
|
/*%%%*/
|
||||||
$<vars>$ = dyna_push();
|
$<vars>$ = dyna_push();
|
||||||
/*%
|
/*%
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
$<num>$ = lpar_beg;
|
||||||
|
lpar_beg = ++paren_nest;
|
||||||
|
}
|
||||||
f_larglist
|
f_larglist
|
||||||
{
|
{
|
||||||
$<vars>$ = ruby_dyna_vars;
|
$<vars>$ = ruby_dyna_vars;
|
||||||
|
@ -3192,11 +3193,12 @@ lambda : {
|
||||||
lambda_body
|
lambda_body
|
||||||
{
|
{
|
||||||
/*%%%*/
|
/*%%%*/
|
||||||
$$ = $2;
|
$$ = $3;
|
||||||
$$->nd_body = block_append($$->nd_body, $4);
|
$$->nd_body = block_append($$->nd_body, $5);
|
||||||
dyna_pop($<vars>1);
|
dyna_pop($<vars>1);
|
||||||
|
lpar_beg = $<num>2;
|
||||||
/*%
|
/*%
|
||||||
$$ = dispatch2(lambda, $2, $4);
|
$$ = dispatch2(lambda, $3, $5);
|
||||||
%*/
|
%*/
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -3219,15 +3221,11 @@ f_larglist : '(' f_args opt_bv_decl rparen
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
lambda_body : tLAMBEG
|
lambda_body : tLAMBEG compstmt '}'
|
||||||
compstmt
|
|
||||||
'}'
|
|
||||||
{
|
{
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
| kDO_LAMBDA
|
| kDO_LAMBDA compstmt kEND
|
||||||
compstmt
|
|
||||||
kEND
|
|
||||||
{
|
{
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
|
@ -4360,7 +4358,6 @@ none : /* none */
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
%%
|
%%
|
||||||
|
|
||||||
# undef parser
|
# undef parser
|
||||||
# undef yylex
|
# undef yylex
|
||||||
# undef yylval
|
# undef yylval
|
||||||
|
@ -4568,10 +4565,6 @@ yycompile(parser, f, line)
|
||||||
else {
|
else {
|
||||||
return ruby_eval_tree;
|
return ruby_eval_tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n == 0) node = ruby_eval_tree;
|
|
||||||
else ruby_eval_tree_begin = 0;
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
#endif /* !RIPPER */
|
#endif /* !RIPPER */
|
||||||
|
|
||||||
|
@ -6485,6 +6478,8 @@ parser_yylex(parser)
|
||||||
case '{':
|
case '{':
|
||||||
if (lpar_beg && lpar_beg == paren_nest) {
|
if (lpar_beg && lpar_beg == paren_nest) {
|
||||||
lex_state = EXPR_BEG;
|
lex_state = EXPR_BEG;
|
||||||
|
lpar_beg = 0;
|
||||||
|
--paren_nest;
|
||||||
return tLAMBEG;
|
return tLAMBEG;
|
||||||
}
|
}
|
||||||
if (IS_ARG() || lex_state == EXPR_END || lex_state == EXPR_END2)
|
if (IS_ARG() || lex_state == EXPR_END || lex_state == EXPR_END2)
|
||||||
|
@ -6805,6 +6800,8 @@ parser_yylex(parser)
|
||||||
}
|
}
|
||||||
if (kw->id[0] == kDO) {
|
if (kw->id[0] == kDO) {
|
||||||
if (lpar_beg && lpar_beg == paren_nest) {
|
if (lpar_beg && lpar_beg == paren_nest) {
|
||||||
|
lpar_beg = 0;
|
||||||
|
--paren_nest;
|
||||||
return kDO_LAMBDA;
|
return kDO_LAMBDA;
|
||||||
}
|
}
|
||||||
if (COND_P()) return kDO_COND;
|
if (COND_P()) return kDO_COND;
|
||||||
|
@ -8722,6 +8719,8 @@ parser_initialize(parser)
|
||||||
parser->parser_cond_stack = 0;
|
parser->parser_cond_stack = 0;
|
||||||
parser->parser_cmdarg_stack = 0;
|
parser->parser_cmdarg_stack = 0;
|
||||||
parser->parser_class_nest = 0;
|
parser->parser_class_nest = 0;
|
||||||
|
parser->parser_paren_nest = 0;
|
||||||
|
parser->parser_lpar_beg = 0;
|
||||||
parser->parser_in_single = 0;
|
parser->parser_in_single = 0;
|
||||||
parser->parser_in_def = 0;
|
parser->parser_in_def = 0;
|
||||||
parser->parser_in_defined = 0;
|
parser->parser_in_defined = 0;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче