* eval.c (rb_f_require): searches ".rb" and ".so" at the same
time. previous behavior (search ".rb", then ".so") has a security risk (ruby-bugs#PR140). * array.c (rb_ary_to_ary): new function to replace internal rb_Array(), which never calls to_a, but to_ary (rb_Array() might call both). [new] * regex.c (PUSH_FAILURE_POINT): push option status again. * regex.c (re_compile_pattern): avoid pushing unnecessary option_set. * eval.c (rb_load): tainted string is OK if wrapped *and* $SAFE >= 4. * eval.c (rb_thread_start_0): should not nail down higher blocks before preserving original context (i.e. should not alter original context). * eval.c (proc_yield): new method equivalent to Proc#call but no check for number of arguments. [new] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1526 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
6aa71d4c80
commit
9d51cf8a6a
33
ChangeLog
33
ChangeLog
@ -1,9 +1,42 @@
|
|||||||
|
Mon Jun 18 17:38:50 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* eval.c (rb_f_require): searches ".rb" and ".so" at the same
|
||||||
|
time. previous behavior (search ".rb", then ".so") has a
|
||||||
|
security risk (ruby-bugs#PR140).
|
||||||
|
|
||||||
|
* array.c (rb_ary_to_ary): new function to replace internal
|
||||||
|
rb_Array(), which never calls to_a, but to_ary (rb_Array() might
|
||||||
|
call both). [new]
|
||||||
|
|
||||||
|
Mon Jun 18 00:43:20 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* regex.c (PUSH_FAILURE_POINT): push option status again.
|
||||||
|
|
||||||
|
* regex.c (re_compile_pattern): avoid pushing unnecessary
|
||||||
|
option_set.
|
||||||
|
|
||||||
|
Sat Jun 16 10:58:48 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* eval.c (rb_load): tainted string is OK if wrapped *and*
|
||||||
|
$SAFE >= 4.
|
||||||
|
|
||||||
|
Thu Jun 14 16:27:07 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* eval.c (rb_thread_start_0): should not nail down higher blocks
|
||||||
|
before preserving original context (i.e. should not alter
|
||||||
|
original context).
|
||||||
|
|
||||||
Wed Jun 13 19:34:59 2001 Akinori MUSHA <knu@iDaemons.org>
|
Wed Jun 13 19:34:59 2001 Akinori MUSHA <knu@iDaemons.org>
|
||||||
|
|
||||||
* dir.c (Init_Dir): add a new method File::fnmatch? along with
|
* dir.c (Init_Dir): add a new method File::fnmatch? along with
|
||||||
File::Constants::FNM_*. While I am here, FNM_NOCASE is renamed
|
File::Constants::FNM_*. While I am here, FNM_NOCASE is renamed
|
||||||
to FNM_CASEFOLD which is commonly used by *BSD and GNU libc.
|
to FNM_CASEFOLD which is commonly used by *BSD and GNU libc.
|
||||||
|
|
||||||
|
Wed Jun 13 09:33:45 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* eval.c (proc_yield): new method equivalent to Proc#call but no
|
||||||
|
check for number of arguments. [new]
|
||||||
|
|
||||||
Tue Jun 12 14:21:28 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
Tue Jun 12 14:21:28 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
||||||
|
|
||||||
* lib/mkmf.rb: target_prefix is only for installation, not for
|
* lib/mkmf.rb: target_prefix is only for installation, not for
|
||||||
|
1
ToDo
1
ToDo
@ -83,6 +83,7 @@ Standard Libraries
|
|||||||
* hash etc. should handle self referenceing array/hash
|
* hash etc. should handle self referenceing array/hash
|
||||||
* move NameError under StandardError.
|
* move NameError under StandardError.
|
||||||
* library to load per-user profile seeking .ruby_profile or ruby.ini file.
|
* library to load per-user profile seeking .ruby_profile or ruby.ini file.
|
||||||
|
* warning framework
|
||||||
|
|
||||||
Extension Libraries
|
Extension Libraries
|
||||||
|
|
||||||
|
17
array.c
17
array.c
@ -17,6 +17,7 @@
|
|||||||
#include "st.h"
|
#include "st.h"
|
||||||
|
|
||||||
VALUE rb_cArray;
|
VALUE rb_cArray;
|
||||||
|
static ID cmp;
|
||||||
|
|
||||||
#define ARY_DEFAULT_SIZE 16
|
#define ARY_DEFAULT_SIZE 16
|
||||||
|
|
||||||
@ -729,6 +730,20 @@ to_ary(ary)
|
|||||||
return rb_convert_type(ary, T_ARRAY, "Array", "to_ary");
|
return rb_convert_type(ary, T_ARRAY, "Array", "to_ary");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_ary_to_ary(obj)
|
||||||
|
VALUE obj;
|
||||||
|
{
|
||||||
|
if (NIL_P(obj)) return rb_ary_new2(0);
|
||||||
|
if (TYPE(obj) == T_ARRAY) {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
if (rb_respond_to(obj, rb_intern("to_ary"))) {
|
||||||
|
return rb_convert_type(obj, T_ARRAY, "Array", "to_ary");
|
||||||
|
}
|
||||||
|
return rb_ary_new3(1, obj);
|
||||||
|
}
|
||||||
|
|
||||||
extern VALUE rb_output_fs;
|
extern VALUE rb_output_fs;
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
@ -958,8 +973,6 @@ rb_ary_reverse_m(ary)
|
|||||||
return rb_ary_reverse(rb_obj_dup(ary));
|
return rb_ary_reverse(rb_obj_dup(ary));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ID cmp;
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sort_1(a, b)
|
sort_1(a, b)
|
||||||
VALUE *a, *b;
|
VALUE *a, *b;
|
||||||
|
111
eval.c
111
eval.c
@ -1676,7 +1676,7 @@ copy_node_scope(node, rval)
|
|||||||
char *file = ruby_sourcefile;\
|
char *file = ruby_sourcefile;\
|
||||||
int line = ruby_sourceline;\
|
int line = ruby_sourceline;\
|
||||||
if (TYPE(args) != T_ARRAY)\
|
if (TYPE(args) != T_ARRAY)\
|
||||||
args = rb_Array(args);\
|
args = rb_ary_to_ary(args);\
|
||||||
argc = RARRAY(args)->len;\
|
argc = RARRAY(args)->len;\
|
||||||
argv = ALLOCA_N(VALUE, argc);\
|
argv = ALLOCA_N(VALUE, argc);\
|
||||||
MEMCPY(argv, RARRAY(args)->ptr, VALUE, argc);\
|
MEMCPY(argv, RARRAY(args)->ptr, VALUE, argc);\
|
||||||
@ -2129,7 +2129,7 @@ rb_eval(self, n)
|
|||||||
VALUE v = rb_eval(self, tag->nd_head->nd_head);
|
VALUE v = rb_eval(self, tag->nd_head->nd_head);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (TYPE(v) != T_ARRAY) v = rb_Array(v);
|
if (TYPE(v) != T_ARRAY) v = rb_ary_to_ary(v);
|
||||||
for (i=0; i<RARRAY(v)->len; i++) {
|
for (i=0; i<RARRAY(v)->len; i++) {
|
||||||
if (RTEST(RARRAY(v)->ptr[i])) {
|
if (RTEST(RARRAY(v)->ptr[i])) {
|
||||||
node = node->nd_body;
|
node = node->nd_body;
|
||||||
@ -2174,7 +2174,7 @@ rb_eval(self, n)
|
|||||||
VALUE v = rb_eval(self, tag->nd_head->nd_head);
|
VALUE v = rb_eval(self, tag->nd_head->nd_head);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (TYPE(v) != T_ARRAY) v = rb_Array(v);
|
if (TYPE(v) != T_ARRAY) v = rb_ary_to_ary(v);
|
||||||
for (i=0; i<RARRAY(v)->len; i++) {
|
for (i=0; i<RARRAY(v)->len; i++) {
|
||||||
if (RTEST(rb_funcall2(RARRAY(v)->ptr[i], eqq, 1, &val))){
|
if (RTEST(rb_funcall2(RARRAY(v)->ptr[i], eqq, 1, &val))){
|
||||||
node = node->nd_body;
|
node = node->nd_body;
|
||||||
@ -2347,14 +2347,14 @@ rb_eval(self, n)
|
|||||||
case NODE_RESTARY:
|
case NODE_RESTARY:
|
||||||
result = rb_eval(self, node->nd_head);
|
result = rb_eval(self, node->nd_head);
|
||||||
if (TYPE(result) != T_ARRAY) {
|
if (TYPE(result) != T_ARRAY) {
|
||||||
result = rb_Array(result);
|
result = rb_ary_to_ary(result);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_REXPAND:
|
case NODE_REXPAND:
|
||||||
result = rb_eval(self, node->nd_head);
|
result = rb_eval(self, node->nd_head);
|
||||||
if (TYPE(result) != T_ARRAY) {
|
if (TYPE(result) != T_ARRAY) {
|
||||||
result = rb_Array(result);
|
result = rb_ary_to_ary(result);
|
||||||
}
|
}
|
||||||
if (RARRAY(result)->len == 0) {
|
if (RARRAY(result)->len == 0) {
|
||||||
result = Qnil;
|
result = Qnil;
|
||||||
@ -2520,7 +2520,7 @@ rb_eval(self, n)
|
|||||||
|
|
||||||
case NODE_ARGSCAT:
|
case NODE_ARGSCAT:
|
||||||
result = rb_ary_concat(rb_eval(self, node->nd_head),
|
result = rb_ary_concat(rb_eval(self, node->nd_head),
|
||||||
rb_Array(rb_eval(self, node->nd_body)));
|
rb_ary_to_ary(rb_eval(self, node->nd_body)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_ARGSPUSH:
|
case NODE_ARGSPUSH:
|
||||||
@ -3546,16 +3546,20 @@ rb_f_block_given_p()
|
|||||||
return Qfalse;
|
return Qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PC_NONE 0x0
|
||||||
|
#define PC_ACHECK 0x1
|
||||||
|
#define PC_PCALL 0x2
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_yield_0(val, self, klass, acheck)
|
rb_yield_0(val, self, klass, pcall)
|
||||||
VALUE val, self, klass; /* OK */
|
VALUE val, self, klass; /* OK */
|
||||||
int acheck;
|
int pcall;
|
||||||
{
|
{
|
||||||
NODE *node;
|
NODE *node;
|
||||||
volatile VALUE result = Qnil;
|
volatile VALUE result = Qnil;
|
||||||
volatile VALUE old_cref;
|
volatile VALUE old_cref;
|
||||||
struct BLOCK *block;
|
struct BLOCK * volatile block;
|
||||||
struct SCOPE *old_scope;
|
struct SCOPE * volatile old_scope;
|
||||||
struct FRAME frame;
|
struct FRAME frame;
|
||||||
int state;
|
int state;
|
||||||
static unsigned serial = 1;
|
static unsigned serial = 1;
|
||||||
@ -3591,7 +3595,7 @@ rb_yield_0(val, self, klass, acheck)
|
|||||||
PUSH_TAG(PROT_NONE);
|
PUSH_TAG(PROT_NONE);
|
||||||
if ((state = EXEC_TAG()) == 0) {
|
if ((state = EXEC_TAG()) == 0) {
|
||||||
if (block->var == (NODE*)1) {
|
if (block->var == (NODE*)1) {
|
||||||
if (acheck && val != Qundef &&
|
if ((pcall&PC_ACHECK) && val != Qundef &&
|
||||||
TYPE(val) == T_ARRAY && RARRAY(val)->len != 0) {
|
TYPE(val) == T_ARRAY && RARRAY(val)->len != 0) {
|
||||||
rb_raise(rb_eArgError, "wrong # of arguments (%d for 0)",
|
rb_raise(rb_eArgError, "wrong # of arguments (%d for 0)",
|
||||||
RARRAY(val)->len);
|
RARRAY(val)->len);
|
||||||
@ -3605,14 +3609,14 @@ rb_yield_0(val, self, klass, acheck)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (nd_type(block->var) == NODE_MASGN)
|
if (nd_type(block->var) == NODE_MASGN)
|
||||||
massign(self, block->var, val, acheck);
|
massign(self, block->var, val, (pcall&PC_ACHECK));
|
||||||
else {
|
else {
|
||||||
/* argument adjust for proc_call etc. */
|
/* argument adjust for proc_call etc. */
|
||||||
if (acheck && val != Qundef &&
|
if (pcall && val != Qundef &&
|
||||||
TYPE(val) == T_ARRAY && RARRAY(val)->len == 1) {
|
TYPE(val) == T_ARRAY && RARRAY(val)->len == 1) {
|
||||||
val = RARRAY(val)->ptr[0];
|
val = RARRAY(val)->ptr[0];
|
||||||
}
|
}
|
||||||
assign(self, block->var, val, acheck);
|
assign(self, block->var, val, (pcall&PC_ACHECK));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3621,7 +3625,7 @@ rb_yield_0(val, self, klass, acheck)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* argument adjust for proc_call etc. */
|
/* argument adjust for proc_call etc. */
|
||||||
if (acheck && val != Qundef &&
|
if (pcall && val != Qundef &&
|
||||||
TYPE(val) == T_ARRAY && RARRAY(val)->len == 1) {
|
TYPE(val) == T_ARRAY && RARRAY(val)->len == 1) {
|
||||||
val = RARRAY(val)->ptr[0];
|
val = RARRAY(val)->ptr[0];
|
||||||
}
|
}
|
||||||
@ -5171,7 +5175,12 @@ rb_load(fname, wrap)
|
|||||||
NODE *saved_cref = ruby_cref;
|
NODE *saved_cref = ruby_cref;
|
||||||
TMP_PROTECT;
|
TMP_PROTECT;
|
||||||
|
|
||||||
SafeStringValue(fname);
|
if (wrap && ruby_safe_level >= 4) {
|
||||||
|
StringValue(fname);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SafeStringValue(fname);
|
||||||
|
}
|
||||||
file = rb_find_file(RSTRING(fname)->ptr);
|
file = rb_find_file(RSTRING(fname)->ptr);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
rb_raise(rb_eLoadError, "No such file to load -- %s", RSTRING(fname)->ptr);
|
rb_raise(rb_eLoadError, "No such file to load -- %s", RSTRING(fname)->ptr);
|
||||||
@ -5402,28 +5411,20 @@ rb_f_require(obj, fname)
|
|||||||
}
|
}
|
||||||
buf = ALLOCA_N(char, strlen(RSTRING(fname)->ptr) + 5);
|
buf = ALLOCA_N(char, strlen(RSTRING(fname)->ptr) + 5);
|
||||||
strcpy(buf, RSTRING(fname)->ptr);
|
strcpy(buf, RSTRING(fname)->ptr);
|
||||||
strcat(buf, ".rb");
|
switch (rb_find_file_noext(buf)) {
|
||||||
if (rb_find_file(buf)) {
|
case 0:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
fname = rb_str_new2(buf);
|
fname = rb_str_new2(buf);
|
||||||
feature = buf;
|
file = feature = buf;
|
||||||
goto load_rb;
|
goto load_rb;
|
||||||
}
|
|
||||||
strcpy(buf, RSTRING(fname)->ptr);
|
default:
|
||||||
strcat(buf, DLEXT);
|
|
||||||
file = rb_find_file(buf);
|
|
||||||
if (file) {
|
|
||||||
feature = buf;
|
feature = buf;
|
||||||
|
file = rb_find_file(buf);
|
||||||
goto load_dyna;
|
goto load_dyna;
|
||||||
}
|
}
|
||||||
#ifdef DLEXT2
|
|
||||||
strcpy(buf, RSTRING(fname)->ptr);
|
|
||||||
strcat(buf, DLEXT2);
|
|
||||||
file = rb_find_file(buf);
|
|
||||||
if (file) {
|
|
||||||
feature = buf;
|
|
||||||
goto load_dyna;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
rb_raise(rb_eLoadError, "No such file to load -- %s",
|
rb_raise(rb_eLoadError, "No such file to load -- %s",
|
||||||
RSTRING(fname)->ptr);
|
RSTRING(fname)->ptr);
|
||||||
|
|
||||||
@ -6330,8 +6331,9 @@ callargs(args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
proc_call(proc, args)
|
proc_invoke(proc, args, pcall)
|
||||||
VALUE proc, args; /* OK */
|
VALUE proc, args; /* OK */
|
||||||
|
int pcall;
|
||||||
{
|
{
|
||||||
struct BLOCK * volatile old_block;
|
struct BLOCK * volatile old_block;
|
||||||
struct BLOCK _block;
|
struct BLOCK _block;
|
||||||
@ -6341,6 +6343,13 @@ proc_call(proc, args)
|
|||||||
volatile int orphan;
|
volatile int orphan;
|
||||||
volatile int safe = ruby_safe_level;
|
volatile int safe = ruby_safe_level;
|
||||||
|
|
||||||
|
if (pcall) {
|
||||||
|
pcall = PC_ACHECK|PC_PCALL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pcall = PC_PCALL;
|
||||||
|
}
|
||||||
|
|
||||||
if (rb_block_given_p() && ruby_frame->last_func) {
|
if (rb_block_given_p() && ruby_frame->last_func) {
|
||||||
rb_warning("block for %s#%s is useless",
|
rb_warning("block for %s#%s is useless",
|
||||||
rb_class2name(CLASS_OF(proc)),
|
rb_class2name(CLASS_OF(proc)),
|
||||||
@ -6367,7 +6376,7 @@ proc_call(proc, args)
|
|||||||
state = EXEC_TAG();
|
state = EXEC_TAG();
|
||||||
if (state == 0) {
|
if (state == 0) {
|
||||||
proc_set_safe_level(proc);
|
proc_set_safe_level(proc);
|
||||||
result = rb_yield_0(args, 0, 0, Qtrue);
|
result = rb_yield_0(args, 0, 0, pcall);
|
||||||
}
|
}
|
||||||
POP_TAG();
|
POP_TAG();
|
||||||
|
|
||||||
@ -6398,6 +6407,20 @@ proc_call(proc, args)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
proc_call(proc, args)
|
||||||
|
VALUE proc, args; /* OK */
|
||||||
|
{
|
||||||
|
return proc_invoke(proc, args, Qtrue);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
proc_yield(proc, args)
|
||||||
|
VALUE proc, args; /* OK */
|
||||||
|
{
|
||||||
|
return proc_invoke(proc, args, Qfalse);
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
proc_arity(proc)
|
proc_arity(proc)
|
||||||
VALUE proc;
|
VALUE proc;
|
||||||
@ -6899,6 +6922,7 @@ Init_Proc()
|
|||||||
rb_define_singleton_method(rb_cProc, "new", proc_s_new, -1);
|
rb_define_singleton_method(rb_cProc, "new", proc_s_new, -1);
|
||||||
|
|
||||||
rb_define_method(rb_cProc, "call", proc_call, -2);
|
rb_define_method(rb_cProc, "call", proc_call, -2);
|
||||||
|
rb_define_method(rb_cProc, "yield", proc_yield, -2);
|
||||||
rb_define_method(rb_cProc, "arity", proc_arity, 0);
|
rb_define_method(rb_cProc, "arity", proc_arity, 0);
|
||||||
rb_define_method(rb_cProc, "[]", proc_call, -2);
|
rb_define_method(rb_cProc, "[]", proc_call, -2);
|
||||||
rb_define_method(rb_cProc, "==", proc_eq, 1);
|
rb_define_method(rb_cProc, "==", proc_eq, 1);
|
||||||
@ -8210,7 +8234,11 @@ rb_thread_start_0(fn, arg, th_arg)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ruby_block) { /* should nail down higher scopes */
|
if (THREAD_SAVE_CONTEXT(curr_thread)) {
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ruby_block) { /* should nail down higher blocks */
|
||||||
struct BLOCK dummy;
|
struct BLOCK dummy;
|
||||||
|
|
||||||
dummy.prev = ruby_block;
|
dummy.prev = ruby_block;
|
||||||
@ -8219,9 +8247,6 @@ rb_thread_start_0(fn, arg, th_arg)
|
|||||||
}
|
}
|
||||||
scope_dup(ruby_scope);
|
scope_dup(ruby_scope);
|
||||||
FL_SET(ruby_scope, SCOPE_SHARED);
|
FL_SET(ruby_scope, SCOPE_SHARED);
|
||||||
if (THREAD_SAVE_CONTEXT(curr_thread)) {
|
|
||||||
return thread;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!th->next) {
|
if (!th->next) {
|
||||||
/* merge in thread list */
|
/* merge in thread list */
|
||||||
@ -8243,17 +8268,21 @@ rb_thread_start_0(fn, arg, th_arg)
|
|||||||
POP_TAG();
|
POP_TAG();
|
||||||
status = th->status;
|
status = th->status;
|
||||||
|
|
||||||
|
if (th == main_thread) ruby_stop(state);
|
||||||
|
rb_thread_remove(th);
|
||||||
|
|
||||||
while (saved_block) {
|
while (saved_block) {
|
||||||
struct BLOCK *tmp = saved_block;
|
struct BLOCK *tmp = saved_block;
|
||||||
|
|
||||||
|
if (curr_thread == main_thread) {
|
||||||
|
printf("free(%p)\n", saved_block);
|
||||||
|
}
|
||||||
if (tmp->frame.argc > 0)
|
if (tmp->frame.argc > 0)
|
||||||
free(tmp->frame.argv);
|
free(tmp->frame.argv);
|
||||||
saved_block = tmp->prev;
|
saved_block = tmp->prev;
|
||||||
free(tmp);
|
free(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (th == main_thread) ruby_stop(state);
|
|
||||||
rb_thread_remove(th);
|
|
||||||
if (state && status != THREAD_TO_KILL && !NIL_P(ruby_errinfo)) {
|
if (state && status != THREAD_TO_KILL && !NIL_P(ruby_errinfo)) {
|
||||||
th->flags |= THREAD_RAISED;
|
th->flags |= THREAD_RAISED;
|
||||||
if (state == TAG_FATAL) {
|
if (state == TAG_FATAL) {
|
||||||
|
110
file.c
110
file.c
@ -2202,41 +2202,76 @@ is_macos_native_path(path)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static char*
|
||||||
|
file_load_ok(file)
|
||||||
|
char *file;
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
f = fopen(file, "r");
|
||||||
|
if (f == NULL) return 0;
|
||||||
|
fclose(f);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern VALUE rb_load_path;
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_find_file_noext(file)
|
||||||
|
char *file;
|
||||||
|
{
|
||||||
|
char *path, *e, *found;
|
||||||
|
char *fend = file + strlen(file);
|
||||||
|
VALUE fname;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
static char *ext[] = {
|
||||||
|
".rb", DLEXT,
|
||||||
|
#ifdef DLEXT2
|
||||||
|
DLEXT2,
|
||||||
|
#endif
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
if (file[0] == '~') {
|
||||||
|
fname = rb_str_new2(file);
|
||||||
|
fname = rb_file_s_expand_path(1, &fname);
|
||||||
|
file = StringValuePtr(fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_absolute_path(file)) {
|
||||||
|
for (i=0; ext[i]; i++) {
|
||||||
|
strcpy(fend, ext[i]);
|
||||||
|
if (file_load_ok(file)) return i+1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rb_load_path) return 0;
|
||||||
|
|
||||||
|
Check_Type(rb_load_path, T_ARRAY);
|
||||||
|
for (i=0;i<RARRAY(rb_load_path)->len;i++) {
|
||||||
|
VALUE str = RARRAY(rb_load_path)->ptr[i];
|
||||||
|
|
||||||
|
SafeStringValue(str);
|
||||||
|
path = RSTRING(str)->ptr;
|
||||||
|
for (j=0; ext[j]; j++) {
|
||||||
|
strcpy(fend, ext[j]);
|
||||||
|
found = dln_find_file(file, path);
|
||||||
|
if (found && file_load_ok(found)) return j+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
char*
|
char*
|
||||||
rb_find_file(file)
|
rb_find_file(file)
|
||||||
char *file;
|
char *file;
|
||||||
{
|
{
|
||||||
extern VALUE rb_load_path;
|
|
||||||
VALUE vpath, fname;
|
VALUE vpath, fname;
|
||||||
char *path;
|
char *path;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
#if defined(__MACOS__) || defined(riscos)
|
|
||||||
if (is_macos_native_path(file)) {
|
|
||||||
FILE *f;
|
|
||||||
|
|
||||||
if (rb_safe_level() >= 2 && !rb_path_check(file)) {
|
|
||||||
rb_raise(rb_eSecurityError, "loading from unsafe file %s", file);
|
|
||||||
}
|
|
||||||
f= fopen(file, "r");
|
|
||||||
if (f == NULL) return 0;
|
|
||||||
fclose(f);
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (is_absolute_path(file)) {
|
|
||||||
FILE *f;
|
|
||||||
|
|
||||||
if (rb_safe_level() >= 2 && !rb_path_check(file)) {
|
|
||||||
rb_raise(rb_eSecurityError, "loading from unsafe file %s", file);
|
|
||||||
}
|
|
||||||
f = fopen(file, "r");
|
|
||||||
if (f == NULL) return 0;
|
|
||||||
fclose(f);
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file[0] == '~') {
|
if (file[0] == '~') {
|
||||||
fname = rb_str_new2(file);
|
fname = rb_str_new2(file);
|
||||||
fname = rb_file_s_expand_path(1, &fname);
|
fname = rb_file_s_expand_path(1, &fname);
|
||||||
@ -2246,6 +2281,22 @@ rb_find_file(file)
|
|||||||
file = StringValuePtr(fname);
|
file = StringValuePtr(fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__MACOS__) || defined(riscos)
|
||||||
|
if (is_macos_native_path(file)) {
|
||||||
|
if (rb_safe_level() >= 2 && !rb_path_check(file)) {
|
||||||
|
rb_raise(rb_eSecurityError, "loading from unsafe file %s", file);
|
||||||
|
}
|
||||||
|
return file_load_ok(file);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (is_absolute_path(file)) {
|
||||||
|
if (rb_safe_level() >= 2 && !rb_path_check(file)) {
|
||||||
|
rb_raise(rb_eSecurityError, "loading from unsafe file %s", file);
|
||||||
|
}
|
||||||
|
return file_load_ok(file);
|
||||||
|
}
|
||||||
|
|
||||||
if (rb_load_path) {
|
if (rb_load_path) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -2269,10 +2320,7 @@ rb_find_file(file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
path = dln_find_file(file, path);
|
path = dln_find_file(file, path);
|
||||||
if (path && stat(path, &st) == 0) {
|
return file_load_ok(path);
|
||||||
return path;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
2
intern.h
2
intern.h
@ -27,6 +27,7 @@ VALUE rb_ary_new4 _((long, VALUE *));
|
|||||||
VALUE rb_ary_freeze _((VALUE));
|
VALUE rb_ary_freeze _((VALUE));
|
||||||
VALUE rb_ary_aref _((int, VALUE*, VALUE));
|
VALUE rb_ary_aref _((int, VALUE*, VALUE));
|
||||||
void rb_ary_store _((VALUE, long, VALUE));
|
void rb_ary_store _((VALUE, long, VALUE));
|
||||||
|
VALUE rb_ary_to_ary _((VALUE));
|
||||||
VALUE rb_ary_to_s _((VALUE));
|
VALUE rb_ary_to_s _((VALUE));
|
||||||
VALUE rb_ary_push _((VALUE, VALUE));
|
VALUE rb_ary_push _((VALUE, VALUE));
|
||||||
VALUE rb_ary_pop _((VALUE));
|
VALUE rb_ary_pop _((VALUE));
|
||||||
@ -179,6 +180,7 @@ void rb_thread_atfork _((void));
|
|||||||
int eaccess _((const char*, int));
|
int eaccess _((const char*, int));
|
||||||
VALUE rb_file_s_expand_path _((int, VALUE *));
|
VALUE rb_file_s_expand_path _((int, VALUE *));
|
||||||
void rb_file_const _((const char*, VALUE));
|
void rb_file_const _((const char*, VALUE));
|
||||||
|
int rb_find_file_noext _((char*));
|
||||||
char *rb_find_file _((char*));
|
char *rb_find_file _((char*));
|
||||||
/* gc.c */
|
/* gc.c */
|
||||||
void rb_gc_mark_locations _((VALUE*, VALUE*));
|
void rb_gc_mark_locations _((VALUE*, VALUE*));
|
||||||
|
6
io.c
6
io.c
@ -3462,10 +3462,8 @@ opt_i_set(val)
|
|||||||
VALUE val;
|
VALUE val;
|
||||||
{
|
{
|
||||||
if (ruby_inplace_mode) free(ruby_inplace_mode);
|
if (ruby_inplace_mode) free(ruby_inplace_mode);
|
||||||
if (!RTEST(val)) {
|
ruby_inplace_mode = 0;
|
||||||
ruby_inplace_mode = 0;
|
if (!RTEST(val)) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
StringValue(val);
|
StringValue(val);
|
||||||
ruby_inplace_mode = strdup(RSTRING(val)->ptr);
|
ruby_inplace_mode = strdup(RSTRING(val)->ptr);
|
||||||
}
|
}
|
||||||
|
@ -854,7 +854,7 @@ class Resolv
|
|||||||
raise DecodeError.new("limit exceed") if @limit < @index + len
|
raise DecodeError.new("limit exceed") if @limit < @index + len
|
||||||
arr = @data.unpack("@#{@index}#{template}")
|
arr = @data.unpack("@#{@index}#{template}")
|
||||||
@index += len
|
@index += len
|
||||||
return *arr
|
return arr
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_string
|
def get_string
|
||||||
|
@ -660,21 +660,24 @@ An end of a defun is found by moving forward from the beginning of one."
|
|||||||
|
|
||||||
(cond
|
(cond
|
||||||
((featurep 'font-lock)
|
((featurep 'font-lock)
|
||||||
|
(or (boundp 'font-lock-variable-name-face)
|
||||||
|
(setq font-lock-variable-name-face font-lock-type-face))
|
||||||
|
|
||||||
(setq ruby-font-lock-syntactic-keywords
|
|
||||||
'(("\\$\\([#\"'`$\\]\\)" 1 (1 . nil))
|
(add-hook 'ruby-mode-hook
|
||||||
("\\(#\\)[{$@]" 1 (1 . nil))
|
'(lambda ()
|
||||||
("\\(/\\)\\([^/\n]\\|\\/\\)*\\(/\\)"
|
(make-local-variable 'font-lock-syntactic-keywords)
|
||||||
(1 (7 . ?'))
|
(setq font-lock-syntactic-keywords
|
||||||
(3 (7 . ?')))
|
'(("\\$\\([#\"'`$\\]\\)" 1 (1 . nil))
|
||||||
("^\\(=\\)begin\\(\\s \\|$\\)" 1 (7 . nil))
|
("\\(#\\)[{$@]" 1 (1 . nil))
|
||||||
("^\\(=\\)end\\(\\s \\|$\\)" 1 (7 . nil))))
|
("\\(/\\)\\([^/\n]\\|\\/\\)*\\(/\\)"
|
||||||
(put major-mode 'font-lock-defaults
|
(1 (7 . ?'))
|
||||||
'((ruby-font-lock-keywords)
|
(3 (7 . ?')))
|
||||||
nil nil nil
|
("^\\(=\\)begin\\(\\s \\|$\\)" 1 (7 . nil))
|
||||||
beginning-of-line
|
("^\\(=\\)end\\(\\s \\|$\\)" 1 (7 . nil))))
|
||||||
(font-lock-syntactic-keywords
|
(make-local-variable 'font-lock-defaults)
|
||||||
. ruby-font-lock-syntactic-keywords)))
|
(setq font-lock-defaults '((ruby-font-lock-keywords) nil nil))
|
||||||
|
(setq font-lock-keywords ruby-font-lock-keywords)))
|
||||||
|
|
||||||
(defun ruby-font-lock-docs (limit)
|
(defun ruby-font-lock-docs (limit)
|
||||||
(if (re-search-forward "^=begin\\(\\s \\|$\\)" limit t)
|
(if (re-search-forward "^=begin\\(\\s \\|$\\)" limit t)
|
||||||
@ -687,6 +690,21 @@ An end of a defun is found by moving forward from the beginning of one."
|
|||||||
(set-match-data (list beg (point)))
|
(set-match-data (list beg (point)))
|
||||||
t)))))
|
t)))))
|
||||||
|
|
||||||
|
(defun ruby-font-lock-maybe-docs (limit)
|
||||||
|
(let (beg)
|
||||||
|
(save-excursion
|
||||||
|
(if (and (re-search-backward "^=\\(begin\\|end\\)\\(\\s \\|$\\)" nil t)
|
||||||
|
(string= (match-string-no-properties 1) "begin"))
|
||||||
|
(progn
|
||||||
|
(beginning-of-line)
|
||||||
|
(setq beg (point)))))
|
||||||
|
(if (and beg (and (re-search-forward "^=\\(begin\\|end\\)\\(\\s \\|$\\)" nil t)
|
||||||
|
(string= (match-string-no-properties 1) "end")))
|
||||||
|
(progn
|
||||||
|
(set-match-data (list beg (point)))
|
||||||
|
t)
|
||||||
|
nil)))
|
||||||
|
|
||||||
(defvar ruby-font-lock-keywords
|
(defvar ruby-font-lock-keywords
|
||||||
(list
|
(list
|
||||||
(cons (concat
|
(cons (concat
|
||||||
@ -741,6 +759,8 @@ An end of a defun is found by moving forward from the beginning of one."
|
|||||||
;; embedded document
|
;; embedded document
|
||||||
'(ruby-font-lock-docs
|
'(ruby-font-lock-docs
|
||||||
0 font-lock-comment-face t)
|
0 font-lock-comment-face t)
|
||||||
|
'(ruby-font-lock-maybe-docs
|
||||||
|
0 font-lock-comment-face t)
|
||||||
;; constants
|
;; constants
|
||||||
'("\\(^\\|[^_]\\)\\b\\([A-Z]+\\(\\w\\|_\\)*\\)"
|
'("\\(^\\|[^_]\\)\\b\\([A-Z]+\\(\\w\\|_\\)*\\)"
|
||||||
2 font-lock-type-face)
|
2 font-lock-type-face)
|
||||||
|
31
regex.c
31
regex.c
@ -1874,8 +1874,10 @@ re_compile_pattern(pattern, size, bufp)
|
|||||||
if ((options ^ stackp[-1]) & RE_OPTION_IGNORECASE) {
|
if ((options ^ stackp[-1]) & RE_OPTION_IGNORECASE) {
|
||||||
BUFPUSH((options&RE_OPTION_IGNORECASE)?casefold_off:casefold_on);
|
BUFPUSH((options&RE_OPTION_IGNORECASE)?casefold_off:casefold_on);
|
||||||
}
|
}
|
||||||
BUFPUSH(option_set);
|
if ((options ^ stackp[-1]) != RE_OPTION_IGNORECASE) {
|
||||||
BUFPUSH(stackp[-1]);
|
BUFPUSH(option_set);
|
||||||
|
BUFPUSH(stackp[-1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
p0 = b;
|
p0 = b;
|
||||||
options = *--stackp;
|
options = *--stackp;
|
||||||
@ -3262,7 +3264,8 @@ re_search(bufp, string, size, startpos, range, regs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (startpos > size) return -1;
|
if (startpos > size) return -1;
|
||||||
if (anchor && size > 0 && startpos == size) return -1;
|
if ((anchor || !bufp->can_be_null) && size > 0 && startpos == size)
|
||||||
|
return -1;
|
||||||
val = re_match(bufp, string, size, startpos, regs);
|
val = re_match(bufp, string, size, startpos, regs);
|
||||||
if (val >= 0) return startpos;
|
if (val >= 0) return startpos;
|
||||||
if (val == -2) return -2;
|
if (val == -2) return -2;
|
||||||
@ -3362,7 +3365,7 @@ re_search(bufp, string, size, startpos, range, regs)
|
|||||||
#define NUM_COUNT_ITEMS 2
|
#define NUM_COUNT_ITEMS 2
|
||||||
|
|
||||||
/* Individual items aside from the registers. */
|
/* Individual items aside from the registers. */
|
||||||
#define NUM_NONREG_ITEMS 3
|
#define NUM_NONREG_ITEMS 4
|
||||||
|
|
||||||
/* We push at most this many things on the stack whenever we
|
/* We push at most this many things on the stack whenever we
|
||||||
fail. The `+ 2' refers to PATTERN_PLACE and STRING_PLACE, which are
|
fail. The `+ 2' refers to PATTERN_PLACE and STRING_PLACE, which are
|
||||||
@ -3412,6 +3415,7 @@ re_search(bufp, string, size, startpos, range, regs)
|
|||||||
\
|
\
|
||||||
*stackp++ = pattern_place; \
|
*stackp++ = pattern_place; \
|
||||||
*stackp++ = string_place; \
|
*stackp++ = string_place; \
|
||||||
|
*stackp++ = (unsigned char*)options; /* current option status */ \
|
||||||
*stackp++ = (unsigned char*)0; /* non-greedy flag */ \
|
*stackp++ = (unsigned char*)0; /* non-greedy flag */ \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
@ -3735,15 +3739,11 @@ re_match(bufp, string_arg, size, pos, regs)
|
|||||||
int regno = *p++; /* Get which register to match against */
|
int regno = *p++; /* Get which register to match against */
|
||||||
register unsigned char *d2, *dend2;
|
register unsigned char *d2, *dend2;
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Check if corresponding group is still open */
|
/* Check if corresponding group is still open */
|
||||||
if (IS_ACTIVE(reg_info[regno])) goto fail;
|
if (IS_ACTIVE(reg_info[regno])) goto fail;
|
||||||
|
|
||||||
/* Where in input to try to start matching. */
|
/* Where in input to try to start matching. */
|
||||||
d2 = regstart[regno];
|
d2 = regstart[regno];
|
||||||
#else
|
|
||||||
d2 = IS_ACTIVE(reg_info[regno])?old_regstart[regno]:regstart[regno];
|
|
||||||
#endif
|
|
||||||
if (REG_UNSET(d2)) goto fail;
|
if (REG_UNSET(d2)) goto fail;
|
||||||
|
|
||||||
/* Where to stop matching; if both the place to start and
|
/* Where to stop matching; if both the place to start and
|
||||||
@ -3791,7 +3791,7 @@ re_match(bufp, string_arg, size, pos, regs)
|
|||||||
case stop_nowidth:
|
case stop_nowidth:
|
||||||
EXTRACT_NUMBER_AND_INCR(mcnt, p);
|
EXTRACT_NUMBER_AND_INCR(mcnt, p);
|
||||||
stackp = stackb + mcnt;
|
stackp = stackb + mcnt;
|
||||||
d = stackp[-2];
|
d = stackp[-3];
|
||||||
POP_FAILURE_POINT();
|
POP_FAILURE_POINT();
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -4015,8 +4015,8 @@ re_match(bufp, string_arg, size, pos, regs)
|
|||||||
because didn't fail. Also remove the register information
|
because didn't fail. Also remove the register information
|
||||||
put on by the on_failure_jump. */
|
put on by the on_failure_jump. */
|
||||||
case finalize_jump:
|
case finalize_jump:
|
||||||
if (stackp > stackb && stackp[-2] == d) {
|
if (stackp > stackb && stackp[-3] == d) {
|
||||||
p = stackp[-3];
|
p = stackp[-4];
|
||||||
POP_FAILURE_POINT();
|
POP_FAILURE_POINT();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -4032,7 +4032,7 @@ re_match(bufp, string_arg, size, pos, regs)
|
|||||||
case jump:
|
case jump:
|
||||||
nofinalize:
|
nofinalize:
|
||||||
EXTRACT_NUMBER_AND_INCR(mcnt, p);
|
EXTRACT_NUMBER_AND_INCR(mcnt, p);
|
||||||
if (mcnt < 0 && stackp > stackb && stackp[-2] == d) /* avoid infinite loop */
|
if (mcnt < 0 && stackp > stackb && stackp[-3] == d) /* avoid infinite loop */
|
||||||
goto fail;
|
goto fail;
|
||||||
p += mcnt;
|
p += mcnt;
|
||||||
continue;
|
continue;
|
||||||
@ -4123,7 +4123,7 @@ re_match(bufp, string_arg, size, pos, regs)
|
|||||||
case finalize_push:
|
case finalize_push:
|
||||||
POP_FAILURE_POINT();
|
POP_FAILURE_POINT();
|
||||||
EXTRACT_NUMBER_AND_INCR(mcnt, p);
|
EXTRACT_NUMBER_AND_INCR(mcnt, p);
|
||||||
if (mcnt < 0 && stackp > stackb && stackp[-2] == d) /* avoid infinite loop */
|
if (mcnt < 0 && stackp > stackb && stackp[-3] == d) /* avoid infinite loop */
|
||||||
goto fail;
|
goto fail;
|
||||||
PUSH_FAILURE_POINT(p + mcnt, d);
|
PUSH_FAILURE_POINT(p + mcnt, d);
|
||||||
stackp[-1] = NON_GREEDY;
|
stackp[-1] = NON_GREEDY;
|
||||||
@ -4288,11 +4288,12 @@ re_match(bufp, string_arg, size, pos, regs)
|
|||||||
|
|
||||||
/* If this failure point is from a dummy_failure_point, just
|
/* If this failure point is from a dummy_failure_point, just
|
||||||
skip it. */
|
skip it. */
|
||||||
if (stackp[-3] == 0 || (best_regs_set && stackp[-1] == NON_GREEDY)) {
|
if (stackp[-4] == 0 || (best_regs_set && stackp[-1] == NON_GREEDY)) {
|
||||||
POP_FAILURE_POINT();
|
POP_FAILURE_POINT();
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
stackp--; /* discard flag */
|
stackp--; /* discard greedy flag */
|
||||||
|
options = (int)*--stackp;
|
||||||
d = *--stackp;
|
d = *--stackp;
|
||||||
p = *--stackp;
|
p = *--stackp;
|
||||||
/* Restore register info. */
|
/* Restore register info. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user