From 62261ccb47fce9c4728cfbeb84f81d23369ab910 Mon Sep 17 00:00:00 2001 From: matz Date: Wed, 28 Mar 2001 08:43:25 +0000 Subject: [PATCH] * object.c (rb_str2cstr): warn if string contains \0 and length value is ignored. * class.c (rb_singleton_class_clone): should copy class constant table as well. * class.c (rb_include_module): sometimes cache was mistakenly left uncleared - based on the patch by K.Kosako. * ruby.h: all Check_SafeStr()'s are replaced by SafeStr() to ensure 'to_str' be always effective. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1288 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 18 ++++++++++++++++++ class.c | 11 ++++++++--- dir.c | 12 ++++++------ eval.c | 20 +++++++++++--------- file.c | 52 ++++++++++++++++++++++++---------------------------- intern.h | 1 - io.c | 36 ++++++++++++++++++++---------------- object.c | 3 +++ prec.c | 1 + process.c | 25 +++++++++++++------------ ruby.h | 7 +++++++ signal.c | 2 +- version.h | 4 ++-- 13 files changed, 114 insertions(+), 78 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4cd01e9d9a..4d60793753 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +Wed Mar 28 17:39:04 2001 Yukihiro Matsumoto + + * object.c (rb_str2cstr): warn if string contains \0 and length + value is ignored. + +Wed Mar 28 15:00:31 2001 K.Kosako + + * class.c (rb_singleton_class_clone): should copy class constant + table as well. + +Wed Mar 28 14:23:23 2001 Yukihiro Matsumoto + + * class.c (rb_include_module): sometimes cache was mistakenly left + uncleared - based on the patch by K.Kosako. + + * ruby.h: all Check_SafeStr()'s are replaced by SafeStr() to + ensure 'to_str' be always effective. + Wed Mar 28 09:52:33 2001 WATANABE Hirofumi * win32/Makefile.sub: disable global optimization. diff --git a/class.c b/class.c index b8d2cbca96..5e9cc0e5d9 100644 --- a/class.c +++ b/class.c @@ -67,6 +67,9 @@ rb_singleton_class_clone(klass) clone->super = RCLASS(klass)->super; clone->iv_tbl = 0; clone->m_tbl = 0; + if (RCLASS(klass)->iv_tbl) { + clone->iv_tbl = st_copy(RCLASS(klass)->iv_tbl); + } clone->m_tbl = st_init_numtable(); st_foreach(RCLASS(klass)->m_tbl, clone_method, clone->m_tbl); FL_SET(clone, FL_SINGLETON); @@ -217,6 +220,7 @@ rb_include_module(klass, module) VALUE klass, module; { VALUE p; + int changed = 0; if (NIL_P(module)) return; if (klass == module) return; @@ -238,16 +242,17 @@ rb_include_module(klass, module) if (RCLASS(module)->super) { rb_include_module(p, RCLASS(module)->super); } + if (changed) rb_clear_cache(); return; } } rb_frozen_class_p(klass); - RCLASS(klass)->super = - include_class_new(module, RCLASS(klass)->super); + RCLASS(klass)->super = include_class_new(module, RCLASS(klass)->super); klass = RCLASS(klass)->super; module = RCLASS(module)->super; + changed = 1; } - rb_clear_cache(); + if (changed) rb_clear_cache(); } VALUE diff --git a/dir.c b/dir.c index a1b14348f2..0ef70c6d10 100644 --- a/dir.c +++ b/dir.c @@ -254,7 +254,7 @@ dir_initialize(dir, dirname) { DIR *dirp; - Check_SafeStr(dirname); + SafeStr(dirname); if (DATA_PTR(dir)) closedir(DATA_PTR(dir)); DATA_PTR(dir) = NULL; dirp = opendir(RSTRING(dirname)->ptr); @@ -425,7 +425,7 @@ dir_s_chdir(argc, argv, obj) rb_secure(2); if (rb_scan_args(argc, argv, "01", &path) == 1) { - Check_SafeStr(path); + SafeStr(path); dist = RSTRING(path)->ptr; } else { @@ -467,7 +467,7 @@ dir_s_chroot(dir, path) { #if defined(HAVE_CHROOT) && !defined(__CHECKER__) rb_secure(2); - Check_SafeStr(path); + SafeStr(path); if (chroot(RSTRING(path)->ptr) == -1) rb_sys_fail(RSTRING(path)->ptr); @@ -495,7 +495,7 @@ dir_s_mkdir(argc, argv, obj) mode = 0777; } - Check_SafeStr(path); + SafeStr(path); rb_secure(2); #if !defined(NT) if (mkdir(RSTRING(path)->ptr, mode) == -1) @@ -512,7 +512,7 @@ static VALUE dir_s_rmdir(obj, dir) VALUE obj, dir; { - Check_SafeStr(dir); + SafeStr(dir); rb_secure(2); if (rmdir(RSTRING(dir)->ptr) < 0) rb_sys_fail(RSTRING(dir)->ptr); @@ -853,7 +853,7 @@ dir_s_glob(dir, str) int nest; VALUE ary = 0; - Check_SafeStr(str); + SafeStr(str); if (!rb_block_given_p()) { ary = rb_ary_new(); } diff --git a/eval.c b/eval.c index ffa465a6b1..80eabdac7c 100644 --- a/eval.c +++ b/eval.c @@ -4091,6 +4091,7 @@ static int STACK_LEVEL_MAX = 65535; #ifdef __human68k__ extern int _stacksize; # define STACK_LEVEL_MAX (_stacksize - 4096) +#undef HAVE_GETRLIMIT #else #ifdef HAVE_GETRLIMIT static int STACK_LEVEL_MAX = 655300; @@ -4857,10 +4858,10 @@ rb_f_eval(argc, argv, self) } if (ruby_safe_level >= 4) { - Check_Type(src, T_STRING); + src = rb_str_to_str(src); } else { - Check_SafeStr(src); + SafeStr(src); } if (NIL_P(scope) && ruby_frame->prev) { struct FRAME *prev; @@ -4932,10 +4933,10 @@ eval_under(under, self, src, file, line) VALUE args[4]; if (ruby_safe_level >= 4) { - Check_Type(src, T_STRING); + src = rb_str_to_str(src); } else { - Check_SafeStr(src); + SafeStr(src); } args[0] = self; args[1] = src; @@ -5002,16 +5003,17 @@ specific_eval(argc, argv, klass, self) else { char *file = "(eval)"; int line = 1; + VALUE src = argv[0]; if (argc == 0) { rb_raise(rb_eArgError, "block not supplied"); } else { if (ruby_safe_level >= 4) { - Check_Type(argv[0], T_STRING); + src = rb_str_to_str(src); } else { - Check_SafeStr(argv[0]); + SafeStr(src); } if (argc > 3) { rb_raise(rb_eArgError, "wrong # of arguments: %s(src) or %s{..}", @@ -5067,10 +5069,10 @@ rb_load(fname, wrap) TMP_PROTECT; if (wrap) { - Check_Type(fname, T_STRING); + fname = rb_str_to_str(fname); } else { - Check_SafeStr(fname); + SafeStr(fname); } file = rb_find_file(RSTRING(fname)->ptr); if (!file) { @@ -5264,7 +5266,7 @@ rb_f_require(obj, fname) int state; volatile int safe = ruby_safe_level; - Check_SafeStr(fname); + SafeStr(fname); if (rb_feature_p(RSTRING(fname)->ptr, Qtrue)) return Qfalse; ext = strrchr(RSTRING(fname)->ptr, '.'); diff --git a/file.c b/file.c index 2881e6c7b3..9f10a0faf8 100644 --- a/file.c +++ b/file.c @@ -84,12 +84,9 @@ apply2files(func, vargs, arg) VALUE path; struct RArray *args = RARRAY(vargs); - for (i=0; ilen; i++) { - Check_SafeStr(args->ptr[i]); - } - for (i=0; ilen; i++) { path = args->ptr[i]; + SafeStr(path); if ((*func)(RSTRING(path)->ptr, arg) < 0) rb_sys_fail(RSTRING(path)->ptr); } @@ -309,7 +306,7 @@ rb_stat(file, st) GetOpenFile(file, fptr); return fstat(fileno(fptr->f), st); } - Check_SafeStr(file); + SafeStr(file); #if defined DJGPP if (RSTRING(file)->len == 0) return -1; #endif @@ -322,7 +319,7 @@ rb_file_s_stat(obj, fname) { struct stat st; - Check_SafeStr(fname); + SafeStr(fname); if (stat(RSTRING(fname)->ptr, &st) == -1) { rb_sys_fail(RSTRING(fname)->ptr); } @@ -350,7 +347,7 @@ rb_file_s_lstat(obj, fname) #ifdef HAVE_LSTAT struct stat st; - Check_SafeStr(fname); + SafeStr(fname); if (lstat(RSTRING(fname)->ptr, &st) == -1) { rb_sys_fail(RSTRING(fname)->ptr); } @@ -503,7 +500,7 @@ test_l(obj, fname) #ifdef S_ISLNK struct stat st; - Check_SafeStr(fname); + SafeStr(fname); if (lstat(RSTRING(fname)->ptr, &st) < 0) return Qfalse; if (S_ISLNK(st.st_mode)) return Qtrue; #endif @@ -591,7 +588,7 @@ static VALUE test_r(obj, fname) VALUE obj, fname; { - Check_SafeStr(fname); + SafeStr(fname); if (eaccess(RSTRING(fname)->ptr, R_OK) < 0) return Qfalse; return Qtrue; } @@ -600,7 +597,7 @@ static VALUE test_R(obj, fname) VALUE obj, fname; { - Check_SafeStr(fname); + SafeStr(fname); if (access(RSTRING(fname)->ptr, R_OK) < 0) return Qfalse; return Qtrue; } @@ -609,7 +606,7 @@ static VALUE test_w(obj, fname) VALUE obj, fname; { - Check_SafeStr(fname); + SafeStr(fname); if (eaccess(RSTRING(fname)->ptr, W_OK) < 0) return Qfalse; return Qtrue; } @@ -618,7 +615,7 @@ static VALUE test_W(obj, fname) VALUE obj, fname; { - Check_SafeStr(fname); + SafeStr(fname); if (access(RSTRING(fname)->ptr, W_OK) < 0) return Qfalse; return Qtrue; } @@ -627,7 +624,7 @@ static VALUE test_x(obj, fname) VALUE obj, fname; { - Check_SafeStr(fname); + SafeStr(fname); if (eaccess(RSTRING(fname)->ptr, X_OK) < 0) return Qfalse; return Qtrue; } @@ -636,7 +633,7 @@ static VALUE test_X(obj, fname) VALUE obj, fname; { - Check_SafeStr(fname); + SafeStr(fname); if (access(RSTRING(fname)->ptr, X_OK) < 0) return Qfalse; return Qtrue; } @@ -732,7 +729,7 @@ test_suid(obj, fname) VALUE obj, fname; { #ifdef S_ISUID - Check_SafeStr(fname); + SafeStr(fname); return check3rdbyte(RSTRING(fname)->ptr, S_ISUID); #else return Qfalse; @@ -744,7 +741,7 @@ test_sgid(obj, fname) VALUE obj, fname; { #ifdef S_ISGID - Check_SafeStr(fname); + SafeStr(fname); return check3rdbyte(RSTRING(fname)->ptr, S_ISGID); #else return Qfalse; @@ -819,7 +816,7 @@ rb_file_s_ftype(obj, fname) { struct stat st; - Check_SafeStr(fname); + SafeStr(fname); if (lstat(RSTRING(fname)->ptr, &st) == -1) { rb_sys_fail(RSTRING(fname)->ptr); } @@ -1182,8 +1179,8 @@ static VALUE rb_file_s_link(obj, from, to) VALUE obj, from, to; { - Check_SafeStr(from); - Check_SafeStr(to); + SafeStr(from); + SafeStr(to); if (link(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0) rb_sys_fail(RSTRING(from)->ptr); @@ -1195,8 +1192,8 @@ rb_file_s_symlink(obj, from, to) VALUE obj, from, to; { #ifdef HAVE_SYMLINK - Check_SafeStr(from); - Check_SafeStr(to); + SafeStr(from); + SafeStr(to); if (symlink(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0) rb_sys_fail(RSTRING(from)->ptr); @@ -1215,8 +1212,7 @@ rb_file_s_readlink(obj, path) char buf[MAXPATHLEN]; int cc; - Check_SafeStr(path); - + SafeStr(path); if ((cc = readlink(RSTRING(path)->ptr, buf, MAXPATHLEN)) < 0) rb_sys_fail(RSTRING(path)->ptr); @@ -1249,8 +1245,8 @@ static VALUE rb_file_s_rename(obj, from, to) VALUE obj, from, to; { - Check_SafeStr(from); - Check_SafeStr(to); + SafeStr(from); + SafeStr(to); if (rename(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0) { #if defined __CYGWIN__ @@ -1514,7 +1510,7 @@ rb_file_s_truncate(obj, path, len) VALUE obj, path, len; { rb_secure(2); - Check_SafeStr(path); + SafeStr(path); #ifdef HAVE_TRUNCATE if (truncate(RSTRING(path)->ptr, NUM2INT(len)) < 0) @@ -1659,7 +1655,7 @@ test_check(n, argc, argv) for (i=1; ilen;i++) { VALUE str = RARRAY(rb_load_path)->ptr[i]; - Check_SafeStr(str); + SafeStr(str); if (RSTRING(str)->len > 0) { rb_ary_push(vpath, str); } diff --git a/intern.h b/intern.h index 1d0f38b60d..9e89ae9f2b 100644 --- a/intern.h +++ b/intern.h @@ -310,7 +310,6 @@ VALUE rb_str_new4 _((VALUE)); VALUE rb_tainted_str_new _((const char*, long)); VALUE rb_tainted_str_new2 _((const char*)); VALUE rb_obj_as_string _((VALUE)); -VALUE rb_str_to_str _((VALUE)); VALUE rb_str_dup _((VALUE)); VALUE rb_str_plus _((VALUE, VALUE)); VALUE rb_str_times _((VALUE, VALUE)); diff --git a/io.c b/io.c index 56e2b6361c..237f9d55fd 100644 --- a/io.c +++ b/io.c @@ -606,11 +606,11 @@ rb_io_gets_internal(argc, argv, io) VALUE rs; if (argc == 0) { - rs = rb_rs; + rs = rb_str_to_str(rb_rs); } else { rb_scan_args(argc, argv, "1", &rs); - if (!NIL_P(rs)) Check_Type(rs, T_STRING); + if (!NIL_P(rs)) rs = rb_str_to_str(rs); } if (NIL_P(rs)) { @@ -1687,7 +1687,7 @@ rb_io_popen(str, argc, argv, klass) else { mode = STR2CSTR(pmode); } - Check_SafeStr(pname); + SafeStr(pname); port = pipe_open(str, mode); if (NIL_P(port)) { /* child */ @@ -1732,7 +1732,7 @@ rb_file_s_open(argc, argv, klass) NEWOBJ(io, struct RFile); OBJSETUP(io, klass, T_FILE); rb_scan_args(argc, argv, "12", &fname, &vmode, &perm); - Check_SafeStr(fname); + SafeStr(fname); path = RSTRING(fname)->ptr; RFILE(io)->fptr = 0; @@ -1897,7 +1897,7 @@ rb_io_reopen(argc, argv, file) } } - Check_SafeStr(fname); + SafeStr(fname); if (!NIL_P(nmode)) { mode = STR2CSTR(nmode); } @@ -2361,7 +2361,7 @@ rb_io_initialize(argc, argv, io) RFILE(io)->fptr = 0; } if (rb_scan_args(argc, argv, "11", &fnum, &mode) == 2) { - Check_SafeStr(mode); + SafeStr(mode); m = RSTRING(mode)->ptr; } MakeOpenFile(io, fp); @@ -2381,7 +2381,7 @@ rb_file_initialize(argc, argv, io) char *path, *mode; rb_scan_args(argc, argv, "12", &fname, &vmode, &perm); - Check_SafeStr(fname); + SafeStr(fname); path = RSTRING(fname)->ptr; if (RFILE(io)->fptr) { @@ -2424,7 +2424,7 @@ rb_io_s_for_fd(argc, argv, klass) OBJSETUP(io, klass, T_FILE); if (rb_scan_args(argc, argv, "11", &fnum, &mode) == 2) { - Check_SafeStr(mode); + SafeStr(mode); m = RSTRING(mode)->ptr; } MakeOpenFile(io, fp); @@ -2681,7 +2681,7 @@ rb_f_backquote(obj, str) { VALUE port, result; - Check_SafeStr(str); + SafeStr(str); port = pipe_open(RSTRING(str)->ptr, "r"); if (NIL_P(port)) return rb_str_new(0,0); result = read_all(port); @@ -2832,6 +2832,7 @@ rb_f_select(argc, argv, obj) return res; /* returns an empty array on interrupt */ } +#if !defined(MSDOS) && !defined(__human68k__) static int io_cntl(fd,cmd,narg,io_p) int fd, cmd, io_p; @@ -2857,6 +2858,7 @@ io_cntl(fd,cmd,narg,io_p) #endif return retval; } +#endif static VALUE rb_io_ctl(io, req, arg, io_p) @@ -2979,13 +2981,15 @@ rb_f_syscall(argc, argv) arg[0] = NUM2INT(argv[0]); argv++; while (items--) { if (FIXNUM_P(*argv)) { - arg[i] = (unsigned long)NUM2INT(*argv); argv++; + arg[i] = (unsigned long)NUM2INT(*argv); } else { - Check_Type(*argv, T_STRING); - rb_str_modify(*argv); - arg[i] = (unsigned long)RSTRING(*argv)->ptr; argv++; + VALUE v = rb_str_to_str(*argv); + + rb_str_modify(v); + arg[i] = (unsigned long)RSTRING(*argv)->ptr; } + argv++; i++; } TRAP_BEG; @@ -3103,7 +3107,7 @@ rb_io_s_foreach(argc, argv, io) struct foreach_arg arg; rb_scan_args(argc, argv, "11", &fname, &arg.sep); - Check_SafeStr(fname); + SafeStr(fname); arg.argc = argc - 1; arg.io = rb_io_open(RSTRING(fname)->ptr, "r"); @@ -3128,7 +3132,7 @@ rb_io_s_readlines(argc, argv, io) struct foreach_arg arg; rb_scan_args(argc, argv, "11", &fname, &arg.sep); - Check_SafeStr(fname); + SafeStr(fname); arg.argc = argc - 1; arg.io = rb_io_open(RSTRING(fname)->ptr, "r"); @@ -3153,7 +3157,7 @@ rb_io_s_read(argc, argv, io) struct foreach_arg arg; rb_scan_args(argc, argv, "12", &fname, &arg.sep, &offset); - Check_SafeStr(fname); + SafeStr(fname); arg.argc = argc ? 1 : 0; arg.io = rb_io_open(RSTRING(fname)->ptr, "r"); diff --git a/object.c b/object.c index a9f8b0297e..fa08e0ae19 100644 --- a/object.c +++ b/object.c @@ -1058,6 +1058,9 @@ rb_str2cstr(str, len) str = rb_str_to_str(str); } if (len) *len = RSTRING(str)->len; + else if (ruby_verbose && RSTRING(str)->len != strlen(RSTRING(str)->ptr)) { + rb_warn("string contains \\0 character"); + } return RSTRING(str)->ptr; } diff --git a/prec.c b/prec.c index d30969b3a8..3d33fe55f1 100644 --- a/prec.c +++ b/prec.c @@ -47,6 +47,7 @@ prec_induced_from(module, x) { rb_raise(rb_eTypeError, "undefined conversion from %s into %s", rb_class2name(CLASS_OF(x)), rb_class2name(module)); + return Qnil; /* not reached */ } static VALUE diff --git a/process.c b/process.c index 7f62331d83..101a4d0c89 100644 --- a/process.c +++ b/process.c @@ -564,6 +564,7 @@ proc_exec_n(argc, argv, progv) } args = ALLOCA_N(char*, argc+1); for (i=0; iptr; } args[i] = 0; @@ -690,10 +691,10 @@ proc_spawn_n(argc, argv, prog) args = ALLOCA_N(char*, argc + 1); for (i = 0; i < argc; i++) { - Check_SafeStr(argv[i]); + SafeStr(argv[i]); args[i] = RSTRING(argv[i])->ptr; } - Check_SafeStr(prog); + SafeStr(prog); args[i] = (char*) 0; if (args[0]) return proc_spawn_v(args, RSTRING(prog)->ptr); @@ -709,7 +710,7 @@ proc_spawn(sv) char **argv, **a; int status; - Check_SafeStr(sv); + SafeStr(sv); str = s = RSTRING(sv)->ptr; for (s = str; *s; s++) { if (*s != ' ' && !ISALPHA(*s) && strchr("*?{}[]<>()~&|\\$;'`\"\n",*s)) { @@ -752,13 +753,13 @@ rb_f_exec(argc, argv) argv[0] = RARRAY(argv[0])->ptr[1]; } if (prog) { - Check_SafeStr(prog); - } - for (i = 0; i < argc; i++) { - Check_SafeStr(argv[i]); + SafeStr(prog); } if (argc == 1 && prog == 0) { - rb_proc_exec(RSTRING(argv[0])->ptr); + VALUE cmd = argv[0]; + + SafeStr(cmd); + rb_proc_exec(RSTRING(cmd)->ptr); } else { proc_exec_n(argc, argv, prog); @@ -875,7 +876,7 @@ rb_f_system(argc, argv) } cmd = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" ")); - Check_SafeStr(cmd); + SafeStr(cmd); status = do_spawn(RSTRING(cmd)->ptr); last_status_set(status); @@ -899,7 +900,7 @@ rb_f_system(argc, argv) } cmd = rb_ary_join(rb_ary_new4(argc, argv), rb_str_new2(" ")); - Check_SafeStr(cmd); + SafeStr(cmd); status = system(RSTRING(cmd)->ptr); last_status_set((status & 0xff) << 8); @@ -956,10 +957,10 @@ rb_f_system(argc, argv) } if (prog) { - Check_SafeStr(prog); + SafeStr(prog); } for (i = 0; i < argc; i++) { - Check_SafeStr(argv[i]); + SafeStr(argv[i]); } retry: switch (pid = vfork()) { diff --git a/ruby.h b/ruby.h index 03c9b61f3d..839bbb5e52 100644 --- a/ruby.h +++ b/ruby.h @@ -177,7 +177,14 @@ VALUE rb_uint2inum _((unsigned long)); void rb_check_type _((VALUE,int)); #define Check_Type(v,t) rb_check_type((VALUE)(v),t) void rb_check_safe_str _((VALUE)); +/* obsolete macro - use SafeStr(v) */ #define Check_SafeStr(v) rb_check_safe_str((VALUE)(v)) +VALUE rb_str_to_str _((VALUE)); +#define SafeStr(v) do {\ + v = rb_str_to_str(v);\ + rb_check_safe_str(v);\ +} while (0) + void rb_secure _((int)); EXTERN int ruby_safe_level; diff --git a/signal.c b/signal.c index 5222dc7400..a2221aca50 100644 --- a/signal.c +++ b/signal.c @@ -465,7 +465,7 @@ trap(arg) func = SIG_IGN; } else if (TYPE(command) == T_STRING) { - Check_SafeStr(command); /* taint check */ + SafeStr(command); /* taint check */ if (RSTRING(command)->len == 0) { func = SIG_IGN; } diff --git a/version.h b/version.h index 1ba0f06af8..75caba04f0 100644 --- a/version.h +++ b/version.h @@ -1,4 +1,4 @@ #define RUBY_VERSION "1.7.0" -#define RUBY_RELEASE_DATE "2001-03-27" +#define RUBY_RELEASE_DATE "2001-03-28" #define RUBY_VERSION_CODE 170 -#define RUBY_RELEASE_CODE 20010327 +#define RUBY_RELEASE_CODE 20010328