git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@587 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 1999-12-14 06:50:43 +00:00
Родитель c18d3740a9
Коммит 9d228b13de
34 изменённых файлов: 649 добавлений и 508 удалений

Просмотреть файл

@ -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
Просмотреть файл

@ -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/
です.

Просмотреть файл

@ -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
Просмотреть файл

@ -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

4
configure поставляемый
Просмотреть файл

@ -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
Просмотреть файл

@ -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);

Просмотреть файл

@ -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
Просмотреть файл

@ -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
Просмотреть файл

@ -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
Просмотреть файл

@ -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
Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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
Просмотреть файл

@ -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)

Просмотреть файл

@ -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
Просмотреть файл

@ -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
Просмотреть файл

@ -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
Просмотреть файл

@ -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
Просмотреть файл

@ -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
Просмотреть файл

@ -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. */

Просмотреть файл

@ -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
Просмотреть файл

@ -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)

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;

Просмотреть файл

@ -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