diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-11-08 06:43:14 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-11-08 06:43:14 +0000 |
commit | dc98adf839d0d68c4c18647a1db2fb3dc9be8cc4 (patch) | |
tree | 7f6e3c4b45359409bf57526308837f5dbbc45905 | |
parent | ab827130d3f563535abb7404230f5b5e63bf0946 (diff) | |
download | ruby-dc98adf839d0d68c4c18647a1db2fb3dc9be8cc4.tar.gz |
* process.c (security): always give warning for insecure PATH.
* dir.c (my_getcwd): do not rely on MAXPATHLEN.
* file.c (rb_file_s_readlink): ditto.
* file.c (path_check_1): ditto.
* eval.c (rb_yield_0): should not call rb_f_block_given_p().
* string.c (rb_str_chomp_bang): should terminate string by NUL.
* eval.c (rb_yield_0): better error message.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1816 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | Makefile.in | 2 | ||||
-rw-r--r-- | bignum.c | 13 | ||||
-rw-r--r-- | configure.in | 4 | ||||
-rw-r--r-- | dir.c | 22 | ||||
-rw-r--r-- | doc/NEWS | 33 | ||||
-rw-r--r-- | eval.c | 4 | ||||
-rw-r--r-- | file.c | 78 | ||||
-rw-r--r-- | lib/resolv.rb | 14 | ||||
-rw-r--r-- | lib/weakref.rb | 6 | ||||
-rw-r--r-- | parse.y | 66 | ||||
-rw-r--r-- | process.c | 9 | ||||
-rw-r--r-- | ruby.h | 17 | ||||
-rw-r--r-- | sample/test.rb | 10 | ||||
-rw-r--r-- | string.c | 10 | ||||
-rw-r--r-- | util.c | 15 | ||||
-rw-r--r-- | util.h | 3 | ||||
-rw-r--r-- | version.h | 4 |
17 files changed, 201 insertions, 109 deletions
diff --git a/Makefile.in b/Makefile.in index ac2cf879f1..bd197ded87 100644 --- a/Makefile.in +++ b/Makefile.in @@ -249,7 +249,7 @@ dmyext.@OBJEXT@: dmyext.c enum.@OBJEXT@: enum.c ruby.h config.h defines.h intern.h node.h error.@OBJEXT@: error.c ruby.h config.h defines.h intern.h env.h version.h eval.@OBJEXT@: eval.c ruby.h config.h defines.h intern.h node.h env.h rubysig.h st.h dln.h -file.@OBJEXT@: file.c ruby.h config.h defines.h intern.h rubyio.h rubysig.h dln.h +file.@OBJEXT@: file.c ruby.h config.h defines.h intern.h rubyio.h rubysig.h dln.h util.h gc.@OBJEXT@: gc.c ruby.h config.h defines.h intern.h rubysig.h st.h node.h env.h re.h regex.h hash.@OBJEXT@: hash.c ruby.h config.h defines.h intern.h st.h rubysig.h util.h inits.@OBJEXT@: inits.c ruby.h config.h defines.h intern.h @@ -610,6 +610,17 @@ rb_big_eq(x, y) } static VALUE +rb_big_eql(x, y) + VALUE x, y; +{ + if (TYPE(y) != T_BIGNUM) return Qfalse; + if (RBIGNUM(x)->sign != RBIGNUM(y)->sign) return Qfalse; + if (RBIGNUM(x)->len != RBIGNUM(y)->len) return Qfalse; + if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,RBIGNUM(y)->len) != 0) return Qfalse; + return Qtrue; +} + +static VALUE rb_big_uminus(x) VALUE x; { @@ -1454,7 +1465,7 @@ Init_Bignum() rb_define_method(rb_cBignum, "<=>", rb_big_cmp, 1); rb_define_method(rb_cBignum, "==", rb_big_eq, 1); rb_define_method(rb_cBignum, "===", rb_big_eq, 1); - rb_define_method(rb_cBignum, "eql?", rb_big_eq, 1); + rb_define_method(rb_cBignum, "eql?", rb_big_eql, 1); rb_define_method(rb_cBignum, "hash", rb_big_hash, 0); rb_define_method(rb_cBignum, "to_f", rb_big_to_f, 0); rb_define_method(rb_cBignum, "abs", rb_big_abs, 0); diff --git a/configure.in b/configure.in index a8c30589ba..b752a81ab7 100644 --- a/configure.in +++ b/configure.in @@ -293,7 +293,7 @@ AC_FUNC_MEMCMP AC_REPLACE_FUNCS(dup2 memmove mkdir strcasecmp strncasecmp strerror strftime\ strchr strstr strtoul crypt flock vsnprintf\ isinf isnan finite hypot) -AC_CHECK_FUNCS(fmod killpg drand48 random wait4 waitpid syscall getcwd chroot\ +AC_CHECK_FUNCS(fmod killpg drand48 random wait4 waitpid syscall chroot\ truncate chsize times utimes fcntl lockf lstat symlink readlink\ setitimer setruid seteuid setreuid setresuid setproctitle\ setrgid setegid setregid setresgid pause lchown lchmod\ @@ -581,7 +581,7 @@ if test "$with_dln_a_out" != yes; then LDFLAGS="-Wl,-E" rb_cv_dlopen=yes;; solaris*) if test "$GCC" = yes; then - LDSHARED='$(CC) -Wl,-G' + LDSHARED='$(CC) -Wl,-G -shared' `$CC --print-prog-name=ld` -v 2>&1 | grep "GNU ld" > /dev/null && LDFLAGS="-Wl,-E" else LDSHARED='ld -G' @@ -61,6 +61,8 @@ char *strchr _((char*,char)); #include <ctype.h> +#include "util.h" + #ifndef HAVE_LSTAT #define lstat(path,st) stat(path,st) #endif @@ -430,21 +432,16 @@ static VALUE chdir_thread = Qnil; static VALUE chdir_restore(path) - const char *path; + char *path; { chdir_blocking--; if (chdir_blocking == 0) chdir_thread = Qnil; dir_chdir(path); + free(path); return Qnil; } -#ifdef HAVE_GETCWD -#define GETCWD(path) if (getcwd(path, sizeof(path)) == 0) rb_sys_fail(path) -#else -#define GETCWD(path) if (getwd(path) == 0) rb_sys_fail(path) -#endif - static VALUE dir_s_chdir(argc, argv, obj) int argc; @@ -473,9 +470,7 @@ dir_s_chdir(argc, argv, obj) } if (rb_block_given_p()) { - char cwd[MAXPATHLEN]; - - GETCWD(cwd); + char *cwd = my_getcwd(); chdir_blocking++; if (chdir_thread == Qnil) chdir_thread = rb_thread_current(); @@ -491,10 +486,11 @@ static VALUE dir_s_getwd(dir) VALUE dir; { - char path[MAXPATHLEN]; + char *path = my_getcwd(); + VALUE cwd = rb_tainted_str_new2(path); - GETCWD(path); - return rb_tainted_str_new2(path); + free(path); + return cwd; } static VALUE @@ -1,3 +1,36 @@ +: String#chomp + + if $/ == '\n', chops off last newlines (any of \n, \r, \r\n). + +: IO#puts + + do not treat Array specially. + +: Module::new/Class::new + + takes block. + +: allocation framework + + any instance of class can be allocated by class.allocate, + (except a few classes). + +: String#[] + + starting offset can be specified as optional second parameter. + +: String/Array methods + + returns an instance of receivers class. + +: String::new + + returns "". + +: Dir#path + + Added. + : Enum#sort_by Added. @@ -3645,8 +3645,8 @@ rb_yield_0(val, self, klass, pcall) int state; static unsigned serial = 1; - if (!(rb_block_given_p() || rb_f_block_given_p())) { - rb_raise(rb_eLocalJumpError, "yield called out of block"); + if (!rb_block_given_p()) { + rb_raise(rb_eLocalJumpError, "no block given"); } PUSH_VARS(); @@ -19,6 +19,7 @@ #include "ruby.h" #include "rubyio.h" #include "rubysig.h" +#include "util.h" #include "dln.h" #ifdef HAVE_UNISTD_H @@ -1225,14 +1226,22 @@ rb_file_s_readlink(klass, path) VALUE klass, path; { #ifdef HAVE_READLINK - char buf[MAXPATHLEN]; - int cc; + char *buf; + int size = 100; + int rv; + VALUE v; SafeStringValue(path); - if ((cc = readlink(RSTRING(path)->ptr, buf, MAXPATHLEN)) < 0) - rb_sys_fail(RSTRING(path)->ptr); + buf = xmalloc(size); + if ((rv = readlink(RSTRING(path)->ptr, buf, size)) == size) { + size *= 2; + buf = xrealloc(buf, size); + } + if (rv < 0) rb_sys_fail(RSTRING(path)->ptr); + v = rb_tainted_str_new(buf, rv); + free(buf); - return rb_tainted_str_new(buf, cc); + return v; #else rb_notimplement(); return Qnil; /* not reached */ @@ -1297,10 +1306,6 @@ rb_file_s_umask(argc, argv) return INT2FIX(omask); } -#ifndef HAVE_GETCWD -#define getcwd(buf, len) ((void)(len), getwd(buf)) -#endif - #if defined DOSISH #define isdirsep(x) ((x) == '/' || (x) == '\\') #else @@ -2228,29 +2233,31 @@ is_absolute_path(path) static int path_check_1(path) - char *path; + VALUE path; { struct stat st; - char *p = 0; - char *s; + char *p0 = RSTRING(path)->ptr; + char *p, *s; + + if (!is_absolute_path(p0)) { + char *buf = my_getcwd(); + VALUE newpath; - if (!is_absolute_path(path)) { - char buf[MAXPATHLEN+1]; + newpath = rb_str_new2(buf); + free(buf); - if (getcwd(buf, MAXPATHLEN) == 0) return 0; - strncat(buf, "/", MAXPATHLEN); - strncat(buf, path, MAXPATHLEN); - buf[MAXPATHLEN] = '\0'; - return path_check_1(buf); + rb_str_cat2(newpath, "/"); + rb_str_cat2(newpath, p0); + return path_check_1(newpath); } for (;;) { - if (stat(path, &st) == 0 && (st.st_mode & 002)) { + if (stat(p0, &st) == 0 && (st.st_mode & 002)) { if (p) *p = '/'; return 0; } - s = strrdirsep(path); + s = strrdirsep(p0); if (p) *p = '/'; - if (!s || s == path) return 1; + if (!s || s == p0) return 1; p = s; *p = '\0'; } @@ -2260,27 +2267,24 @@ int rb_path_check(path) char *path; { - char *p, *pend; + char *p0, *p, *pend; const char sep = PATH_SEP_CHAR; if (!path) return 1; - p = path; - pend = strchr(path, sep); + pend = path + strlen(path); + p0 = path; + p = strchr(path, sep); + if (!p) p = pend; for (;;) { - int safe; - - if (pend) *pend = '\0'; - safe = path_check_1(p); - if (!safe) { - if (pend) *pend = sep; - return 0; - } - if (!pend) break; - *pend = sep; - p = pend + 1; - pend = strchr(p, sep); + if (!path_check_1(rb_str_new(p0, p - p0))) { + return 0; /* not safe */ + } + if (p0 > pend) break; + p0 = p + 1; + p = strchr(p0, sep); + if (!p) p = pend; } return 1; } diff --git a/lib/resolv.rb b/lib/resolv.rb index dd7bddc6d6..5caaa1af5f 100644 --- a/lib/resolv.rb +++ b/lib/resolv.rb @@ -76,7 +76,7 @@ DNS stub resolver. --- Resolv::DNS#getresource(name, typeclass) --- Resolv::DNS#getresources(name, typeclass) ---- Resolv::DNS#each_resources(name, typeclass) {|resource| ...} +--- Resolv::DNS#each_resource(name, typeclass) {|resource| ...} They lookup DNS resources of ((|name|)). ((|name|)) must be a instance of Resolv::Name or String. @@ -370,7 +370,7 @@ class Resolv end def each_address(name) - each_resources(name, Resource::IN::A) {|resource| yield resource.address} + each_resource(name, Resource::IN::A) {|resource| yield resource.address} end def getname(address) @@ -395,21 +395,21 @@ class Resolv else raise ResolvError.new("cannot interpret as address: #{address}") end - each_resources(ptr, Resource::IN::PTR) {|resource| yield resource.name} + each_resource(ptr, Resource::IN::PTR) {|resource| yield resource.name} end def getresource(name, typeclass) - each_resources(name, typeclass) {|resource| return resource} + each_resource(name, typeclass) {|resource| return resource} raise ResolvError.new("DNS result has no information for #{name}") end def getresources(name, typeclass) ret = [] - each_resources(name, typeclass) {|resource| ret << resource} + each_resource(name, typeclass) {|resource| ret << resource} return ret end - def each_resources(name, typeclass, &proc) + def each_resource(name, typeclass, &proc) lazy_initialize q = Queue.new senders = {} @@ -1594,7 +1594,7 @@ class Resolv def initialize(address) unless address.kind_of?(String) && address.length == 16 - raise ArgumentError.new('IPv4 address muse be 16 bytes') + raise ArgumentError.new('IPv6 address muse be 16 bytes') end @address = address end diff --git a/lib/weakref.rb b/lib/weakref.rb index 459f69f924..6861fde5f5 100644 --- a/lib/weakref.rb +++ b/lib/weakref.rb @@ -60,7 +60,11 @@ class WeakRef<Delegator unless ID_MAP[@__id] raise RefError, "Illegal Reference - probably recycled", caller(2) end - ObjectSpace._id2ref(@__id) + begin + ObjectSpace._id2ref(@__id) + rescue RangeError + raise RefError, "Illegal Reference - probably recycled", caller(2) + end end def weakref_alive? @@ -428,24 +428,29 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem | variable tOP_ASGN command_call { NODE *n = assignable($1, 0); - if ($2 == tOROP) { - n->nd_value = $3; - $$ = NEW_OP_ASGN_OR(gettable($1), n); - if (is_instance_id($1)) { - $$->nd_aid = $1; + if (n) { + if ($2 == tOROP) { + n->nd_value = $3; + $$ = NEW_OP_ASGN_OR(gettable($1), n); + if (is_instance_id($1)) { + $$->nd_aid = $1; + } } - } - else if ($2 == tANDOP) { - n->nd_value = $3; - $$ = NEW_OP_ASGN_AND(gettable($1), n); + else if ($2 == tANDOP) { + n->nd_value = $3; + $$ = NEW_OP_ASGN_AND(gettable($1), n); + } + else { + $$ = n; + if ($$) { + $$->nd_value = call_op(gettable($1),$2,1,$3); + } + } + fixpos($$, $3); } else { - $$ = n; - if ($$) { - $$->nd_value = call_op(gettable($1),$2,1,$3); - } + $$ = 0; } - fixpos($$, $3); } | primary '[' aref_args ']' tOP_ASGN command_call { @@ -770,24 +775,29 @@ arg : lhs '=' arg | variable tOP_ASGN arg { NODE *n = assignable($1, 0); - if ($2 == tOROP) { - n->nd_value = $3; - $$ = NEW_OP_ASGN_OR(gettable($1), n); - if (is_instance_id($1)) { - $$->nd_aid = $1; + if (n) { + if ($2 == tOROP) { + n->nd_value = $3; + $$ = NEW_OP_ASGN_OR(gettable($1), n); + if (is_instance_id($1)) { + $$->nd_aid = $1; + } } - } - else if ($2 == tANDOP) { - n->nd_value = $3; - $$ = NEW_OP_ASGN_AND(gettable($1), n); + else if ($2 == tANDOP) { + n->nd_value = $3; + $$ = NEW_OP_ASGN_AND(gettable($1), n); + } + else { + $$ = n; + if ($$) { + $$->nd_value = call_op(gettable($1),$2,1,$3); + } + } + fixpos($$, $3); } else { - $$ = n; - if ($$) { - $$->nd_value = call_op(gettable($1),$2,1,$3); - } + $$ = 0; } - fixpos($$, $3); } | primary '[' aref_args ']' tOP_ASGN arg { @@ -422,10 +422,13 @@ static void security(str) char *str; { - if (rb_safe_level() > 0) { - if (rb_env_path_tainted()) { + if (rb_env_path_tainted()) { + if (rb_safe_level() > 0) { rb_raise(rb_eSecurityError, "Insecure PATH - %s", str); } + else { + rb_warn("Insecure PATH - %s", str); + } } } @@ -521,8 +524,6 @@ rb_proc_exec(str) char *ss, *t; char **argv, **a; - security(str); - while (*str && ISSPACE(*str)) str++; @@ -35,15 +35,16 @@ extern "C" { #include <stdio.h> /* need to include <ctype.h> to use these macros */ +#define ISASCII(c) isascii((unsigned char)(c)) #undef ISPRINT -#define ISPRINT(c) isprint((unsigned char)(c)) -#define ISSPACE(c) isspace((unsigned char)(c)) -#define ISUPPER(c) isupper((unsigned char)(c)) -#define ISLOWER(c) islower((unsigned char)(c)) -#define ISALNUM(c) isalnum((unsigned char)(c)) -#define ISALPHA(c) isalpha((unsigned char)(c)) -#define ISDIGIT(c) isdigit((unsigned char)(c)) -#define ISXDIGIT(c) isxdigit((unsigned char)(c)) +#define ISPRINT(c) (ISASCII(c) && isprint((unsigned char)(c))) +#define ISSPACE(c) (ISASCII(c) && isspace((unsigned char)(c))) +#define ISUPPER(c) (ISASCII(c) && isupper((unsigned char)(c))) +#define ISLOWER(c) (ISASCII(c) && islower((unsigned char)(c))) +#define ISALNUM(c) (ISASCII(c) && isalnum((unsigned char)(c))) +#define ISALPHA(c) (ISASCII(c) && isalpha((unsigned char)(c))) +#define ISDIGIT(c) (ISASCII(c) && isdigit((unsigned char)(c))) +#define ISXDIGIT(c) (ISASCII(c) && isxdigit((unsigned char)(c))) #if !defined(__STDC__) && !defined(_MSC_VER) # define volatile diff --git a/sample/test.rb b/sample/test.rb index 104ff2900d..4ee6ddcec8 100644 --- a/sample/test.rb +++ b/sample/test.rb @@ -1329,6 +1329,16 @@ begin rescue test_ok false end +class S + def initialize(a) + @a = a + end +end +l=nil +100000.times { + l = S.new(l) +} +test_ok true # reach here or dumps core if $failed > 0 printf "test: %d failed %d\n", $ntest, $failed @@ -291,6 +291,8 @@ rb_str_dup(str) } else if (RSTRING(str)->orig) { str2 = rb_str_new3(RSTRING(str)->orig); + FL_UNSET(str2, FL_TAINT); + OBJ_INFECT(str2, str); } else { str2 = rb_str_new3(rb_str_new4(str)); @@ -2673,13 +2675,15 @@ rb_str_chomp_bang(argc, argv, str) RSTRING(str)->ptr[RSTRING(str)->len-1] == '\r') { RSTRING(str)->len--; } - return str; } else if (RSTRING(str)->ptr[len-1] == '\r') { RSTRING(str)->len--; - return str; } - return Qnil; + else { + return Qnil; + } + RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; + return str; } } if (NIL_P(rs)) return Qnil; @@ -11,6 +11,7 @@ **********************************************************************/ #include <stdio.h> +#include <errno.h> #ifdef NT #include "missing/file.h" @@ -628,3 +629,17 @@ ruby_strdup(str) return tmp; } + +char * +ruby_getcwd() +{ + int size = 200; + char *buf = xmalloc(size); + + while (!getcwd(buf, size)) { + if (errno != ERANGE) rb_sys_fail(buf); + size *= 2; + buf = xrealloc(buf, size); + } + return buf; +} @@ -50,4 +50,7 @@ char *ruby_strdup _((const char*)); #undef strdup #define strdup(s) ruby_strdup((s)) +char *ruby_getcwd _((void)); +#define my_getcwd() ruby_getcwd() + #endif /* UTIL_H */ @@ -1,4 +1,4 @@ #define RUBY_VERSION "1.7.2" -#define RUBY_RELEASE_DATE "2001-11-02" +#define RUBY_RELEASE_DATE "2001-11-08" #define RUBY_VERSION_CODE 172 -#define RUBY_RELEASE_CODE 20011102 +#define RUBY_RELEASE_CODE 20011108 |