зеркало из https://github.com/github/ruby.git
19991214
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@587 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
c18d3740a9
Коммит
9d228b13de
52
ChangeLog
52
ChangeLog
|
@ -1,3 +1,55 @@
|
|||
Mon Dec 13 15:15:31 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* regex.c (re_adjust_startpos): separate startpos adjustment
|
||||
because of major performace drawback.
|
||||
|
||||
* class.c (rb_singleton_class): tainted status of the singleton
|
||||
class must synchronize with the object.
|
||||
|
||||
* eval.c (rb_thread_schedule): implement thread priority.
|
||||
|
||||
Sat Dec 11 03:34:38 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* gc.c (mark_hashentry): key should be VALUE, not ID.
|
||||
|
||||
* io.c (argf_eof): should check next_p too.
|
||||
|
||||
Thu Dec 9 18:09:13 1999 EGUCHI Osamu <eguchi@shizuokanet.ne.jp>
|
||||
|
||||
* error.c (exc_set_backtrace): forgot to declare a VALUE argument.
|
||||
|
||||
Thu Dec 9 14:19:31 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* object.c (rb_obj_taint): explicit tainting must be prohibited at
|
||||
level 4 to prevent polluting trusted object by untrusted code.
|
||||
|
||||
* file.c: file operations (stat, lstat, chmod, chown, umask,
|
||||
truncate, flock) are prohibited in level 2 (was level 4).
|
||||
|
||||
Wed Dec 8 11:48:23 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* eval.c (rb_f_require): prohibiting require() in the secure mode
|
||||
cause serious autoloading error.
|
||||
|
||||
* variable.c (rb_obj_instance_variables): don't need to prohibit
|
||||
to get list of instance variable names of untainted objects.
|
||||
|
||||
* variable.c (rb_ivar_get): don't need to prohibit to get instance
|
||||
variables of untainted objects.
|
||||
|
||||
* variable.c (rb_mod_remove_const): should prohibit constant
|
||||
removals too.
|
||||
|
||||
Wed Dec 8 09:23:01 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* eval.c (rb_eval): should try autoloading before defining
|
||||
class/module at the toplevel.
|
||||
|
||||
Tue Dec 7 22:15:30 1999 EGUCHI Osamu <eguchi@shizuokanet.ne.jp>
|
||||
|
||||
* configure.in: Modified rb_cv_rshift_sign detect routine and
|
||||
more simple/fast RSHIFT() for hpux-10.x.
|
||||
|
||||
Tue Dec 7 11:16:30 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* eval.c (Init_eval): calculate stack limit from rlimit where
|
||||
|
|
2
README
2
README
|
@ -135,7 +135,7 @@ You can redistribute it and/or modify it under either the terms of the GPL
|
|||
|
||||
The URL of the Ruby home-page is:
|
||||
|
||||
http://www.netlab.co.jp/ruby/
|
||||
http://www.ruby-lang.org/
|
||||
|
||||
* The Author
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ Ruby
|
|||
|
||||
RubyのホームページのURLは
|
||||
|
||||
http://www.netlab.co.jp/ruby/jp/
|
||||
http://www.ruby-lang.org/
|
||||
|
||||
です.
|
||||
|
||||
|
|
5
array.c
5
array.c
|
@ -49,7 +49,7 @@ rb_ary_modify(ary)
|
|||
rb_raise(rb_eTypeError, "can't modify frozen array");
|
||||
if (FL_TEST(ary, ARY_TMPLOCK))
|
||||
rb_raise(rb_eTypeError, "can't modify array during sort");
|
||||
if (!FL_TEST(ary, FL_TAINT) && rb_safe_level() >= 4)
|
||||
if (!OBJ_TAINTED(ary) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify array");
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,9 @@ VALUE
|
|||
rb_ary_freeze(ary)
|
||||
VALUE ary;
|
||||
{
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(ary))
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't freeze array");
|
||||
|
||||
FL_SET(ary, ARY_FREEZE);
|
||||
return ary;
|
||||
}
|
||||
|
|
27
class.c
27
class.c
|
@ -130,7 +130,7 @@ rb_define_class_under(outer, name, super)
|
|||
|
||||
id = rb_intern(name);
|
||||
klass = rb_define_class_id(id, super);
|
||||
rb_shvar_set(outer, id, klass);
|
||||
rb_const_set(outer, id, klass);
|
||||
rb_set_class_path(klass, outer, name);
|
||||
|
||||
return klass;
|
||||
|
@ -186,7 +186,7 @@ rb_define_module_under(outer, name)
|
|||
|
||||
id = rb_intern(name);
|
||||
module = rb_define_module_id(id);
|
||||
rb_shvar_set(outer, id, module);
|
||||
rb_const_set(outer, id, module);
|
||||
rb_set_class_path(module, outer, name);
|
||||
|
||||
return module;
|
||||
|
@ -368,7 +368,7 @@ method_list(mod, option, func)
|
|||
VALUE klass;
|
||||
VALUE *p, *q, *pend;
|
||||
|
||||
if (!FL_TEST(mod, FL_TAINT) && rb_safe_level() >= 4)
|
||||
if (!OBJ_TAINTED(mod) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't get metainfo");
|
||||
ary = rb_ary_new();
|
||||
for (klass = mod; klass; klass = RCLASS(klass)->super) {
|
||||
|
@ -431,7 +431,7 @@ rb_obj_singleton_methods(obj)
|
|||
VALUE klass;
|
||||
VALUE *p, *q, *pend;
|
||||
|
||||
if (rb_safe_level() >= 4 && !FL_TEST(obj, FL_TAINT))
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(obj))
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't get metainfo");
|
||||
ary = rb_ary_new();
|
||||
klass = CLASS_OF(obj);
|
||||
|
@ -510,15 +510,26 @@ VALUE
|
|||
rb_singleton_class(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
VALUE klass;
|
||||
if (rb_special_const_p(obj)) {
|
||||
rb_raise(rb_eTypeError, "can't define singleton");
|
||||
}
|
||||
if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON)) {
|
||||
return RBASIC(obj)->klass;
|
||||
klass = RBASIC(obj)->klass;
|
||||
}
|
||||
RBASIC(obj)->klass = rb_singleton_class_new(RBASIC(obj)->klass);
|
||||
rb_singleton_class_attached(RBASIC(obj)->klass, obj);
|
||||
return RBASIC(obj)->klass;
|
||||
else {
|
||||
klass = rb_singleton_class_new(RBASIC(obj)->klass);
|
||||
RBASIC(obj)->klass = klass;
|
||||
rb_singleton_class_attached(klass, obj);
|
||||
}
|
||||
if (OBJ_TAINTED(obj)) {
|
||||
OBJ_TAINT(klass);
|
||||
}
|
||||
else {
|
||||
FL_UNSET(klass, FL_TAINT);
|
||||
}
|
||||
|
||||
return klass;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -3783,7 +3783,7 @@ else
|
|||
int
|
||||
main()
|
||||
{
|
||||
if (-1==(-1>>(unsigned)1))
|
||||
if (-1==(-1>>1))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
@ -3806,7 +3806,7 @@ fi
|
|||
echo "$ac_t""$rb_cv_rshift_sign" 1>&6
|
||||
if test "$rb_cv_rshift_sign" = yes; then
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define RSHIFT(x,y) ((x)>>y)
|
||||
#define RSHIFT(x,y) ((x)>>(int)y)
|
||||
EOF
|
||||
|
||||
else
|
||||
|
|
|
@ -260,7 +260,7 @@ AC_CACHE_CHECK(whether right shift preserve sign bit, rb_cv_rshift_sign,
|
|||
int
|
||||
main()
|
||||
{
|
||||
if (-1==(-1>>(unsigned)1))
|
||||
if (-1==(-1>>1))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ main()
|
|||
rb_cv_rshift_sign=no,
|
||||
rb_cv_rshift_sign=yes)])
|
||||
if test "$rb_cv_rshift_sign" = yes; then
|
||||
AC_DEFINE(RSHIFT(x,y), ((x)>>y))
|
||||
AC_DEFINE(RSHIFT(x,y), ((x)>>(int)y))
|
||||
else
|
||||
AC_DEFINE(RSHIFT(x,y), (((x)<0) ? ~((~(x))>>y) : (x)>>y))
|
||||
fi
|
||||
|
|
4
dir.c
4
dir.c
|
@ -435,7 +435,6 @@ dir_s_mkdir(argc, argv, obj)
|
|||
VALUE path, vmode;
|
||||
int mode;
|
||||
|
||||
rb_secure(2);
|
||||
if (rb_scan_args(argc, argv, "11", &path, &vmode) == 2) {
|
||||
mode = NUM2INT(vmode);
|
||||
}
|
||||
|
@ -444,6 +443,7 @@ dir_s_mkdir(argc, argv, obj)
|
|||
}
|
||||
|
||||
Check_SafeStr(path);
|
||||
rb_secure(2);
|
||||
#if !defined(NT) && !defined(USE_CWGUSI)
|
||||
if (mkdir(RSTRING(path)->ptr, mode) == -1)
|
||||
rb_sys_fail(RSTRING(path)->ptr);
|
||||
|
@ -459,8 +459,8 @@ static VALUE
|
|||
dir_s_rmdir(obj, dir)
|
||||
VALUE obj, dir;
|
||||
{
|
||||
rb_secure(2);
|
||||
Check_SafeStr(dir);
|
||||
rb_secure(2);
|
||||
if (rmdir(RSTRING(dir)->ptr) < 0)
|
||||
rb_sys_fail(RSTRING(dir)->ptr);
|
||||
|
||||
|
|
3
error.c
3
error.c
|
@ -247,6 +247,7 @@ VALUE rb_eIndexError;
|
|||
VALUE rb_eLoadError;
|
||||
VALUE rb_eSecurityError;
|
||||
VALUE rb_eNotImpError;
|
||||
VALUE rb_eNoMemError;
|
||||
|
||||
VALUE rb_eSystemCallError;
|
||||
VALUE rb_mErrno;
|
||||
|
@ -387,6 +388,7 @@ check_backtrace(bt)
|
|||
static VALUE
|
||||
exc_set_backtrace(exc, bt)
|
||||
VALUE exc;
|
||||
VALUE bt;
|
||||
{
|
||||
return rb_iv_set(exc, "bt", check_backtrace(bt));
|
||||
}
|
||||
|
@ -541,6 +543,7 @@ Init_Exception()
|
|||
rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError);
|
||||
rb_eSecurityError = rb_define_class("SecurityError", rb_eStandardError);
|
||||
rb_eNotImpError = rb_define_class("NotImplementError", rb_eException);
|
||||
rb_eNoMemError = rb_define_class("NoMemoryError", rb_eException);
|
||||
|
||||
init_syserr();
|
||||
}
|
||||
|
|
477
eval.c
477
eval.c
|
@ -90,6 +90,73 @@ static int scope_vmode;
|
|||
#define SCOPE_SET(f) do {scope_vmode=(f);} while(0)
|
||||
#define SCOPE_TEST(f) (scope_vmode&(f))
|
||||
|
||||
static int safe_level = 0;
|
||||
/* safe-level:
|
||||
0 - strings from streams/environment/ARGV are tainted (default)
|
||||
1 - no dangerous operation by tainted string
|
||||
2 - process/file operations prohibited
|
||||
3 - all genetated strings are tainted
|
||||
4 - no global (non-tainted) variable modification/no direct output
|
||||
*/
|
||||
|
||||
int
|
||||
rb_safe_level()
|
||||
{
|
||||
return safe_level;
|
||||
}
|
||||
|
||||
void
|
||||
rb_set_safe_level(level)
|
||||
int level;
|
||||
{
|
||||
if (level > safe_level) {
|
||||
safe_level = level;
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
safe_getter()
|
||||
{
|
||||
return INT2FIX(safe_level);
|
||||
}
|
||||
|
||||
static void
|
||||
safe_setter(val)
|
||||
VALUE val;
|
||||
{
|
||||
int level = NUM2INT(val);
|
||||
|
||||
if (level < safe_level) {
|
||||
rb_raise(rb_eSecurityError, "tried to downgrade safe level from %d to %d",
|
||||
safe_level, level);
|
||||
}
|
||||
safe_level = level;
|
||||
}
|
||||
|
||||
void
|
||||
rb_check_safe_str(x)
|
||||
VALUE x;
|
||||
{
|
||||
if (safe_level > 0 && OBJ_TAINTED(x)){
|
||||
rb_raise(rb_eSecurityError, "Insecure operation - %s",
|
||||
rb_id2name(ruby_frame->last_func));
|
||||
}
|
||||
if (TYPE(x)!= T_STRING) {
|
||||
rb_raise(rb_eTypeError, "wrong argument type %s (expected String)",
|
||||
rb_class2name(CLASS_OF(x)));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rb_secure(level)
|
||||
int level;
|
||||
{
|
||||
if (level <= safe_level) {
|
||||
rb_raise(rb_eSecurityError, "Insecure operation `%s' for level %d",
|
||||
rb_id2name(ruby_frame->last_func), safe_level);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_undef _((VALUE, ID)) NORETURN;
|
||||
static void
|
||||
print_undef(klass, id)
|
||||
|
@ -158,6 +225,9 @@ rb_add_method(klass, mid, node, noex)
|
|||
if (klass == rb_cObject) {
|
||||
rb_secure(4);
|
||||
}
|
||||
if (safe_level >= 4 && !OBJ_TAINTED(klass)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't define method");
|
||||
}
|
||||
body = NEW_METHOD(node, noex);
|
||||
st_insert(RCLASS(klass)->m_tbl, mid, body);
|
||||
}
|
||||
|
@ -225,38 +295,6 @@ rb_get_method_body(klassp, idp, noexp)
|
|||
return body;
|
||||
}
|
||||
|
||||
void
|
||||
rb_alias(klass, name, def)
|
||||
VALUE klass;
|
||||
ID name, def;
|
||||
{
|
||||
VALUE origin;
|
||||
NODE *orig, *body;
|
||||
|
||||
if (name == def) return;
|
||||
if (klass == rb_cObject) {
|
||||
rb_secure(4);
|
||||
}
|
||||
orig = search_method(klass, def, &origin);
|
||||
if (!orig || !orig->nd_body) {
|
||||
if (TYPE(klass) == T_MODULE) {
|
||||
orig = search_method(rb_cObject, def, &origin);
|
||||
}
|
||||
}
|
||||
if (!orig || !orig->nd_body) {
|
||||
print_undef(klass, def);
|
||||
}
|
||||
body = orig->nd_body;
|
||||
if (nd_type(body) == NODE_FBODY) { /* was alias */
|
||||
def = body->nd_mid;
|
||||
origin = body->nd_orig;
|
||||
body = body->nd_head;
|
||||
}
|
||||
|
||||
st_insert(RCLASS(klass)->m_tbl, name,
|
||||
NEW_METHOD(NEW_FBODY(body, def, origin), orig->nd_noex));
|
||||
}
|
||||
|
||||
static void
|
||||
remove_method(klass, mid)
|
||||
VALUE klass;
|
||||
|
@ -267,6 +305,9 @@ remove_method(klass, mid)
|
|||
if (klass == rb_cObject) {
|
||||
rb_secure(4);
|
||||
}
|
||||
if (safe_level >= 4 && !OBJ_TAINTED(klass)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't remove method");
|
||||
}
|
||||
if (!st_delete(RCLASS(klass)->m_tbl, &mid, &body)) {
|
||||
rb_raise(rb_eNameError, "method `%s' not defined in %s",
|
||||
rb_id2name(mid), rb_class2name(klass));
|
||||
|
@ -282,6 +323,14 @@ rb_remove_method(klass, name)
|
|||
remove_method(klass, rb_intern(name));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_mod_remove_method(mod, name)
|
||||
VALUE mod, name;
|
||||
{
|
||||
remove_method(mod, rb_to_id(name));
|
||||
return mod;
|
||||
}
|
||||
|
||||
void
|
||||
rb_disable_super(klass, name)
|
||||
VALUE klass;
|
||||
|
@ -740,75 +789,6 @@ static VALUE module_setup _((VALUE,NODE*));
|
|||
static VALUE massign _((VALUE,NODE*,VALUE,int));
|
||||
static void assign _((VALUE,NODE*,VALUE,int));
|
||||
|
||||
static int safe_level = 0;
|
||||
/* safe-level:
|
||||
0 - strings from streams/environment/ARGV are tainted (default)
|
||||
1 - no dangerous operation by tainted string
|
||||
2 - process/file operations prohibited
|
||||
3 - all genetated strings are tainted
|
||||
4 - no global (non-tainted) variable modification/no direct output
|
||||
*/
|
||||
|
||||
int
|
||||
rb_safe_level()
|
||||
{
|
||||
return safe_level;
|
||||
}
|
||||
|
||||
void
|
||||
rb_set_safe_level(level)
|
||||
int level;
|
||||
{
|
||||
if (level > safe_level) {
|
||||
safe_level = level;
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
safe_getter()
|
||||
{
|
||||
return INT2FIX(safe_level);
|
||||
}
|
||||
|
||||
static void
|
||||
safe_setter(val)
|
||||
VALUE val;
|
||||
{
|
||||
int level = NUM2INT(val);
|
||||
|
||||
if (level < safe_level) {
|
||||
rb_raise(rb_eSecurityError, "tried to downgrade safe level from %d to %d",
|
||||
safe_level, level);
|
||||
}
|
||||
safe_level = level;
|
||||
}
|
||||
|
||||
void
|
||||
rb_check_safe_str(x)
|
||||
VALUE x;
|
||||
{
|
||||
if (TYPE(x)!= T_STRING) {
|
||||
rb_raise(rb_eTypeError, "wrong argument type %s (expected String)",
|
||||
rb_class2name(CLASS_OF(x)));
|
||||
}
|
||||
if (OBJ_TAINTED(x)) {
|
||||
if (safe_level > 0){
|
||||
rb_raise(rb_eSecurityError, "Insecure operation - %s",
|
||||
rb_id2name(ruby_frame->last_func));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rb_secure(level)
|
||||
int level;
|
||||
{
|
||||
if (level <= safe_level) {
|
||||
rb_raise(rb_eSecurityError, "Insecure operation `%s' for level %d",
|
||||
rb_id2name(ruby_frame->last_func), safe_level);
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE trace_func = 0;
|
||||
static void call_trace_func _((char*,char*,int,VALUE,ID,VALUE));
|
||||
|
||||
|
@ -1322,7 +1302,7 @@ superclass(self, node)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
ev_shvar_defined(cref, id)
|
||||
ev_const_defined(cref, id)
|
||||
NODE *cref;
|
||||
ID id;
|
||||
{
|
||||
|
@ -1337,11 +1317,11 @@ ev_shvar_defined(cref, id)
|
|||
}
|
||||
cbase = cbase->nd_next;
|
||||
}
|
||||
return rb_shvar_defined(cref->nd_clss, id);
|
||||
return rb_const_defined(cref->nd_clss, id);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
ev_shvar_get(cref, id)
|
||||
ev_const_get(cref, id)
|
||||
NODE *cref;
|
||||
ID id;
|
||||
{
|
||||
|
@ -1356,11 +1336,11 @@ ev_shvar_get(cref, id)
|
|||
}
|
||||
cbase = cbase->nd_next;
|
||||
}
|
||||
return rb_shvar_get(cref->nd_clss, id);
|
||||
return rb_const_get(cref->nd_clss, id);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
ev_shvar_set(cref, id, val)
|
||||
ev_const_set(cref, id, val)
|
||||
NODE *cref;
|
||||
ID id;
|
||||
VALUE val;
|
||||
|
@ -1377,7 +1357,7 @@ ev_shvar_set(cref, id, val)
|
|||
}
|
||||
cbase = cbase->nd_next;
|
||||
}
|
||||
rb_shvar_assign(cbase->nd_clss, id, val);
|
||||
rb_const_assign(cbase->nd_clss, id, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
@ -1395,47 +1375,103 @@ rb_mod_nesting()
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_mod_s_shvars()
|
||||
rb_mod_s_constants()
|
||||
{
|
||||
NODE *cbase = (NODE*)ruby_frame->cbase;
|
||||
VALUE ary = rb_ary_new();
|
||||
|
||||
while (cbase && cbase->nd_clss != rb_cObject) {
|
||||
rb_mod_shvar_at(cbase->nd_clss, ary);
|
||||
rb_mod_const_at(cbase->nd_clss, ary);
|
||||
cbase = cbase->nd_next;
|
||||
}
|
||||
|
||||
rb_mod_shvar_of(((NODE*)ruby_frame->cbase)->nd_clss, ary);
|
||||
rb_mod_const_of(((NODE*)ruby_frame->cbase)->nd_clss, ary);
|
||||
return ary;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_mod_remove_method(mod, name)
|
||||
VALUE mod, name;
|
||||
void
|
||||
rb_undef(klass, id)
|
||||
VALUE klass;
|
||||
ID id;
|
||||
{
|
||||
remove_method(mod, rb_to_id(name));
|
||||
return mod;
|
||||
VALUE origin;
|
||||
NODE *body;
|
||||
|
||||
if (safe_level >= 4 && !OBJ_TAINTED(klass)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't undef");
|
||||
}
|
||||
body = search_method(ruby_class, id, &origin);
|
||||
if (!body || !body->nd_body) {
|
||||
char *s0 = " class";
|
||||
VALUE c = klass;
|
||||
|
||||
if (FL_TEST(c, FL_SINGLETON)) {
|
||||
VALUE obj = rb_iv_get(klass, "__attached__");
|
||||
|
||||
switch (TYPE(obj)) {
|
||||
case T_MODULE:
|
||||
case T_CLASS:
|
||||
c = obj;
|
||||
s0 = "";
|
||||
}
|
||||
}
|
||||
else if (TYPE(c) == T_MODULE) {
|
||||
s0 = " module";
|
||||
}
|
||||
rb_raise(rb_eNameError, "undefined method `%s' for%s `%s'",
|
||||
rb_id2name(id),s0,rb_class2name(c));
|
||||
}
|
||||
rb_clear_cache_by_id(id);
|
||||
rb_add_method(klass, id, 0, NOEX_PUBLIC);
|
||||
rb_clear_cache_by_id(id);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_mod_undef_method(mod, name)
|
||||
VALUE mod, name;
|
||||
{
|
||||
ID id = rb_to_id(name);
|
||||
|
||||
rb_add_method(mod, id, 0, NOEX_PUBLIC);
|
||||
rb_clear_cache_by_id(id);
|
||||
rb_undef(mod, rb_to_id(name));
|
||||
return mod;
|
||||
}
|
||||
|
||||
void
|
||||
rb_alias(klass, name, def)
|
||||
VALUE klass;
|
||||
ID name, def;
|
||||
{
|
||||
VALUE origin;
|
||||
NODE *orig, *body;
|
||||
|
||||
if (name == def) return;
|
||||
if (klass == rb_cObject) {
|
||||
rb_secure(4);
|
||||
}
|
||||
orig = search_method(klass, def, &origin);
|
||||
if (!orig || !orig->nd_body) {
|
||||
if (TYPE(klass) == T_MODULE) {
|
||||
orig = search_method(rb_cObject, def, &origin);
|
||||
}
|
||||
}
|
||||
if (!orig || !orig->nd_body) {
|
||||
print_undef(klass, def);
|
||||
}
|
||||
body = orig->nd_body;
|
||||
if (nd_type(body) == NODE_FBODY) { /* was alias */
|
||||
def = body->nd_mid;
|
||||
origin = body->nd_orig;
|
||||
body = body->nd_head;
|
||||
}
|
||||
|
||||
st_insert(RCLASS(klass)->m_tbl, name,
|
||||
NEW_METHOD(NEW_FBODY(body, def, origin), orig->nd_noex));
|
||||
rb_clear_cache_by_id(name);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_mod_alias_method(mod, newname, oldname)
|
||||
VALUE mod, newname, oldname;
|
||||
{
|
||||
ID id = rb_to_id(newname);
|
||||
|
||||
rb_alias(mod, id, rb_to_id(oldname));
|
||||
rb_clear_cache_by_id(id);
|
||||
rb_alias(mod, rb_to_id(newname), rb_to_id(oldname));
|
||||
return mod;
|
||||
}
|
||||
|
||||
|
@ -1628,7 +1664,7 @@ is_defined(self, node, buf)
|
|||
break;
|
||||
|
||||
case NODE_CVAR:
|
||||
if (ev_shvar_defined((NODE*)ruby_frame->cbase, node->nd_vid)) {
|
||||
if (ev_const_defined((NODE*)ruby_frame->cbase, node->nd_vid)) {
|
||||
return "constant";
|
||||
}
|
||||
break;
|
||||
|
@ -1644,7 +1680,7 @@ is_defined(self, node, buf)
|
|||
switch (TYPE(val)) {
|
||||
case T_CLASS:
|
||||
case T_MODULE:
|
||||
if (rb_shvar_defined_at(val, node->nd_mid))
|
||||
if (rb_const_defined_at(val, node->nd_mid))
|
||||
return "constant";
|
||||
default:
|
||||
if (rb_method_boundp(val, node->nd_mid, 1)) {
|
||||
|
@ -2435,7 +2471,7 @@ rb_eval(self, node)
|
|||
rb_raise(rb_eTypeError, "no class/module to define constant");
|
||||
}
|
||||
result = rb_eval(self, node->nd_value);
|
||||
ev_shvar_set((NODE*)ruby_frame->cbase, node->nd_vid, result);
|
||||
ev_const_set((NODE*)ruby_frame->cbase, node->nd_vid, result);
|
||||
break;
|
||||
|
||||
case NODE_CDECL:
|
||||
|
@ -2443,7 +2479,7 @@ rb_eval(self, node)
|
|||
rb_raise(rb_eTypeError, "no class/module to define constant");
|
||||
}
|
||||
result = rb_eval(self, node->nd_value);
|
||||
rb_shvar_set(ruby_class, node->nd_vid, result);
|
||||
rb_const_set(ruby_class, node->nd_vid, result);
|
||||
break;
|
||||
|
||||
case NODE_LVAR:
|
||||
|
@ -2466,7 +2502,7 @@ rb_eval(self, node)
|
|||
break;
|
||||
|
||||
case NODE_CVAR:
|
||||
result = ev_shvar_get((NODE*)ruby_frame->cbase, node->nd_vid);
|
||||
result = ev_const_get((NODE*)ruby_frame->cbase, node->nd_vid);
|
||||
break;
|
||||
|
||||
case NODE_BLOCK_ARG:
|
||||
|
@ -2493,12 +2529,12 @@ rb_eval(self, node)
|
|||
default:
|
||||
return rb_funcall(klass, node->nd_mid, 0, 0);
|
||||
}
|
||||
result = rb_shvar_get(klass, node->nd_mid);
|
||||
result = rb_const_get(klass, node->nd_mid);
|
||||
}
|
||||
break;
|
||||
|
||||
case NODE_COLON3:
|
||||
result = rb_shvar_get(rb_cObject, node->nd_mid);
|
||||
result = rb_const_get(rb_cObject, node->nd_mid);
|
||||
break;
|
||||
|
||||
case NODE_NTH_REF:
|
||||
|
@ -2654,14 +2690,9 @@ rb_eval(self, node)
|
|||
rb_warn("re-defining Object#initialize may cause infinite loop");
|
||||
}
|
||||
body = search_method(ruby_class, node->nd_mid, &origin);
|
||||
if (body) {
|
||||
if (origin == ruby_class) {
|
||||
if (safe_level >= 4) {
|
||||
rb_raise(rb_eSecurityError, "re-defining method prohibited");
|
||||
}
|
||||
if (RTEST(ruby_verbose)) {
|
||||
rb_warning("discarding old %s", rb_id2name(node->nd_mid));
|
||||
}
|
||||
if (body){
|
||||
if (RTEST(ruby_verbose)) {
|
||||
rb_warning("discarding old %s", rb_id2name(node->nd_mid));
|
||||
}
|
||||
rb_clear_cache_by_id(node->nd_mid);
|
||||
}
|
||||
|
@ -2711,7 +2742,7 @@ rb_eval(self, node)
|
|||
rb_class2name(CLASS_OF(recv)));
|
||||
}
|
||||
|
||||
if (rb_safe_level() >= 4 && !FL_TEST(recv, FL_TAINT)) {
|
||||
if (safe_level >= 4 && !OBJ_TAINTED(recv)) {
|
||||
rb_raise(rb_eSecurityError, "can't define singleton method");
|
||||
}
|
||||
klass = rb_singleton_class(recv);
|
||||
|
@ -2733,40 +2764,14 @@ rb_eval(self, node)
|
|||
break;
|
||||
|
||||
case NODE_UNDEF:
|
||||
{
|
||||
VALUE origin;
|
||||
NODE *body;
|
||||
|
||||
if (NIL_P(ruby_class)) {
|
||||
rb_raise(rb_eTypeError, "no class to undef method");
|
||||
}
|
||||
if (ruby_class == rb_cObject) {
|
||||
rb_secure(4);
|
||||
}
|
||||
body = search_method(ruby_class, node->nd_mid, &origin);
|
||||
if (!body || !body->nd_body) {
|
||||
char *s0 = " class";
|
||||
VALUE klass = ruby_class;
|
||||
|
||||
if (FL_TEST(ruby_class, FL_SINGLETON)) {
|
||||
VALUE obj = rb_iv_get(ruby_class, "__attached__");
|
||||
switch (TYPE(obj)) {
|
||||
case T_MODULE:
|
||||
case T_CLASS:
|
||||
klass = obj;
|
||||
s0 = "";
|
||||
}
|
||||
}
|
||||
else if (TYPE(klass) == T_MODULE) {
|
||||
s0 = " module";
|
||||
}
|
||||
rb_raise(rb_eNameError, "undefined method `%s' for%s `%s'",
|
||||
rb_id2name(node->nd_mid),s0,rb_class2name(klass));
|
||||
}
|
||||
rb_clear_cache_by_id(node->nd_mid);
|
||||
rb_add_method(ruby_class, node->nd_mid, 0, NOEX_PUBLIC);
|
||||
result = Qnil;
|
||||
if (NIL_P(ruby_class)) {
|
||||
rb_raise(rb_eTypeError, "no class to undef method");
|
||||
}
|
||||
if (ruby_class == rb_cObject) {
|
||||
rb_secure(4);
|
||||
}
|
||||
rb_undef(ruby_class, node->nd_mid);
|
||||
result = Qnil;
|
||||
break;
|
||||
|
||||
case NODE_ALIAS:
|
||||
|
@ -2799,12 +2804,16 @@ rb_eval(self, node)
|
|||
}
|
||||
|
||||
klass = 0;
|
||||
if (rb_shvar_defined_at(ruby_class, node->nd_cname) &&
|
||||
(ruby_class != rb_cObject || !rb_autoload_defined(node->nd_cname))) {
|
||||
klass = rb_shvar_get(ruby_class, node->nd_cname);
|
||||
if ((ruby_class == rb_cObject || ruby_class == ruby_wrapper) &&
|
||||
rb_autoload_defined(node->nd_cname)) {
|
||||
rb_autoload_load(node->nd_cname);
|
||||
}
|
||||
if (ruby_wrapper && rb_shvar_defined_at(rb_cObject, node->nd_cname)) {
|
||||
klass = rb_shvar_get(rb_cObject, node->nd_cname);
|
||||
if (rb_const_defined_at(ruby_class, node->nd_cname)) {
|
||||
klass = rb_const_get(ruby_class, node->nd_cname);
|
||||
}
|
||||
if (!klass && ruby_class == ruby_wrapper &&
|
||||
rb_const_defined_at(rb_cObject, node->nd_cname)) {
|
||||
klass = rb_const_get(rb_cObject, node->nd_cname);
|
||||
}
|
||||
if (klass) {
|
||||
if (TYPE(klass) != T_CLASS) {
|
||||
|
@ -2832,7 +2841,7 @@ rb_eval(self, node)
|
|||
else {
|
||||
if (!super) super = rb_cObject;
|
||||
klass = rb_define_class_id(node->nd_cname, super);
|
||||
rb_shvar_set(ruby_class, node->nd_cname, klass);
|
||||
rb_const_set(ruby_class, node->nd_cname, klass);
|
||||
rb_set_class_path(klass,ruby_class,rb_id2name(node->nd_cname));
|
||||
}
|
||||
if (ruby_wrapper) {
|
||||
|
@ -2852,13 +2861,16 @@ rb_eval(self, node)
|
|||
rb_raise(rb_eTypeError, "no outer class/module");
|
||||
}
|
||||
module = 0;
|
||||
if (rb_shvar_defined_at(ruby_class, node->nd_cname) &&
|
||||
(ruby_class != rb_cObject ||
|
||||
!rb_autoload_defined(node->nd_cname))) {
|
||||
module = rb_shvar_get(ruby_class, node->nd_cname);
|
||||
if ((ruby_class == rb_cObject || ruby_class == ruby_wrapper) &&
|
||||
rb_autoload_defined(node->nd_cname)) {
|
||||
rb_autoload_load(node->nd_cname);
|
||||
}
|
||||
if (ruby_wrapper && rb_shvar_defined_at(rb_cObject, node->nd_cname)) {
|
||||
module = rb_shvar_get(rb_cObject, node->nd_cname);
|
||||
if (rb_const_defined_at(ruby_class, node->nd_cname)) {
|
||||
module = rb_const_get(ruby_class, node->nd_cname);
|
||||
}
|
||||
if (!module && ruby_class == ruby_wrapper &&
|
||||
rb_const_defined_at(rb_cObject, node->nd_cname)) {
|
||||
module = rb_const_get(rb_cObject, node->nd_cname);
|
||||
}
|
||||
if (module) {
|
||||
if (TYPE(module) != T_MODULE) {
|
||||
|
@ -2871,7 +2883,7 @@ rb_eval(self, node)
|
|||
}
|
||||
else {
|
||||
module = rb_define_module_id(node->nd_cname);
|
||||
rb_shvar_set(ruby_class, node->nd_cname, module);
|
||||
rb_const_set(ruby_class, node->nd_cname, module);
|
||||
rb_set_class_path(module,ruby_class,rb_id2name(node->nd_cname));
|
||||
}
|
||||
if (ruby_wrapper) {
|
||||
|
@ -2892,10 +2904,13 @@ rb_eval(self, node)
|
|||
rb_raise(rb_eTypeError, "no virtual class for %s",
|
||||
rb_class2name(CLASS_OF(klass)));
|
||||
}
|
||||
if (safe_level >= 4 && !OBJ_TAINTED(klass))
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't extend object");
|
||||
if (FL_TEST(CLASS_OF(klass), FL_SINGLETON)) {
|
||||
rb_clear_cache();
|
||||
}
|
||||
klass = rb_singleton_class(klass);
|
||||
|
||||
if (ruby_wrapper) {
|
||||
rb_extend_object(klass, ruby_wrapper);
|
||||
rb_include_module(klass, ruby_wrapper);
|
||||
|
@ -3414,11 +3429,11 @@ assign(self, lhs, val, check)
|
|||
break;
|
||||
|
||||
case NODE_CASGN:
|
||||
ev_shvar_set((NODE*)ruby_frame->cbase, lhs->nd_vid, val);
|
||||
ev_const_set((NODE*)ruby_frame->cbase, lhs->nd_vid, val);
|
||||
break;
|
||||
|
||||
case NODE_CDECL:
|
||||
rb_shvar_set(ruby_class, lhs->nd_vid, val);
|
||||
rb_const_set(ruby_class, lhs->nd_vid, val);
|
||||
break;
|
||||
|
||||
case NODE_MASGN:
|
||||
|
@ -4557,7 +4572,7 @@ static VALUE
|
|||
yield_under(under, self)
|
||||
VALUE under, self;
|
||||
{
|
||||
if (rb_safe_level() >= 4 && !FL_TEST(self, FL_TAINT))
|
||||
if (safe_level >= 4 && !OBJ_TAINTED(self))
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't eval");
|
||||
return exec_under(yield_under_i, under, self);
|
||||
}
|
||||
|
@ -4649,7 +4664,6 @@ static char*
|
|||
find_file(file)
|
||||
char *file;
|
||||
{
|
||||
extern VALUE rb_load_path;
|
||||
volatile VALUE vpath;
|
||||
char *path;
|
||||
|
||||
|
@ -4692,7 +4706,7 @@ find_file(file)
|
|||
vpath = rb_ary_join(vpath, rb_str_new2(PATH_SEP));
|
||||
path = STR2CSTR(vpath);
|
||||
if (safe_level >= 2 && !rb_path_check(path)) {
|
||||
rb_raise(rb_eSecurityError, "loading from unsefe path %s", path);
|
||||
rb_raise(rb_eSecurityError, "loading from unsafe path %s", path);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -4868,8 +4882,8 @@ rb_f_require(obj, fname)
|
|||
char *ext, *file, *feature, *buf; /* OK */
|
||||
volatile VALUE load;
|
||||
int state;
|
||||
volatile int safe = safe_level;
|
||||
|
||||
rb_secure(4);
|
||||
Check_SafeStr(fname);
|
||||
if (rb_provided(RSTRING(fname)->ptr))
|
||||
return Qfalse;
|
||||
|
@ -4936,6 +4950,7 @@ rb_f_require(obj, fname)
|
|||
return Qtrue;
|
||||
|
||||
load_rb:
|
||||
safe_level = 0;
|
||||
if (rb_thread_loading(feature)) return Qfalse;
|
||||
rb_provide(feature);
|
||||
|
||||
|
@ -4945,6 +4960,7 @@ rb_f_require(obj, fname)
|
|||
}
|
||||
POP_TAG();
|
||||
rb_thread_loading_done(feature);
|
||||
safe_level = safe;
|
||||
if (state) JUMP_TAG(state);
|
||||
|
||||
return Qtrue;
|
||||
|
@ -5399,9 +5415,7 @@ Init_eval()
|
|||
rb_define_private_method(rb_cModule, "alias_method", rb_mod_alias_method, 2);
|
||||
|
||||
rb_define_singleton_method(rb_cModule, "nesting", rb_mod_nesting, 0);
|
||||
rb_define_singleton_method(rb_cModule, "shared_variables", rb_mod_s_shvars, 0);
|
||||
/* to be removed at 1.6 */
|
||||
rb_define_singleton_method(rb_cModule, "constants", rb_mod_s_shvars, 0);
|
||||
rb_define_singleton_method(rb_cModule, "constants", rb_mod_s_constants, 0);
|
||||
|
||||
rb_define_singleton_method(ruby_top_self, "include", top_include, -1);
|
||||
rb_define_singleton_method(ruby_top_self, "public", top_public, -1);
|
||||
|
@ -5617,7 +5631,7 @@ static void
|
|||
proc_save_safe_level(data)
|
||||
VALUE data;
|
||||
{
|
||||
if (FL_TEST(data, FL_TAINT)) {
|
||||
if (OBJ_TAINTED(data)) {
|
||||
switch (safe_level) {
|
||||
case 3:
|
||||
FL_SET(data, PROC_T3);
|
||||
|
@ -5636,7 +5650,7 @@ static void
|
|||
proc_set_safe_level(data)
|
||||
VALUE data;
|
||||
{
|
||||
if (FL_TEST(data, FL_TAINT)) {
|
||||
if (OBJ_TAINTED(data)) {
|
||||
switch (RBASIC(data)->flags & PROC_TMASK) {
|
||||
case PROC_T3:
|
||||
safe_level = 3;
|
||||
|
@ -5923,8 +5937,8 @@ rb_obj_method(obj, vid)
|
|||
data->body = body;
|
||||
data->oklass = CLASS_OF(obj);
|
||||
data->oid = rb_to_id(vid);
|
||||
if (FL_TEST(obj, FL_TAINT)) {
|
||||
FL_SET(method, FL_TAINT);
|
||||
if (OBJ_TAINTED(obj)) {
|
||||
OBJ_TAINT(method);
|
||||
}
|
||||
|
||||
return method;
|
||||
|
@ -5944,8 +5958,8 @@ method_call(argc, argv, method)
|
|||
Data_Get_Struct(method, struct METHOD, data);
|
||||
PUSH_ITER(rb_iterator_p()?ITER_PRE:ITER_NOT);
|
||||
PUSH_TAG(PROT_NONE);
|
||||
if (FL_TEST(data->recv, FL_TAINT) || FL_TEST(method, FL_TAINT)) {
|
||||
FL_SET(method, FL_TAINT);
|
||||
if (OBJ_TAINTED(data->recv) || OBJ_TAINTED(method)) {
|
||||
OBJ_TAINT(method);
|
||||
if (safe_level < 4) safe_level = 4;
|
||||
}
|
||||
if ((state = EXEC_TAG()) == 0) {
|
||||
|
@ -6140,6 +6154,7 @@ struct thread {
|
|||
thread_t join;
|
||||
|
||||
int abort;
|
||||
int priority;
|
||||
|
||||
st_table *locals;
|
||||
|
||||
|
@ -6270,8 +6285,8 @@ rb_thread_save_context(th)
|
|||
th->stk_len = 0;
|
||||
th->stk_pos = (rb_gc_stack_start<(VALUE*)&v)?rb_gc_stack_start
|
||||
:rb_gc_stack_start - len;
|
||||
if (len > th->stk_max) {
|
||||
REALLOC_N(th->stk_ptr, VALUE, len);
|
||||
if (len > th->stk_max) {
|
||||
REALLOC_N(th->stk_ptr, VALUE, len);
|
||||
th->stk_max = len;
|
||||
}
|
||||
th->stk_len = len;
|
||||
|
@ -6501,8 +6516,8 @@ rb_thread_schedule()
|
|||
|
||||
FOREACH_THREAD_FROM(curr, th) {
|
||||
if (th->status != THREAD_STOPPED && th->status != THREAD_KILLED) {
|
||||
next = th;
|
||||
break;
|
||||
if (!next || next->priority < th->priority)
|
||||
next = th;
|
||||
}
|
||||
}
|
||||
END_FOREACH_FROM(curr, th);
|
||||
|
@ -6514,7 +6529,8 @@ rb_thread_schedule()
|
|||
th->wait_for &= ~WAIT_JOIN;
|
||||
th->status = THREAD_RUNNABLE;
|
||||
num_waiting_on_join--;
|
||||
if (!next) next = th;
|
||||
if (!next || next->priority < th->priority)
|
||||
next = th;
|
||||
}
|
||||
}
|
||||
END_FOREACH_FROM(curr, th);
|
||||
|
@ -6600,7 +6616,8 @@ rb_thread_schedule()
|
|||
th->fd = 0;
|
||||
th->wait_for &= ~WAIT_FD;
|
||||
num_waiting_on_fd--;
|
||||
if (!next) next = th; /* Found one. */
|
||||
if (!next || next->priority < th->priority)
|
||||
next = th; /* Found one. */
|
||||
}
|
||||
}
|
||||
END_FOREACH_FROM(curr, th);
|
||||
|
@ -6972,6 +6989,31 @@ rb_thread_sleep_forever()
|
|||
rb_thread_schedule();
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_thread_priority(thread)
|
||||
VALUE thread;
|
||||
{
|
||||
thread_t th = rb_thread_check(thread);;
|
||||
|
||||
if (safe_level >= 4 && th != curr_thread) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't get priority");
|
||||
}
|
||||
return INT2NUM(th->priority);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_thread_priority_set(thread, prio)
|
||||
VALUE thread, prio;
|
||||
{
|
||||
thread_t th;
|
||||
|
||||
rb_secure(4);
|
||||
th = rb_thread_check(thread);
|
||||
|
||||
th->priority = NUM2INT(prio);
|
||||
return thread;
|
||||
}
|
||||
|
||||
static int thread_abort;
|
||||
|
||||
static VALUE
|
||||
|
@ -6984,6 +7026,7 @@ static VALUE
|
|||
rb_thread_s_abort_exc_set(self, val)
|
||||
VALUE self, val;
|
||||
{
|
||||
rb_secure(4);
|
||||
thread_abort = RTEST(val);
|
||||
return val;
|
||||
}
|
||||
|
@ -7003,6 +7046,7 @@ rb_thread_abort_exc_set(thread, val)
|
|||
{
|
||||
thread_t th = rb_thread_check(thread);
|
||||
|
||||
rb_secure(4);
|
||||
th->abort = RTEST(val);
|
||||
return val;
|
||||
}
|
||||
|
@ -7035,6 +7079,7 @@ rb_thread_abort_exc_set(thread, val)
|
|||
th->last_line = 0;\
|
||||
th->last_match = 0;\
|
||||
th->abort = 0;\
|
||||
th->priority = 0;\
|
||||
th->locals = 0;\
|
||||
} while(0)
|
||||
|
||||
|
@ -7052,6 +7097,7 @@ rb_thread_alloc(klass)
|
|||
curr_thread->next->prev = th;
|
||||
th->next = curr_thread->next;
|
||||
curr_thread->next = th;
|
||||
th->priority = curr_thread->priority;
|
||||
}
|
||||
else {
|
||||
curr_thread = th->prev = th->next = th;
|
||||
|
@ -7278,13 +7324,13 @@ rb_thread_cleanup()
|
|||
int rb_thread_critical;
|
||||
|
||||
static VALUE
|
||||
rb_thread_get_critical()
|
||||
rb_thread_critical_get()
|
||||
{
|
||||
return rb_thread_critical?Qtrue:Qfalse;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_thread_set_critical(obj, val)
|
||||
rb_thread_critical_set(obj, val)
|
||||
VALUE obj, val;
|
||||
{
|
||||
rb_thread_critical = RTEST(val);
|
||||
|
@ -7417,6 +7463,9 @@ rb_thread_local_aref(thread, id)
|
|||
VALUE val;
|
||||
|
||||
th = rb_thread_check(thread);
|
||||
if (safe_level >= 4 && th != curr_thread) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: thread locals");
|
||||
}
|
||||
if (!th->locals) return Qnil;
|
||||
if (st_lookup(th->locals, id, &val)) {
|
||||
return val;
|
||||
|
@ -7439,8 +7488,9 @@ rb_thread_local_aset(thread, id, val)
|
|||
{
|
||||
thread_t th = rb_thread_check(thread);
|
||||
|
||||
if (safe_level >= 4 && !FL_TEST(thread, FL_TAINT))
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify thread values");
|
||||
if (safe_level >= 4 && th != curr_thread) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify thread locals");
|
||||
}
|
||||
|
||||
if (!th->locals) {
|
||||
th->locals = st_init_numtable();
|
||||
|
@ -7541,8 +7591,8 @@ Init_Thread()
|
|||
rb_define_singleton_method(rb_cThread, "current", rb_thread_current, 0);
|
||||
rb_define_singleton_method(rb_cThread, "main", rb_thread_main, 0);
|
||||
|
||||
rb_define_singleton_method(rb_cThread, "critical", rb_thread_get_critical, 0);
|
||||
rb_define_singleton_method(rb_cThread, "critical=", rb_thread_set_critical, 1);
|
||||
rb_define_singleton_method(rb_cThread, "critical", rb_thread_critical_get, 0);
|
||||
rb_define_singleton_method(rb_cThread, "critical=", rb_thread_critical_set, 1);
|
||||
|
||||
rb_define_singleton_method(rb_cThread, "abort_on_exception", rb_thread_s_abort_exc, 0);
|
||||
rb_define_singleton_method(rb_cThread, "abort_on_exception=", rb_thread_s_abort_exc_set, 1);
|
||||
|
@ -7560,6 +7610,9 @@ Init_Thread()
|
|||
rb_define_method(rb_cThread, "abort_on_exception", rb_thread_abort_exc, 0);
|
||||
rb_define_method(rb_cThread, "abort_on_exception=", rb_thread_abort_exc_set, 1);
|
||||
|
||||
rb_define_method(rb_cThread, "priority", rb_thread_priority, 0);
|
||||
rb_define_method(rb_cThread, "priority=", rb_thread_priority_set, 1);
|
||||
|
||||
rb_define_method(rb_cThread, "[]", rb_thread_aref, 1);
|
||||
rb_define_method(rb_cThread, "[]=", rb_thread_aset, 2);
|
||||
rb_define_method(rb_cThread, "key?", rb_thread_key_p, 1);
|
||||
|
|
|
@ -315,19 +315,12 @@ fdbm_store(obj, keystr, valstr)
|
|||
struct dbmdata *dbmp;
|
||||
DBM *dbm;
|
||||
|
||||
if (valstr == Qnil) {
|
||||
fdbm_delete(obj, keystr);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
rb_secure(4);
|
||||
keystr = rb_obj_as_string(keystr);
|
||||
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
|
||||
if (NIL_P(valstr)) return fdbm_delete(obj, keystr);
|
||||
|
||||
valstr = rb_obj_as_string(valstr);
|
||||
val.dptr = RSTRING(valstr)->ptr;
|
||||
val.dsize = RSTRING(valstr)->len;
|
||||
|
|
|
@ -169,7 +169,7 @@ fgdbm_delete(obj, keystr)
|
|||
|
||||
if (gdbm_delete(dbm, key)) {
|
||||
dbmp->di_size = -1;
|
||||
rb_raise(rb_eRuntimeError, "dbm_delete failed");
|
||||
rb_raise(rb_eRuntimeError, "gdbm_delete failed");
|
||||
}
|
||||
else if (dbmp->di_size >= 0) {
|
||||
dbmp->di_size--;
|
||||
|
@ -218,7 +218,7 @@ fgdbm_delete_if(obj)
|
|||
valstr = rb_tainted_str_new(val.dptr, val.dsize);
|
||||
if (RTEST(rb_yield(rb_assoc_new(keystr, valstr)))) {
|
||||
if (gdbm_delete(dbm, key)) {
|
||||
rb_raise(rb_eRuntimeError, "dbm_delete failed");
|
||||
rb_raise(rb_eRuntimeError, "gdbm_delete failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -240,7 +240,7 @@ fgdbm_clear(obj)
|
|||
for (key = gdbm_firstkey(dbm); key.dptr; key = nextkey) {
|
||||
nextkey = gdbm_nextkey(dbm, key);
|
||||
if (gdbm_delete(dbm, key)) {
|
||||
rb_raise(rb_eRuntimeError, "dbm_delete failed");
|
||||
rb_raise(rb_eRuntimeError, "gdbm_delete failed");
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
|
@ -313,19 +313,12 @@ fgdbm_store(obj, keystr, valstr)
|
|||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
|
||||
if (valstr == Qnil) {
|
||||
fgdbm_delete(obj, keystr);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
rb_secure(4);
|
||||
keystr = rb_obj_as_string(keystr);
|
||||
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
|
||||
if (NIL_P(valstr)) return fgdbm_delete(obj, keystr);
|
||||
|
||||
valstr = rb_obj_as_string(valstr);
|
||||
val.dptr = RSTRING(valstr)->ptr;
|
||||
val.dsize = RSTRING(valstr)->len;
|
||||
|
@ -335,7 +328,7 @@ fgdbm_store(obj, keystr, valstr)
|
|||
dbm = dbmp->di_dbm;
|
||||
if (gdbm_store(dbm, key, val, GDBM_REPLACE)) {
|
||||
if (errno == EPERM) rb_sys_fail(0);
|
||||
rb_raise(rb_eRuntimeError, "dbm_store failed");
|
||||
rb_raise(rb_eRuntimeError, "gdbm_store failed");
|
||||
}
|
||||
|
||||
return valstr;
|
||||
|
|
|
@ -115,7 +115,6 @@ sock_new(class, fd)
|
|||
NEWOBJ(sock, struct RFile);
|
||||
OBJSETUP(sock, class, T_FILE);
|
||||
|
||||
rb_secure(4);
|
||||
MakeOpenFile(sock, fp);
|
||||
fp->f = rb_fdopen(fd, "r");
|
||||
#ifdef NT
|
||||
|
@ -140,7 +139,9 @@ bsock_shutdown(argc, argv, sock)
|
|||
int how;
|
||||
OpenFile *fptr;
|
||||
|
||||
rb_secure(4);
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't shutdown socket");
|
||||
}
|
||||
rb_scan_args(argc, argv, "01", &howto);
|
||||
if (howto == Qnil)
|
||||
how = 2;
|
||||
|
@ -163,7 +164,9 @@ bsock_close_read(sock)
|
|||
{
|
||||
OpenFile *fptr;
|
||||
|
||||
rb_secure(4);
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't close socket");
|
||||
}
|
||||
GetOpenFile(sock, fptr);
|
||||
shutdown(fileno(fptr->f), 0);
|
||||
if (fptr->f2 == 0) {
|
||||
|
@ -188,7 +191,9 @@ bsock_close_write(sock)
|
|||
{
|
||||
OpenFile *fptr;
|
||||
|
||||
rb_secure(4);
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't close socket");
|
||||
}
|
||||
GetOpenFile(sock, fptr);
|
||||
if (fptr->f2 == 0) {
|
||||
return rb_io_close(sock);
|
||||
|
@ -215,7 +220,6 @@ bsock_setsockopt(sock, lev, optname, val)
|
|||
char *v;
|
||||
int vlen;
|
||||
|
||||
rb_secure(2);
|
||||
level = NUM2INT(lev);
|
||||
option = NUM2INT(optname);
|
||||
switch (TYPE(val)) {
|
||||
|
@ -794,6 +798,9 @@ socks_s_close(sock)
|
|||
{
|
||||
OpenFile *fptr;
|
||||
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't close socket");
|
||||
}
|
||||
GetOpenFile(sock, fptr);
|
||||
shutdown(fileno(fptr->f), 2);
|
||||
shutdown(fileno(fptr->f2), 2);
|
||||
|
|
|
@ -2150,7 +2150,7 @@ class TkListbox<TkTextWin
|
|||
def nearest(y)
|
||||
tk_send('nearest', y).to_i
|
||||
end
|
||||
def size(y)
|
||||
def size
|
||||
tk_send('size').to_i
|
||||
end
|
||||
def selection_anchor(index)
|
||||
|
@ -2159,8 +2159,8 @@ class TkListbox<TkTextWin
|
|||
def selection_clear(first, last=None)
|
||||
tk_send 'selection', 'clear', first, last
|
||||
end
|
||||
def selection_includes
|
||||
bool(tk_send('selection', 'includes'))
|
||||
def selection_includes(index)
|
||||
bool(tk_send('selection', 'includes', index))
|
||||
end
|
||||
def selection_set(first, last=None)
|
||||
tk_send 'selection', 'set', first, last
|
||||
|
|
21
file.c
21
file.c
|
@ -102,7 +102,7 @@ rb_file_path(obj)
|
|||
OpenFile *fptr;
|
||||
|
||||
GetOpenFile(obj, fptr);
|
||||
if (fptr->path == NULL) return Qnil;
|
||||
if (!fptr->path) return Qnil;
|
||||
return rb_str_new2(fptr->path);
|
||||
}
|
||||
|
||||
|
@ -261,7 +261,7 @@ rb_stat(file, st)
|
|||
if (TYPE(file) == T_FILE) {
|
||||
OpenFile *fptr;
|
||||
|
||||
rb_secure(4);
|
||||
rb_secure(2);
|
||||
GetOpenFile(file, fptr);
|
||||
return fstat(fileno(fptr->f), st);
|
||||
}
|
||||
|
@ -325,8 +325,9 @@ rb_file_lstat(obj)
|
|||
OpenFile *fptr;
|
||||
struct stat st;
|
||||
|
||||
rb_secure(4);
|
||||
rb_secure(2);
|
||||
GetOpenFile(obj, fptr);
|
||||
if (!fptr->path) return Qnil;
|
||||
if (lstat(fptr->path, &st) == -1) {
|
||||
rb_sys_fail(fptr->path);
|
||||
}
|
||||
|
@ -463,8 +464,8 @@ test_l(obj, fname)
|
|||
Check_SafeStr(fname);
|
||||
if (lstat(RSTRING(fname)->ptr, &st) < 0) return Qfalse;
|
||||
if (S_ISLNK(st.st_mode)) return Qtrue;
|
||||
|
||||
#endif
|
||||
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
|
@ -896,11 +897,12 @@ rb_file_chmod(obj, vmode)
|
|||
OpenFile *fptr;
|
||||
int mode;
|
||||
|
||||
rb_secure(4);
|
||||
rb_secure(2);
|
||||
mode = NUM2INT(vmode);
|
||||
|
||||
GetOpenFile(obj, fptr);
|
||||
#if defined(DJGPP) || defined(NT) || defined(USE_CWGUSI) || defined(__BEOS__) || defined(__EMX__)
|
||||
if (!fptr->path) return Qnil;
|
||||
if (chmod(fptr->path, mode) == -1)
|
||||
rb_sys_fail(fptr->path);
|
||||
#else
|
||||
|
@ -957,9 +959,10 @@ rb_file_chown(obj, owner, group)
|
|||
{
|
||||
OpenFile *fptr;
|
||||
|
||||
rb_secure(4);
|
||||
rb_secure(2);
|
||||
GetOpenFile(obj, fptr);
|
||||
#if defined(DJGPP) || defined(__CYGWIN32__) || defined(NT) || defined(USE_CWGUSI) || defined(__EMX__)
|
||||
if (!fptr->path) return Qnil;
|
||||
if (chown(fptr->path, NUM2INT(owner), NUM2INT(group)) == -1)
|
||||
rb_sys_fail(fptr->path);
|
||||
#else
|
||||
|
@ -1147,7 +1150,7 @@ rb_file_s_umask(argc, argv)
|
|||
#else
|
||||
int omask = 0;
|
||||
|
||||
rb_secure(4);
|
||||
rb_secure(2);
|
||||
if (argc == 0) {
|
||||
omask = umask(0);
|
||||
umask(omask);
|
||||
|
@ -1426,7 +1429,7 @@ rb_file_truncate(obj, len)
|
|||
{
|
||||
OpenFile *fptr;
|
||||
|
||||
rb_secure(4);
|
||||
rb_secure(2);
|
||||
GetOpenFile(obj, fptr);
|
||||
if (!(fptr->mode & FMODE_WRITABLE)) {
|
||||
rb_raise(rb_eIOError, "not opened for writing");
|
||||
|
@ -1494,7 +1497,7 @@ rb_file_flock(obj, operation)
|
|||
#else
|
||||
OpenFile *fptr;
|
||||
|
||||
rb_secure(4);
|
||||
rb_secure(2);
|
||||
GetOpenFile(obj, fptr);
|
||||
|
||||
if (flock(fileno(fptr->f), NUM2INT(operation)) < 0) {
|
||||
|
|
30
gc.c
30
gc.c
|
@ -51,6 +51,17 @@ static unsigned long alloc_objects = 0;
|
|||
|
||||
static int malloc_called = 0;
|
||||
static int free_called = 0;
|
||||
static int second_mem_error = 0;
|
||||
|
||||
static void
|
||||
mem_error(mesg)
|
||||
char *mesg;
|
||||
{
|
||||
if (rb_safe_level() >= 4) {
|
||||
rb_raise(rb_eNoMemError, mesg);
|
||||
}
|
||||
rb_fatal(mesg);
|
||||
}
|
||||
|
||||
#ifndef xmalloc
|
||||
void *
|
||||
|
@ -72,8 +83,12 @@ xmalloc(size)
|
|||
if (!mem) {
|
||||
rb_gc();
|
||||
mem = malloc(size);
|
||||
if (!mem)
|
||||
rb_fatal("failed to allocate memory");
|
||||
if (!mem) {
|
||||
if (size >= 10 * 1024 * 1024) {
|
||||
rb_raise(rb_eNoMemError, "try to allocate too big memory");
|
||||
}
|
||||
mem_error("failed to allocate memory");
|
||||
}
|
||||
}
|
||||
|
||||
return mem;
|
||||
|
@ -109,7 +124,10 @@ xrealloc(ptr, size)
|
|||
rb_gc();
|
||||
mem = realloc(ptr, size);
|
||||
if (!mem)
|
||||
rb_fatal("failed to allocate memory(realloc)");
|
||||
if (size >= 10 * 1024 * 1024) {
|
||||
rb_raise(rb_eNoMemError, "try to re-allocate too big memory");
|
||||
}
|
||||
mem_error("failed to allocate memory(realloc)");
|
||||
}
|
||||
|
||||
return mem;
|
||||
|
@ -244,11 +262,11 @@ add_heap()
|
|||
heaps = (heaps_used>0)?
|
||||
(RVALUE**)realloc(heaps, heaps_length*sizeof(RVALUE*)):
|
||||
(RVALUE**)malloc(heaps_length*sizeof(RVALUE*));
|
||||
if (heaps == 0) rb_fatal("can't alloc memory");
|
||||
if (heaps == 0) mem_error("heaps: can't alloc memory");
|
||||
}
|
||||
|
||||
p = heaps[heaps_used++] = (RVALUE*)malloc(sizeof(RVALUE)*HEAP_SLOTS);
|
||||
if (p == 0) rb_fatal("add_heap: can't alloc memory");
|
||||
if (p == 0) mem_error("add_heap: can't alloc memory");
|
||||
pend = p + HEAP_SLOTS;
|
||||
if (lomem == 0 || lomem > p) lomem = p;
|
||||
if (himem < pend) himem = pend;
|
||||
|
@ -370,7 +388,7 @@ rb_mark_tbl(tbl)
|
|||
|
||||
static int
|
||||
mark_hashentry(key, value)
|
||||
ID key;
|
||||
VALUE key;
|
||||
VALUE value;
|
||||
{
|
||||
rb_gc_mark(key);
|
||||
|
|
5
hash.c
5
hash.c
|
@ -35,7 +35,7 @@ rb_hash_modify(hash)
|
|||
{
|
||||
if (FL_TEST(hash, HASH_FREEZE))
|
||||
rb_raise(rb_eTypeError, "can't modify frozen hash");
|
||||
if (!FL_TEST(hash, FL_TAINT) && rb_safe_level() >= 4)
|
||||
if (!OBJ_TAINTED(hash) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify hash");
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,9 @@ VALUE
|
|||
rb_hash_freeze(hash)
|
||||
VALUE hash;
|
||||
{
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(hash))
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't freeze hash");
|
||||
|
||||
FL_SET(hash, HASH_FREEZE);
|
||||
return hash;
|
||||
}
|
||||
|
|
23
intern.h
23
intern.h
|
@ -221,7 +221,7 @@ int yyparse _((void));
|
|||
ID rb_id_attrset _((ID));
|
||||
void rb_parser_append_print _((void));
|
||||
void rb_parser_while_loop _((int, int));
|
||||
int rb_is_shvar_id _((ID));
|
||||
int rb_is_const_id _((ID));
|
||||
int rb_is_instance_id _((ID));
|
||||
VALUE rb_backref_get _((void));
|
||||
void rb_backref_set _((VALUE));
|
||||
|
@ -323,17 +323,18 @@ VALUE rb_ivar_set _((VALUE, ID, VALUE));
|
|||
VALUE rb_ivar_defined _((VALUE, ID));
|
||||
VALUE rb_obj_instance_variables _((VALUE));
|
||||
VALUE rb_obj_remove_instance_variable _((VALUE, VALUE));
|
||||
VALUE rb_mod_shvar_at _((VALUE, VALUE));
|
||||
VALUE rb_mod_shvars _((VALUE));
|
||||
VALUE rb_mod_shvar_of _((VALUE, VALUE));
|
||||
VALUE rb_mod_remove_shvar _((VALUE, VALUE));
|
||||
int rb_shvar_defined_at _((VALUE, ID));
|
||||
VALUE rb_mod_const_at _((VALUE, VALUE));
|
||||
VALUE rb_mod_constants _((VALUE));
|
||||
VALUE rb_mod_const_of _((VALUE, VALUE));
|
||||
VALUE rb_mod_remove_const _((VALUE, VALUE));
|
||||
int rb_const_defined_at _((VALUE, ID));
|
||||
int rb_autoload_defined _((ID));
|
||||
int rb_shvar_defined _((VALUE, ID));
|
||||
VALUE rb_shvar_get _((VALUE, ID));
|
||||
VALUE rb_shvar_get_at _((VALUE, ID));
|
||||
void rb_shvar_set _((VALUE, ID, VALUE));
|
||||
VALUE rb_mod_shared_variables _((VALUE));
|
||||
int rb_const_defined _((VALUE, ID));
|
||||
VALUE rb_const_get _((VALUE, ID));
|
||||
VALUE rb_const_get_at _((VALUE, ID));
|
||||
void rb_const_set _((VALUE, ID, VALUE));
|
||||
VALUE rb_mod_constants _((VALUE));
|
||||
void rb_autoload_load _((ID));
|
||||
/* version.c */
|
||||
void ruby_show_version _((void));
|
||||
void ruby_show_copyright _((void));
|
||||
|
|
20
io.c
20
io.c
|
@ -969,7 +969,9 @@ static VALUE
|
|||
rb_io_close_method(io)
|
||||
VALUE io;
|
||||
{
|
||||
rb_secure(4);
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't close");
|
||||
}
|
||||
rb_io_close(io);
|
||||
return Qnil;
|
||||
}
|
||||
|
@ -991,7 +993,9 @@ rb_io_close_read(io)
|
|||
OpenFile *fptr;
|
||||
int n;
|
||||
|
||||
rb_secure(4);
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't close");
|
||||
}
|
||||
GetOpenFile(io, fptr);
|
||||
if (fptr->f2 == 0 && (fptr->mode & FMODE_WRITABLE)) {
|
||||
rb_raise(rb_eIOError, "closing non-duplex IO for reading");
|
||||
|
@ -1015,7 +1019,9 @@ rb_io_close_write(io)
|
|||
OpenFile *fptr;
|
||||
int n;
|
||||
|
||||
rb_secure(4);
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(io)) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't close");
|
||||
}
|
||||
GetOpenFile(io, fptr);
|
||||
if (fptr->f2 == 0 && (fptr->mode & FMODE_READABLE)) {
|
||||
rb_raise(rb_eIOError, "closing non-duplex IO for writing");
|
||||
|
@ -1685,9 +1691,11 @@ rb_io_reopen(io, nfile)
|
|||
char *mode;
|
||||
int fd;
|
||||
|
||||
rb_secure(4);
|
||||
GetOpenFile(io, fptr);
|
||||
nfile = rb_io_get_io(nfile);
|
||||
if (rb_safe_level() >= 4 && (!OBJ_TAINTED(io) || !OBJ_TAINTED(nfile))) {
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't reopen");
|
||||
}
|
||||
GetOpenFile(io, fptr);
|
||||
GetOpenFile(nfile, orig);
|
||||
|
||||
if (fptr == orig) return io;
|
||||
|
@ -3070,6 +3078,8 @@ argf_eof()
|
|||
{
|
||||
if (init_p == 0 && !next_argv())
|
||||
return Qtrue;
|
||||
if (next_p == -1)
|
||||
return Qtrue;
|
||||
if (TYPE(current_file) != T_FILE) {
|
||||
return argf_forward();
|
||||
}
|
||||
|
|
|
@ -203,7 +203,12 @@ The variable ruby-indent-level controls the amount of indentation.
|
|||
(looking-at "[\\[({]")
|
||||
(and (not modifier) (looking-at "[!?]"))
|
||||
(and (looking-at ruby-symbol-re)
|
||||
(forward-word -1)
|
||||
(save-restriction
|
||||
(let ((p (point)))
|
||||
(beginning-of-line)
|
||||
(narrow-to-region (point) p)
|
||||
(goto-char p)
|
||||
(forward-word -1)))
|
||||
(if (and (not modifier) (bolp))
|
||||
t
|
||||
(if (or (looking-at ruby-block-beg-re)
|
||||
|
|
29
object.c
29
object.c
|
@ -283,6 +283,7 @@ VALUE
|
|||
rb_obj_taint(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
rb_secure(4);
|
||||
OBJ_TAINT(obj);
|
||||
return obj;
|
||||
}
|
||||
|
@ -688,25 +689,25 @@ rb_mod_attr_accessor(argc, argv, klass)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_mod_shvar_get(mod, name)
|
||||
rb_mod_const_get(mod, name)
|
||||
VALUE mod, name;
|
||||
{
|
||||
return rb_shvar_get(mod, rb_to_id(name));
|
||||
return rb_const_get(mod, rb_to_id(name));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_mod_shvar_set(mod, name, value)
|
||||
rb_mod_const_set(mod, name, value)
|
||||
VALUE mod, name, value;
|
||||
{
|
||||
rb_shvar_set(mod, rb_to_id(name), value);
|
||||
rb_const_set(mod, rb_to_id(name), value);
|
||||
return value;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_mod_shvar_defined(mod, name)
|
||||
rb_mod_const_defined(mod, name)
|
||||
VALUE mod, name;
|
||||
{
|
||||
return rb_shvar_defined_at(mod, rb_to_id(name));
|
||||
return rb_const_defined_at(mod, rb_to_id(name));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -1070,17 +1071,11 @@ Init_Object()
|
|||
rb_define_method(rb_cModule, "protected_instance_methods", rb_class_protected_instance_methods, -1);
|
||||
rb_define_method(rb_cModule, "private_instance_methods", rb_class_private_instance_methods, -1);
|
||||
|
||||
rb_define_method(rb_cModule, "shared_variable", rb_mod_shvars, 0);
|
||||
rb_define_method(rb_cModule, "shared_variable_get", rb_mod_shvar_get, 1);
|
||||
rb_define_method(rb_cModule, "shared_variable_set", rb_mod_shvar_set, 2);
|
||||
rb_define_method(rb_cModule, "shared_variable_defined?", rb_mod_shvar_defined, 1);
|
||||
rb_define_private_method(rb_cModule, "remove_shared_variable", rb_mod_remove_shvar, 1);
|
||||
/* to be remove at 1.6*/
|
||||
rb_define_method(rb_cModule, "constants", rb_mod_shvars, 0);
|
||||
rb_define_method(rb_cModule, "const_get", rb_mod_shvar_get, 1);
|
||||
rb_define_method(rb_cModule, "const_set", rb_mod_shvar_set, 2);
|
||||
rb_define_method(rb_cModule, "const_defined?", rb_mod_shvar_defined, 1);
|
||||
rb_define_private_method(rb_cModule, "remove_const", rb_mod_remove_shvar, 1);
|
||||
rb_define_method(rb_cModule, "constants", rb_mod_constants, 0);
|
||||
rb_define_method(rb_cModule, "const_get", rb_mod_const_get, 1);
|
||||
rb_define_method(rb_cModule, "const_set", rb_mod_const_set, 2);
|
||||
rb_define_method(rb_cModule, "const_defined?", rb_mod_const_defined, 1);
|
||||
rb_define_private_method(rb_cModule, "remove_const", rb_mod_remove_const, 1);
|
||||
rb_define_private_method(rb_cModule, "method_added", rb_obj_dummy, 1);
|
||||
|
||||
rb_define_method(rb_cClass, "new", rb_class_new_instance, -1);
|
||||
|
|
38
parse.y
38
parse.y
|
@ -26,14 +26,14 @@
|
|||
#define ID_INSTANCE 0x02
|
||||
#define ID_GLOBAL 0x03
|
||||
#define ID_ATTRSET 0x04
|
||||
#define ID_SHARED 0x05
|
||||
#define ID_CONST 0x05
|
||||
|
||||
#define is_notop_id(id) ((id)>LAST_TOKEN)
|
||||
#define is_local_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_LOCAL)
|
||||
#define is_global_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_GLOBAL)
|
||||
#define is_instance_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_INSTANCE)
|
||||
#define is_attrset_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_ATTRSET)
|
||||
#define is_shared_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_SHARED)
|
||||
#define is_const_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CONST)
|
||||
|
||||
NODE *ruby_eval_tree_begin = 0;
|
||||
NODE *ruby_eval_tree = 0;
|
||||
|
@ -717,7 +717,7 @@ arg : lhs '=' arg
|
|||
$$ = $2;
|
||||
}
|
||||
else {
|
||||
$$ = call_op($2, tUPLUS, 0);
|
||||
$$ = call_op($2, tUPLUS, 0, 0);
|
||||
}
|
||||
}
|
||||
| tUMINUS arg
|
||||
|
@ -729,7 +729,7 @@ arg : lhs '=' arg
|
|||
$$ = $2;
|
||||
}
|
||||
else {
|
||||
$$ = call_op($2, tUMINUS, 0);
|
||||
$$ = call_op($2, tUMINUS, 0, 0);
|
||||
}
|
||||
}
|
||||
| arg '|' arg
|
||||
|
@ -791,7 +791,7 @@ arg : lhs '=' arg
|
|||
}
|
||||
| '~' arg
|
||||
{
|
||||
$$ = call_op($2, '~', 0);
|
||||
$$ = call_op($2, '~', 0, 0);
|
||||
}
|
||||
| arg tLSHFT arg
|
||||
{
|
||||
|
@ -1787,10 +1787,10 @@ yycompile(f)
|
|||
int n;
|
||||
|
||||
if (!ruby_in_eval && rb_safe_level() == 0 &&
|
||||
rb_shvar_defined(rb_cObject, rb_intern("LINES__"))) {
|
||||
rb_const_defined(rb_cObject, rb_intern("LINES__"))) {
|
||||
VALUE hash, fname;
|
||||
|
||||
hash = rb_shvar_get(rb_cObject, rb_intern("LINES__"));
|
||||
hash = rb_const_get(rb_cObject, rb_intern("LINES__"));
|
||||
if (TYPE(hash) == T_HASH) {
|
||||
fname = rb_str_new2(f);
|
||||
ruby_debug_lines = rb_hash_aref(hash, fname);
|
||||
|
@ -2880,7 +2880,7 @@ yylex()
|
|||
/* binary */
|
||||
c = nextc();
|
||||
if (c != '0' && c != '1') {
|
||||
yyerror("numeric constant with no digits");
|
||||
yyerror("numeric literal without digits");
|
||||
}
|
||||
do {
|
||||
if (c == '_') continue;
|
||||
|
@ -3715,7 +3715,7 @@ gettable(id)
|
|||
else if (is_instance_id(id)) {
|
||||
return NEW_IVAR(id);
|
||||
}
|
||||
else if (is_shared_id(id)) {
|
||||
else if (is_const_id(id)) {
|
||||
return NEW_CVAR(id);
|
||||
}
|
||||
rb_bug("invalid id for gettable");
|
||||
|
@ -3766,11 +3766,10 @@ assignable(id, val)
|
|||
else if (is_instance_id(id)) {
|
||||
lhs = NEW_IASGN(id, val);
|
||||
}
|
||||
else if (is_shared_id(id)) {
|
||||
else if (is_const_id(id)) {
|
||||
if (cur_mid || in_single)
|
||||
lhs = NEW_CASGN(id, val);
|
||||
else
|
||||
lhs = NEW_CDECL(id, val);
|
||||
yyerror("dynamic constant assignment");
|
||||
lhs = NEW_CDECL(id, val);
|
||||
}
|
||||
else {
|
||||
rb_bug("bad id for variable");
|
||||
|
@ -4496,7 +4495,7 @@ rb_intern(name)
|
|||
id = ID_ATTRSET;
|
||||
}
|
||||
else if (ISUPPER(name[0])) {
|
||||
id = ID_SHARED;
|
||||
id = ID_CONST;
|
||||
}
|
||||
else {
|
||||
id = ID_LOCAL;
|
||||
|
@ -4548,19 +4547,12 @@ rb_id2name(id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rb_is_shared_id(id)
|
||||
ID id;
|
||||
{
|
||||
if (is_shared_id(id)) return Qtrue;
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
int
|
||||
rb_is_const_id(id)
|
||||
ID id;
|
||||
{
|
||||
return rb_is_shared_id(id);
|
||||
if (is_const_id(id)) return Qtrue;
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -831,6 +831,7 @@ proc_setpgid(obj, pid, pgrp)
|
|||
#ifdef HAVE_SETPGID
|
||||
int ipid, ipgrp;
|
||||
|
||||
rb_secure(2);
|
||||
ipid = NUM2INT(pid);
|
||||
ipgrp = NUM2INT(pgrp);
|
||||
|
||||
|
@ -845,8 +846,10 @@ static VALUE
|
|||
proc_setsid()
|
||||
{
|
||||
#ifdef HAVE_SETSID
|
||||
int pid = setsid();
|
||||
int pid;
|
||||
|
||||
rb_secure(2);
|
||||
pid = setsid();
|
||||
if (pid < 0) rb_sys_fail(0);
|
||||
return INT2FIX(pid);
|
||||
#else
|
||||
|
@ -879,6 +882,7 @@ proc_setpriority(obj, which, who, prio)
|
|||
#ifdef HAVE_GETPRIORITY
|
||||
int iwhich, iwho, iprio;
|
||||
|
||||
rb_secure(2);
|
||||
iwhich = NUM2INT(which);
|
||||
iwho = NUM2INT(who);
|
||||
iprio = NUM2INT(prio);
|
||||
|
@ -995,6 +999,7 @@ static VALUE
|
|||
proc_setegid(obj, egid)
|
||||
VALUE obj, egid;
|
||||
{
|
||||
rb_secure(2);
|
||||
#ifdef HAVE_SETEGID
|
||||
if (setegid(NUM2INT(egid)) < 0) rb_sys_fail(0);
|
||||
#else
|
||||
|
|
14
range.c
14
range.c
|
@ -138,6 +138,16 @@ range_each(range)
|
|||
else if (TYPE(b) == T_STRING) {
|
||||
rb_str_upto(b, e, EXCL(range));
|
||||
}
|
||||
else if (rb_obj_is_kind_of(b, rb_cNumeric)) {
|
||||
b = rb_Integer(b);
|
||||
e = rb_Integer(e);
|
||||
|
||||
if (!EXCL(range)) e = rb_funcall(e, '+', 1, INT2FIX(1));
|
||||
while (RTEST(rb_funcall(b, '<', 1, e))) {
|
||||
rb_yield(b);
|
||||
b = rb_funcall(b, '+', 1, INT2FIX(1));
|
||||
}
|
||||
}
|
||||
else { /* generic each */
|
||||
VALUE v = b;
|
||||
ID succ = rb_intern("succ");
|
||||
|
@ -286,7 +296,7 @@ range_length(range)
|
|||
VALUE range;
|
||||
{
|
||||
VALUE beg, end;
|
||||
VALUE size;
|
||||
long size;
|
||||
|
||||
beg = rb_ivar_get(range, id_beg);
|
||||
end = rb_ivar_get(range, id_end);
|
||||
|
@ -302,7 +312,7 @@ range_length(range)
|
|||
return INT2NUM(NUM2LONG(end) - NUM2LONG(beg) + 1);
|
||||
}
|
||||
}
|
||||
if (!rb_obj_is_kind_of(beg, rb_cNumeric)) {
|
||||
if (!rb_obj_is_kind_of(beg, rb_cInteger)) {
|
||||
return rb_length_by_each(range);
|
||||
}
|
||||
size = rb_funcall(end, '-', 1, beg);
|
||||
|
|
26
re.c
26
re.c
|
@ -507,6 +507,32 @@ rb_reg_prepare_re(reg)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
rb_reg_adjust_startpos(reg, str, pos, reverse)
|
||||
VALUE reg, str;
|
||||
int pos, reverse;
|
||||
{
|
||||
int range;
|
||||
|
||||
if (may_need_recompile)
|
||||
rb_reg_prepare_re(reg);
|
||||
|
||||
if (FL_TEST(reg, KCODE_FIXED))
|
||||
kcode_set_option(reg);
|
||||
else if (reg_kcode != curr_kcode)
|
||||
kcode_reset_option();
|
||||
|
||||
if (reverse) {
|
||||
range = -pos;
|
||||
}
|
||||
else {
|
||||
range = RSTRING(str)->len - pos;
|
||||
}
|
||||
return re_adjust_startpos(RREGEXP(reg)->ptr,
|
||||
RSTRING(str)->ptr, RSTRING(str)->len,
|
||||
pos, range);
|
||||
}
|
||||
|
||||
int
|
||||
rb_reg_search(reg, str, pos, reverse)
|
||||
VALUE reg, str;
|
||||
|
|
1
re.h
1
re.h
|
@ -32,6 +32,7 @@ int rb_str_cicmp _((VALUE, VALUE));
|
|||
VALUE rb_reg_regcomp _((VALUE));
|
||||
int rb_reg_search _((VALUE, VALUE, int, int));
|
||||
VALUE rb_reg_regsub _((VALUE, VALUE, struct re_registers *));
|
||||
int rb_reg_adjust_startpos _((VALUE, VALUE, int, int));
|
||||
|
||||
int rb_kcode _((void));
|
||||
|
||||
|
|
67
regex.c
67
regex.c
|
@ -2922,6 +2922,47 @@ re_compile_fastmap(bufp)
|
|||
FREE_AND_RETURN_VOID(stackb);
|
||||
}
|
||||
|
||||
/* adjust startpos value to the position between characters. */
|
||||
int
|
||||
re_adjust_startpos(bufp, string, size, startpos, range)
|
||||
struct re_pattern_buffer *bufp;
|
||||
const char *string;
|
||||
int size, startpos, range;
|
||||
{
|
||||
/* Update the fastmap now if not correct already. */
|
||||
if (!bufp->fastmap_accurate) {
|
||||
re_compile_fastmap(bufp);
|
||||
}
|
||||
|
||||
/* Adjust startpos for mbc string */
|
||||
if (current_mbctype && startpos>0 && !(bufp->options&RE_OPTIMIZE_BMATCH)) {
|
||||
int i = 0;
|
||||
|
||||
if (range > 0) {
|
||||
while (i<size) {
|
||||
i += mbclen(string[i]);
|
||||
if (startpos <= i) {
|
||||
startpos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
int w;
|
||||
|
||||
while (i<size) {
|
||||
w = mbclen(string[i]);
|
||||
if (startpos < i + w) {
|
||||
startpos = i;
|
||||
break;
|
||||
}
|
||||
i += w;
|
||||
}
|
||||
}
|
||||
}
|
||||
return startpos;
|
||||
}
|
||||
|
||||
|
||||
/* Using the compiled pattern in BUFP->buffer, first tries to match
|
||||
STRING, starting first at index STARTPOS, then at STARTPOS + 1, and
|
||||
|
@ -2954,32 +2995,6 @@ re_search(bufp, string, size, startpos, range, regs)
|
|||
re_compile_fastmap(bufp);
|
||||
}
|
||||
|
||||
/* Adjust startpos for mbc string */
|
||||
if (current_mbctype && startpos>0 && !(bufp->options&RE_OPTIMIZE_BMATCH)) {
|
||||
int i = 0;
|
||||
|
||||
if (range > 0) {
|
||||
while (i<size) {
|
||||
i += mbclen(string[i]);
|
||||
if (startpos <= i) {
|
||||
startpos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
int w;
|
||||
|
||||
while (i<size) {
|
||||
w = mbclen(string[i]);
|
||||
if (startpos < i + w) {
|
||||
startpos = i;
|
||||
break;
|
||||
}
|
||||
i += w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If the search isn't to be a backwards one, don't waste time in a
|
||||
search for a pattern that must be anchored. */
|
||||
|
|
3
regex.h
3
regex.h
|
@ -28,6 +28,7 @@
|
|||
|
||||
/* symbol mangling for ruby */
|
||||
#ifdef RUBY
|
||||
# define re_adjust_startpos ruby_re_adjust_startpos
|
||||
# define re_compile_fastmap ruby_re_compile_fastmap
|
||||
# define re_compile_pattern ruby_re_compile_pattern
|
||||
# define re_copy_registers ruby_re_copy_registers
|
||||
|
@ -186,6 +187,7 @@ typedef struct
|
|||
extern char *re_compile_pattern (const char *, int, struct re_pattern_buffer *);
|
||||
void re_free_pattern (struct re_pattern_buffer *);
|
||||
/* Is this really advertised? */
|
||||
extern int re_adjust_startpos (struct re_pattern_buffer *, const char*, int, int, int);
|
||||
extern void re_compile_fastmap (struct re_pattern_buffer *);
|
||||
extern int re_search (struct re_pattern_buffer *, const char*, int, int, int,
|
||||
struct re_registers *);
|
||||
|
@ -206,6 +208,7 @@ extern int re_exec (const char *);
|
|||
extern char *re_compile_pattern ();
|
||||
void re_free_regexp ();
|
||||
/* Is this really advertised? */
|
||||
extern int re_adjust_startpos ();
|
||||
extern void re_compile_fastmap ();
|
||||
extern int re_search ();
|
||||
extern int re_match ();
|
||||
|
|
15
ruby.h
15
ruby.h
|
@ -89,7 +89,7 @@ extern "C" {
|
|||
---->> ruby requires sizeof(void*) == sizeof(long) to be compiled. <<----
|
||||
#endif
|
||||
typedef unsigned long VALUE;
|
||||
typedef unsigned int ID;
|
||||
typedef unsigned long ID;
|
||||
|
||||
#ifdef __STDC__
|
||||
# include <limits.h>
|
||||
|
@ -117,6 +117,8 @@ typedef unsigned int ID;
|
|||
#define INT2FIX(i) (VALUE)(((long)(i))<<1 | FIXNUM_FLAG)
|
||||
VALUE rb_int2inum _((long));
|
||||
#define INT2NUM(v) rb_int2inum(v)
|
||||
VALUE rb_uint2inum _((unsigned long));
|
||||
#define UINT2NUM(v) rb_uint2inum(v)
|
||||
|
||||
#define FIX2LONG(x) RSHIFT((long)x,1)
|
||||
#define FIX2ULONG(x) (((unsigned long)(x))>>1)
|
||||
|
@ -271,14 +273,14 @@ struct RFile {
|
|||
|
||||
struct RData {
|
||||
struct RBasic basic;
|
||||
void (*dmark)();
|
||||
void (*dfree)();
|
||||
void (*dmark) _((void*));
|
||||
void (*dfree) _((void*));
|
||||
void *data;
|
||||
};
|
||||
|
||||
#define DATA_PTR(dta) (RDATA(dta)->data)
|
||||
|
||||
VALUE rb_data_object_alloc _((VALUE,void*,void (*)(),void (*)()));
|
||||
VALUE rb_data_object_alloc _((VALUE,void*,void (*) _((void*)),void (*) _((void*))));
|
||||
#define Data_Make_Struct(klass,type,mark,free,sval) (\
|
||||
sval = ALLOC(type),\
|
||||
memset(sval, 0, sizeof(type)),\
|
||||
|
@ -375,8 +377,8 @@ void rb_define_variable _((const char*,VALUE*));
|
|||
void rb_define_virtual_variable _((const char*,VALUE(*)(),void(*)()));
|
||||
void rb_define_hooked_variable _((const char*,VALUE*,VALUE(*)(),void(*)()));
|
||||
void rb_define_readonly_variable _((const char*,VALUE*));
|
||||
void rb_define_shared_variable _((VALUE,const char*,VALUE));
|
||||
void rb_define_global_shared_variable _((const char*,VALUE));
|
||||
void rb_define_constants _((VALUE,const char*,VALUE));
|
||||
void rb_define_global_constants _((const char*,VALUE));
|
||||
|
||||
void rb_define_method _((VALUE,const char*,VALUE(*)(),int));
|
||||
void rb_define_module_function _((VALUE,const char*,VALUE(*)(),int));
|
||||
|
@ -494,6 +496,7 @@ EXTERN VALUE rb_eSystemCallError;
|
|||
EXTERN VALUE rb_eTypeError;
|
||||
EXTERN VALUE rb_eZeroDivError;
|
||||
EXTERN VALUE rb_eNotImpError;
|
||||
EXTERN VALUE rb_eNoMemError;
|
||||
EXTERN VALUE rb_eFloatDomainError;
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 2 && !defined(RUBY_NO_INLINE)
|
||||
|
|
17
string.c
17
string.c
|
@ -66,7 +66,7 @@ rb_tainted_str_new(ptr, len)
|
|||
{
|
||||
VALUE str = rb_str_new(ptr, len);
|
||||
|
||||
FL_SET(str, FL_TAINT);
|
||||
OBJ_TAINT(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ rb_tainted_str_new2(ptr)
|
|||
{
|
||||
VALUE str = rb_str_new2(ptr);
|
||||
|
||||
FL_SET(str, FL_TAINT);
|
||||
OBJ_TAINT(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -112,8 +112,8 @@ rb_str_new4(orig)
|
|||
str->ptr = RSTRING(orig)->ptr;
|
||||
RSTRING(orig)->orig = (VALUE)str;
|
||||
str->orig = 0;
|
||||
if (FL_TEST(orig, FL_TAINT)) {
|
||||
FL_SET(str, FL_TAINT);
|
||||
if (OBJ_TAINTED(orig)) {
|
||||
OBJ_TAINT(str);
|
||||
}
|
||||
FL_SET(str, STR_FREEZE);
|
||||
return (VALUE)str;
|
||||
|
@ -213,7 +213,7 @@ rb_str_s_new(klass, orig)
|
|||
}
|
||||
|
||||
if (rb_safe_level() >= 3) {
|
||||
FL_SET(str, FL_TAINT);
|
||||
OBJ_TAINT(str);
|
||||
}
|
||||
|
||||
return (VALUE)str;
|
||||
|
@ -334,7 +334,7 @@ rb_str_modify(str)
|
|||
|
||||
if (FL_TEST(str, STR_FREEZE))
|
||||
rb_raise(rb_eTypeError, "can't modify frozen string");
|
||||
if (!FL_TEST(str, FL_TAINT) && rb_safe_level() >= 4)
|
||||
if (!OBJ_TAINTED(str) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify string");
|
||||
if (!RSTRING(str)->orig || FL_TEST(str, STR_NO_ORIG)) return;
|
||||
ptr = RSTRING(str)->ptr;
|
||||
|
@ -350,6 +350,9 @@ VALUE
|
|||
rb_str_freeze(str)
|
||||
VALUE str;
|
||||
{
|
||||
if (rb_safe_level() >= 4 && !OBJ_TAINTED(str))
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't freeze string");
|
||||
|
||||
FL_SET(str, STR_FREEZE);
|
||||
return str;
|
||||
}
|
||||
|
@ -585,6 +588,7 @@ rb_str_index_method(argc, argv, str)
|
|||
|
||||
switch (TYPE(sub)) {
|
||||
case T_REGEXP:
|
||||
pos = rb_reg_adjust_startpos(sub, str, pos, 0);
|
||||
pos = rb_reg_search(sub, str, pos, 0);
|
||||
break;
|
||||
|
||||
|
@ -635,6 +639,7 @@ rb_str_rindex(argc, argv, str)
|
|||
switch (TYPE(sub)) {
|
||||
case T_REGEXP:
|
||||
if (RREGEXP(sub)->len) {
|
||||
pos = rb_reg_adjust_startpos(sub, str, pos, 1);
|
||||
pos = rb_reg_search(sub, str, pos, 1);
|
||||
}
|
||||
if (pos >= 0) return INT2NUM(pos);
|
||||
|
|
14
struct.c
14
struct.c
|
@ -161,7 +161,7 @@ make_struct(name, member, klass)
|
|||
else {
|
||||
char *cname = STR2CSTR(name);
|
||||
id = rb_intern(cname);
|
||||
if (!rb_is_shared_id(id)) {
|
||||
if (!rb_is_const_id(id)) {
|
||||
rb_raise(rb_eNameError, "identifier %s needs to be constant", cname);
|
||||
}
|
||||
nstr = rb_define_class_under(klass, cname, klass);
|
||||
|
@ -207,7 +207,8 @@ rb_struct_define(name, va_alist)
|
|||
VALUE nm, ary;
|
||||
char *mem;
|
||||
|
||||
nm = rb_str_new2(name);
|
||||
if (!name) nm = Qnil;
|
||||
else nm = rb_str_new2(name);
|
||||
ary = rb_ary_new();
|
||||
|
||||
va_init_list(ar, name);
|
||||
|
@ -224,16 +225,23 @@ static VALUE
|
|||
rb_struct_s_def(argc, argv, klass)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE klass;
|
||||
{
|
||||
VALUE name, rest;
|
||||
long i;
|
||||
VALUE st;
|
||||
ID id;
|
||||
|
||||
rb_scan_args(argc, argv, "1*", &name, &rest);
|
||||
for (i=0; i<RARRAY(rest)->len; i++) {
|
||||
ID id = rb_to_id(RARRAY(rest)->ptr[i]);
|
||||
id = rb_to_id(RARRAY(rest)->ptr[i]);
|
||||
RARRAY(rest)->ptr[i] = INT2FIX(id);
|
||||
}
|
||||
if (TYPE(name) != T_STRING) {
|
||||
id = rb_to_id(name);
|
||||
rb_ary_unshift(rest, INT2FIX(id));
|
||||
name = Qnil;
|
||||
}
|
||||
st = make_struct(name, rest, klass);
|
||||
|
||||
return st;
|
||||
|
|
189
variable.c
189
variable.c
|
@ -44,7 +44,7 @@ fc_i(key, value, res)
|
|||
VALUE path;
|
||||
char *name;
|
||||
|
||||
if (!rb_is_shared_id(key)) return ST_CONTINUE;
|
||||
if (!rb_is_const_id(key)) return ST_CONTINUE;
|
||||
|
||||
name = rb_id2name(key);
|
||||
if (res->path) {
|
||||
|
@ -226,7 +226,7 @@ rb_autoload_id(id, filename)
|
|||
ID id;
|
||||
const char *filename;
|
||||
{
|
||||
if (!rb_is_shared_id(id)) {
|
||||
if (!rb_is_const_id(id)) {
|
||||
rb_raise(rb_eNameError, "autoload must be constant name",
|
||||
rb_id2name(id));
|
||||
}
|
||||
|
@ -858,7 +858,7 @@ rb_ivar_get(obj, id)
|
|||
{
|
||||
VALUE val;
|
||||
|
||||
if (!FL_TEST(obj, FL_TAINT) && rb_safe_level() >= 4)
|
||||
if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't access instance variable");
|
||||
switch (TYPE(obj)) {
|
||||
case T_OBJECT:
|
||||
|
@ -873,7 +873,7 @@ rb_ivar_get(obj, id)
|
|||
break;
|
||||
}
|
||||
if (ruby_verbose) {
|
||||
rb_warning("instance var %s not initialized", rb_id2name(id));
|
||||
rb_warning("instance variable %s not initialized", rb_id2name(id));
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
@ -884,7 +884,7 @@ rb_ivar_set(obj, id, val)
|
|||
ID id;
|
||||
VALUE val;
|
||||
{
|
||||
if (!FL_TEST(obj, FL_TAINT) && rb_safe_level() >= 4)
|
||||
if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
|
||||
switch (TYPE(obj)) {
|
||||
case T_OBJECT:
|
||||
|
@ -936,10 +936,11 @@ VALUE
|
|||
rb_obj_instance_variables(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
VALUE ary = rb_ary_new();
|
||||
VALUE ary;
|
||||
|
||||
if (!FL_TEST(obj, FL_TAINT) && rb_safe_level() >= 4)
|
||||
if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't get metainfo");
|
||||
ary = rb_ary_new();
|
||||
switch (TYPE(obj)) {
|
||||
case T_OBJECT:
|
||||
case T_CLASS:
|
||||
|
@ -969,7 +970,7 @@ rb_obj_remove_instance_variable(obj, name)
|
|||
VALUE val = Qnil;
|
||||
ID id = rb_to_id(name);
|
||||
|
||||
if (!FL_TEST(obj, FL_TAINT) && rb_safe_level() >= 4)
|
||||
if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
|
||||
if (!rb_is_instance_id(id)) {
|
||||
rb_raise(rb_eNameError, "`%s' is not an instance variable",
|
||||
|
@ -993,7 +994,7 @@ rb_obj_remove_instance_variable(obj, name)
|
|||
}
|
||||
|
||||
VALUE
|
||||
rb_shvar_get_at(klass, id)
|
||||
rb_const_get_at(klass, id)
|
||||
VALUE klass;
|
||||
ID id;
|
||||
{
|
||||
|
@ -1003,7 +1004,7 @@ rb_shvar_get_at(klass, id)
|
|||
return value;
|
||||
}
|
||||
if (klass == rb_cObject) {
|
||||
return rb_shvar_get(klass, id);
|
||||
return rb_const_get(klass, id);
|
||||
}
|
||||
rb_raise(rb_eNameError, "uninitialized constant %s::%s",
|
||||
RSTRING(rb_class_path(klass))->ptr,
|
||||
|
@ -1012,16 +1013,21 @@ rb_shvar_get_at(klass, id)
|
|||
}
|
||||
|
||||
|
||||
VALUE
|
||||
rb_const_get_at(klass, id)
|
||||
VALUE klass;
|
||||
void
|
||||
rb_autoload_load(id)
|
||||
ID id;
|
||||
{
|
||||
return rb_shvar_get_at(klass, id);
|
||||
char *modname;
|
||||
VALUE module;
|
||||
|
||||
st_delete(autoload_tbl, &id, &modname);
|
||||
module = rb_str_new2(modname);
|
||||
free(modname);
|
||||
rb_f_require(Qnil, module);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_shvar_get(klass, id)
|
||||
rb_const_get(klass, id)
|
||||
VALUE klass;
|
||||
ID id;
|
||||
{
|
||||
|
@ -1036,7 +1042,7 @@ rb_shvar_get(klass, id)
|
|||
tmp = RCLASS(tmp)->super;
|
||||
}
|
||||
if (BUILTIN_TYPE(klass) == T_MODULE) {
|
||||
return rb_shvar_get(rb_cObject, id);
|
||||
return rb_const_get(rb_cObject, id);
|
||||
}
|
||||
|
||||
/* pre-defined class */
|
||||
|
@ -1044,14 +1050,8 @@ rb_shvar_get(klass, id)
|
|||
|
||||
/* autoload */
|
||||
if (autoload_tbl && st_lookup(autoload_tbl, id, 0)) {
|
||||
char *modname;
|
||||
VALUE module;
|
||||
|
||||
st_delete(autoload_tbl, &id, &modname);
|
||||
module = rb_str_new2(modname);
|
||||
free(modname);
|
||||
rb_f_require(Qnil, module);
|
||||
return rb_shvar_get(klass, id);
|
||||
rb_autoload_load(id);
|
||||
return rb_const_get(klass, id);
|
||||
}
|
||||
|
||||
/* Uninitialized constant */
|
||||
|
@ -1065,21 +1065,13 @@ rb_shvar_get(klass, id)
|
|||
return Qnil; /* not reached */
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_const_get(klass, id)
|
||||
VALUE klass;
|
||||
ID id;
|
||||
{
|
||||
return rb_shvar_get(klass, id);
|
||||
}
|
||||
|
||||
static int
|
||||
sv_i(key, value, ary)
|
||||
ID key;
|
||||
VALUE value;
|
||||
VALUE ary;
|
||||
{
|
||||
if (rb_is_shared_id(key)) {
|
||||
if (rb_is_const_id(key)) {
|
||||
VALUE kval = rb_str_new2(rb_id2name(key));
|
||||
if (!rb_ary_includes(ary, kval)) {
|
||||
rb_ary_push(ary, kval);
|
||||
|
@ -1089,20 +1081,22 @@ sv_i(key, value, ary)
|
|||
}
|
||||
|
||||
VALUE
|
||||
rb_mod_remove_shvar(mod, name)
|
||||
rb_mod_remove_const(mod, name)
|
||||
VALUE mod, name;
|
||||
{
|
||||
ID id = rb_to_id(name);
|
||||
VALUE val;
|
||||
|
||||
if (!rb_is_shared_id(id)) {
|
||||
rb_raise(rb_eNameError, "`%s' is not shared variable", rb_id2name(id));
|
||||
if (!OBJ_TAINTED(mod) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't remove constant");
|
||||
if (!rb_is_const_id(id)) {
|
||||
rb_raise(rb_eNameError, "`%s' is not constant", rb_id2name(id));
|
||||
}
|
||||
|
||||
if (RCLASS(mod)->iv_tbl && st_delete(ROBJECT(mod)->iv_tbl, &id, &val)) {
|
||||
return val;
|
||||
}
|
||||
if (rb_shvar_defined_at(mod, id)) {
|
||||
if (rb_const_defined_at(mod, id)) {
|
||||
rb_raise(rb_eNameError, "cannot remove %s::%s",
|
||||
rb_class2name(mod), rb_id2name(id));
|
||||
}
|
||||
|
@ -1111,13 +1105,6 @@ rb_mod_remove_shvar(mod, name)
|
|||
return Qnil; /* not reached */
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_mod_remove_const(mod, name)
|
||||
VALUE mod, name;
|
||||
{
|
||||
return rb_mod_remove_shvar(mod, name);
|
||||
}
|
||||
|
||||
static int
|
||||
autoload_i(key, name, ary)
|
||||
ID key;
|
||||
|
@ -1132,10 +1119,10 @@ autoload_i(key, name, ary)
|
|||
}
|
||||
|
||||
VALUE
|
||||
rb_mod_shvar_at(mod, ary)
|
||||
rb_mod_const_at(mod, ary)
|
||||
VALUE mod, ary;
|
||||
{
|
||||
if (!FL_TEST(mod, FL_TAINT) && rb_safe_level() >= 4)
|
||||
if (!OBJ_TAINTED(mod) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't get metainfo");
|
||||
if (RCLASS(mod)->iv_tbl) {
|
||||
st_foreach(RCLASS(mod)->iv_tbl, sv_i, ary);
|
||||
|
@ -1149,61 +1136,25 @@ rb_mod_shvar_at(mod, ary)
|
|||
return ary;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_mod_const_at(mod, ary)
|
||||
VALUE mod, ary;
|
||||
{
|
||||
return rb_mod_shvar_at(mod, ary);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_mod_shvar_of(mod, ary)
|
||||
VALUE mod;
|
||||
VALUE ary;
|
||||
{
|
||||
rb_mod_shvar_at(mod, ary);
|
||||
for (;;) {
|
||||
mod = RCLASS(mod)->super;
|
||||
if (!mod) break;
|
||||
rb_mod_shvar_at(mod, ary);
|
||||
}
|
||||
return ary;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_mod_const_of(mod, ary)
|
||||
VALUE mod;
|
||||
VALUE ary;
|
||||
{
|
||||
return rb_mod_shvar_of(mod, ary);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_mod_shvars(mod)
|
||||
VALUE mod;
|
||||
{
|
||||
return rb_mod_shvar_of(mod, rb_ary_new());
|
||||
rb_mod_const_at(mod, ary);
|
||||
for (;;) {
|
||||
mod = RCLASS(mod)->super;
|
||||
if (!mod) break;
|
||||
rb_mod_const_at(mod, ary);
|
||||
}
|
||||
return ary;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_mod_constants(mod)
|
||||
VALUE mod;
|
||||
{
|
||||
return rb_mod_shvars(mod);
|
||||
}
|
||||
|
||||
int
|
||||
rb_shvar_defined_at(klass, id)
|
||||
VALUE klass;
|
||||
ID id;
|
||||
{
|
||||
if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, 0)) {
|
||||
return Qtrue;
|
||||
}
|
||||
if (klass == rb_cObject) {
|
||||
return rb_shvar_defined(klass, id);
|
||||
}
|
||||
return Qfalse;
|
||||
return rb_mod_const_of(mod, rb_ary_new());
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1211,7 +1162,13 @@ rb_const_defined_at(klass, id)
|
|||
VALUE klass;
|
||||
ID id;
|
||||
{
|
||||
return rb_shvar_defined_at(klass, id);
|
||||
if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, 0)) {
|
||||
return Qtrue;
|
||||
}
|
||||
if (klass == rb_cObject) {
|
||||
return rb_const_defined(klass, id);
|
||||
}
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1224,7 +1181,7 @@ rb_autoload_defined(id)
|
|||
}
|
||||
|
||||
int
|
||||
rb_shvar_defined(klass, id)
|
||||
rb_const_defined(klass, id)
|
||||
VALUE klass;
|
||||
ID id;
|
||||
{
|
||||
|
@ -1237,28 +1194,20 @@ rb_shvar_defined(klass, id)
|
|||
tmp = RCLASS(tmp)->super;
|
||||
}
|
||||
if (BUILTIN_TYPE(klass) == T_MODULE) {
|
||||
return rb_shvar_defined(rb_cObject, id);
|
||||
return rb_const_defined(rb_cObject, id);
|
||||
}
|
||||
if (st_lookup(rb_class_tbl, id, 0))
|
||||
return Qtrue;
|
||||
return rb_autoload_defined(id);
|
||||
}
|
||||
|
||||
int
|
||||
rb_const_defined(klass, id)
|
||||
VALUE klass;
|
||||
ID id;
|
||||
{
|
||||
return rb_shvar_defined(klass, id);
|
||||
}
|
||||
|
||||
void
|
||||
rb_shvar_set(klass, id, val)
|
||||
rb_const_set(klass, id, val)
|
||||
VALUE klass;
|
||||
ID id;
|
||||
VALUE val;
|
||||
{
|
||||
if (!FL_TEST(klass, FL_TAINT) && rb_safe_level() >= 4)
|
||||
if (!OBJ_TAINTED(klass) && rb_safe_level() >= 4)
|
||||
rb_raise(rb_eSecurityError, "Insecure: can't set constant");
|
||||
if (!RCLASS(klass)->iv_tbl) {
|
||||
RCLASS(klass)->iv_tbl = st_init_numtable();
|
||||
|
@ -1268,16 +1217,7 @@ rb_shvar_set(klass, id, val)
|
|||
}
|
||||
|
||||
void
|
||||
rb_const_set(klass, id, val)
|
||||
VALUE klass;
|
||||
ID id;
|
||||
VALUE val;
|
||||
{
|
||||
rb_shvar_set(klass, id, val);
|
||||
}
|
||||
|
||||
void
|
||||
rb_shvar_assign(klass, id, val)
|
||||
rb_const_assign(klass, id, val)
|
||||
VALUE klass;
|
||||
ID id;
|
||||
VALUE val;
|
||||
|
@ -1329,19 +1269,10 @@ rb_define_const(klass, name, val)
|
|||
if (klass == rb_cObject) {
|
||||
rb_secure(4);
|
||||
}
|
||||
if (!rb_is_shared_id(id)) {
|
||||
rb_raise(rb_eNameError, "wrong shared variable name %s", name);
|
||||
if (!rb_is_const_id(id)) {
|
||||
rb_raise(rb_eNameError, "wrong constant name %s", name);
|
||||
}
|
||||
rb_shvar_set(klass, id, val);
|
||||
}
|
||||
|
||||
void
|
||||
rb_define_shvar(klass, name, val)
|
||||
VALUE klass;
|
||||
const char *name;
|
||||
VALUE val;
|
||||
{
|
||||
rb_define_const(klass, name, val);
|
||||
rb_const_set(klass, id, val);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1352,14 +1283,6 @@ rb_define_global_const(name, val)
|
|||
rb_define_const(rb_cObject, name, val);
|
||||
}
|
||||
|
||||
void
|
||||
rb_define_global_shvar(name, val)
|
||||
const char *name;
|
||||
VALUE val;
|
||||
{
|
||||
rb_define_global_const(name, val);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_iv_get(obj, name)
|
||||
VALUE obj;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define RUBY_VERSION "1.5.0"
|
||||
#define RUBY_RELEASE_DATE "1999-12-07"
|
||||
#define RUBY_RELEASE_DATE "1999-12-14"
|
||||
#define RUBY_VERSION_CODE 150
|
||||
#define RUBY_RELEASE_CODE 19991207
|
||||
#define RUBY_RELEASE_CODE 19991214
|
||||
|
|
|
@ -35,7 +35,7 @@ s%@RANLIB@%rem%g
|
|||
s%@AR@%lib -nologo%g
|
||||
s%@LN_S@%%g
|
||||
s%@SET_MAKE@%%g
|
||||
s%@LIBOBJS@% crypt.obj alloca.obj win32.obj fnmatch.obj isinf.obj isnan.obj%g
|
||||
s%@LIBOBJS@% crypt.obj alloca.obj win32.obj isinf.obj isnan.obj%g
|
||||
s%@ALLOCA@%%g
|
||||
s%@DEFAULT_KCODE@%%g
|
||||
s%@EXEEXT@%.exe%g
|
||||
|
|
Загрузка…
Ссылка в новой задаче