* 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
This commit is contained in:
matz 2001-11-08 06:43:14 +00:00
Родитель ab827130d3
Коммит dc98adf839
17 изменённых файлов: 201 добавлений и 109 удалений

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

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

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

@ -609,6 +609,17 @@ rb_big_eq(x, y)
return Qtrue;
}
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);

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

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

22
dir.c
Просмотреть файл

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

4
eval.c
Просмотреть файл

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

78
file.c
Просмотреть файл

@ -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(path)) {
char buf[MAXPATHLEN+1];
if (!is_absolute_path(p0)) {
char *buf = my_getcwd();
VALUE newpath;
if (getcwd(buf, MAXPATHLEN) == 0) return 0;
strncat(buf, "/", MAXPATHLEN);
strncat(buf, path, MAXPATHLEN);
buf[MAXPATHLEN] = '\0';
return path_check_1(buf);
newpath = rb_str_new2(buf);
free(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;
}

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

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

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

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

66
parse.y
Просмотреть файл

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

17
ruby.h
Просмотреть файл

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

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

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

15
util.c
Просмотреть файл

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

3
util.h
Просмотреть файл

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