Skip to content

Commit dc98adf

Browse files
author
matz
committed
* 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
1 parent ab82713 commit dc98adf

File tree

17 files changed

+201
-109
lines changed

17 files changed

+201
-109
lines changed

Makefile.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ dmyext.@OBJEXT@: dmyext.c
249249
enum.@OBJEXT@: enum.c ruby.h config.h defines.h intern.h node.h
250250
error.@OBJEXT@: error.c ruby.h config.h defines.h intern.h env.h version.h
251251
eval.@OBJEXT@: eval.c ruby.h config.h defines.h intern.h node.h env.h rubysig.h st.h dln.h
252-
file.@OBJEXT@: file.c ruby.h config.h defines.h intern.h rubyio.h rubysig.h dln.h
252+
file.@OBJEXT@: file.c ruby.h config.h defines.h intern.h rubyio.h rubysig.h dln.h util.h
253253
gc.@OBJEXT@: gc.c ruby.h config.h defines.h intern.h rubysig.h st.h node.h env.h re.h regex.h
254254
hash.@OBJEXT@: hash.c ruby.h config.h defines.h intern.h st.h rubysig.h util.h
255255
inits.@OBJEXT@: inits.c ruby.h config.h defines.h intern.h

bignum.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,17 @@ rb_big_eq(x, y)
609609
return Qtrue;
610610
}
611611

612+
static VALUE
613+
rb_big_eql(x, y)
614+
VALUE x, y;
615+
{
616+
if (TYPE(y) != T_BIGNUM) return Qfalse;
617+
if (RBIGNUM(x)->sign != RBIGNUM(y)->sign) return Qfalse;
618+
if (RBIGNUM(x)->len != RBIGNUM(y)->len) return Qfalse;
619+
if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,RBIGNUM(y)->len) != 0) return Qfalse;
620+
return Qtrue;
621+
}
622+
612623
static VALUE
613624
rb_big_uminus(x)
614625
VALUE x;
@@ -1454,7 +1465,7 @@ Init_Bignum()
14541465
rb_define_method(rb_cBignum, "<=>", rb_big_cmp, 1);
14551466
rb_define_method(rb_cBignum, "==", rb_big_eq, 1);
14561467
rb_define_method(rb_cBignum, "===", rb_big_eq, 1);
1457-
rb_define_method(rb_cBignum, "eql?", rb_big_eq, 1);
1468+
rb_define_method(rb_cBignum, "eql?", rb_big_eql, 1);
14581469
rb_define_method(rb_cBignum, "hash", rb_big_hash, 0);
14591470
rb_define_method(rb_cBignum, "to_f", rb_big_to_f, 0);
14601471
rb_define_method(rb_cBignum, "abs", rb_big_abs, 0);

configure.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ AC_FUNC_MEMCMP
293293
AC_REPLACE_FUNCS(dup2 memmove mkdir strcasecmp strncasecmp strerror strftime\
294294
strchr strstr strtoul crypt flock vsnprintf\
295295
isinf isnan finite hypot)
296-
AC_CHECK_FUNCS(fmod killpg drand48 random wait4 waitpid syscall getcwd chroot\
296+
AC_CHECK_FUNCS(fmod killpg drand48 random wait4 waitpid syscall chroot\
297297
truncate chsize times utimes fcntl lockf lstat symlink readlink\
298298
setitimer setruid seteuid setreuid setresuid setproctitle\
299299
setrgid setegid setregid setresgid pause lchown lchmod\
@@ -581,7 +581,7 @@ if test "$with_dln_a_out" != yes; then
581581
LDFLAGS="-Wl,-E"
582582
rb_cv_dlopen=yes;;
583583
solaris*) if test "$GCC" = yes; then
584-
LDSHARED='$(CC) -Wl,-G'
584+
LDSHARED='$(CC) -Wl,-G -shared'
585585
`$CC --print-prog-name=ld` -v 2>&1 | grep "GNU ld" > /dev/null && LDFLAGS="-Wl,-E"
586586
else
587587
LDSHARED='ld -G'

dir.c

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ char *strchr _((char*,char));
6161

6262
#include <ctype.h>
6363

64+
#include "util.h"
65+
6466
#ifndef HAVE_LSTAT
6567
#define lstat(path,st) stat(path,st)
6668
#endif
@@ -430,21 +432,16 @@ static VALUE chdir_thread = Qnil;
430432

431433
static VALUE
432434
chdir_restore(path)
433-
const char *path;
435+
char *path;
434436
{
435437
chdir_blocking--;
436438
if (chdir_blocking == 0)
437439
chdir_thread = Qnil;
438440
dir_chdir(path);
441+
free(path);
439442
return Qnil;
440443
}
441444

442-
#ifdef HAVE_GETCWD
443-
#define GETCWD(path) if (getcwd(path, sizeof(path)) == 0) rb_sys_fail(path)
444-
#else
445-
#define GETCWD(path) if (getwd(path) == 0) rb_sys_fail(path)
446-
#endif
447-
448445
static VALUE
449446
dir_s_chdir(argc, argv, obj)
450447
int argc;
@@ -473,9 +470,7 @@ dir_s_chdir(argc, argv, obj)
473470
}
474471

475472
if (rb_block_given_p()) {
476-
char cwd[MAXPATHLEN];
477-
478-
GETCWD(cwd);
473+
char *cwd = my_getcwd();
479474
chdir_blocking++;
480475
if (chdir_thread == Qnil)
481476
chdir_thread = rb_thread_current();
@@ -491,10 +486,11 @@ static VALUE
491486
dir_s_getwd(dir)
492487
VALUE dir;
493488
{
494-
char path[MAXPATHLEN];
489+
char *path = my_getcwd();
490+
VALUE cwd = rb_tainted_str_new2(path);
495491

496-
GETCWD(path);
497-
return rb_tainted_str_new2(path);
492+
free(path);
493+
return cwd;
498494
}
499495

500496
static VALUE

doc/NEWS

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,36 @@
1+
: String#chomp
2+
3+
if $/ == '\n', chops off last newlines (any of \n, \r, \r\n).
4+
5+
: IO#puts
6+
7+
do not treat Array specially.
8+
9+
: Module::new/Class::new
10+
11+
takes block.
12+
13+
: allocation framework
14+
15+
any instance of class can be allocated by class.allocate,
16+
(except a few classes).
17+
18+
: String#[]
19+
20+
starting offset can be specified as optional second parameter.
21+
22+
: String/Array methods
23+
24+
returns an instance of receivers class.
25+
26+
: String::new
27+
28+
returns "".
29+
30+
: Dir#path
31+
32+
Added.
33+
134
: Enum#sort_by
235

336
Added.

eval.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3645,8 +3645,8 @@ rb_yield_0(val, self, klass, pcall)
36453645
int state;
36463646
static unsigned serial = 1;
36473647

3648-
if (!(rb_block_given_p() || rb_f_block_given_p())) {
3649-
rb_raise(rb_eLocalJumpError, "yield called out of block");
3648+
if (!rb_block_given_p()) {
3649+
rb_raise(rb_eLocalJumpError, "no block given");
36503650
}
36513651

36523652
PUSH_VARS();

file.c

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "ruby.h"
2020
#include "rubyio.h"
2121
#include "rubysig.h"
22+
#include "util.h"
2223
#include "dln.h"
2324

2425
#ifdef HAVE_UNISTD_H
@@ -1225,14 +1226,22 @@ rb_file_s_readlink(klass, path)
12251226
VALUE klass, path;
12261227
{
12271228
#ifdef HAVE_READLINK
1228-
char buf[MAXPATHLEN];
1229-
int cc;
1229+
char *buf;
1230+
int size = 100;
1231+
int rv;
1232+
VALUE v;
12301233

12311234
SafeStringValue(path);
1232-
if ((cc = readlink(RSTRING(path)->ptr, buf, MAXPATHLEN)) < 0)
1233-
rb_sys_fail(RSTRING(path)->ptr);
1235+
buf = xmalloc(size);
1236+
if ((rv = readlink(RSTRING(path)->ptr, buf, size)) == size) {
1237+
size *= 2;
1238+
buf = xrealloc(buf, size);
1239+
}
1240+
if (rv < 0) rb_sys_fail(RSTRING(path)->ptr);
1241+
v = rb_tainted_str_new(buf, rv);
1242+
free(buf);
12341243

1235-
return rb_tainted_str_new(buf, cc);
1244+
return v;
12361245
#else
12371246
rb_notimplement();
12381247
return Qnil; /* not reached */
@@ -1297,10 +1306,6 @@ rb_file_s_umask(argc, argv)
12971306
return INT2FIX(omask);
12981307
}
12991308

1300-
#ifndef HAVE_GETCWD
1301-
#define getcwd(buf, len) ((void)(len), getwd(buf))
1302-
#endif
1303-
13041309
#if defined DOSISH
13051310
#define isdirsep(x) ((x) == '/' || (x) == '\\')
13061311
#else
@@ -2228,29 +2233,31 @@ is_absolute_path(path)
22282233

22292234
static int
22302235
path_check_1(path)
2231-
char *path;
2236+
VALUE path;
22322237
{
22332238
struct stat st;
2234-
char *p = 0;
2235-
char *s;
2239+
char *p0 = RSTRING(path)->ptr;
2240+
char *p, *s;
2241+
2242+
if (!is_absolute_path(p0)) {
2243+
char *buf = my_getcwd();
2244+
VALUE newpath;
22362245

2237-
if (!is_absolute_path(path)) {
2238-
char buf[MAXPATHLEN+1];
2246+
newpath = rb_str_new2(buf);
2247+
free(buf);
22392248

2240-
if (getcwd(buf, MAXPATHLEN) == 0) return 0;
2241-
strncat(buf, "/", MAXPATHLEN);
2242-
strncat(buf, path, MAXPATHLEN);
2243-
buf[MAXPATHLEN] = '\0';
2244-
return path_check_1(buf);
2249+
rb_str_cat2(newpath, "/");
2250+
rb_str_cat2(newpath, p0);
2251+
return path_check_1(newpath);
22452252
}
22462253
for (;;) {
2247-
if (stat(path, &st) == 0 && (st.st_mode & 002)) {
2254+
if (stat(p0, &st) == 0 && (st.st_mode & 002)) {
22482255
if (p) *p = '/';
22492256
return 0;
22502257
}
2251-
s = strrdirsep(path);
2258+
s = strrdirsep(p0);
22522259
if (p) *p = '/';
2253-
if (!s || s == path) return 1;
2260+
if (!s || s == p0) return 1;
22542261
p = s;
22552262
*p = '\0';
22562263
}
@@ -2260,27 +2267,24 @@ int
22602267
rb_path_check(path)
22612268
char *path;
22622269
{
2263-
char *p, *pend;
2270+
char *p0, *p, *pend;
22642271
const char sep = PATH_SEP_CHAR;
22652272

22662273
if (!path) return 1;
22672274

2268-
p = path;
2269-
pend = strchr(path, sep);
2275+
pend = path + strlen(path);
2276+
p0 = path;
2277+
p = strchr(path, sep);
2278+
if (!p) p = pend;
22702279

22712280
for (;;) {
2272-
int safe;
2273-
2274-
if (pend) *pend = '\0';
2275-
safe = path_check_1(p);
2276-
if (!safe) {
2277-
if (pend) *pend = sep;
2278-
return 0;
2279-
}
2280-
if (!pend) break;
2281-
*pend = sep;
2282-
p = pend + 1;
2283-
pend = strchr(p, sep);
2281+
if (!path_check_1(rb_str_new(p0, p - p0))) {
2282+
return 0; /* not safe */
2283+
}
2284+
if (p0 > pend) break;
2285+
p0 = p + 1;
2286+
p = strchr(p0, sep);
2287+
if (!p) p = pend;
22842288
}
22852289
return 1;
22862290
}

lib/resolv.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
7777
--- Resolv::DNS#getresource(name, typeclass)
7878
--- Resolv::DNS#getresources(name, typeclass)
79-
--- Resolv::DNS#each_resources(name, typeclass) {|resource| ...}
79+
--- Resolv::DNS#each_resource(name, typeclass) {|resource| ...}
8080
They lookup DNS resources of ((|name|)).
8181
((|name|)) must be a instance of Resolv::Name or String.
8282
@@ -370,7 +370,7 @@ def getaddresses(name)
370370
end
371371

372372
def each_address(name)
373-
each_resources(name, Resource::IN::A) {|resource| yield resource.address}
373+
each_resource(name, Resource::IN::A) {|resource| yield resource.address}
374374
end
375375

376376
def getname(address)
@@ -395,21 +395,21 @@ def each_name(address)
395395
else
396396
raise ResolvError.new("cannot interpret as address: #{address}")
397397
end
398-
each_resources(ptr, Resource::IN::PTR) {|resource| yield resource.name}
398+
each_resource(ptr, Resource::IN::PTR) {|resource| yield resource.name}
399399
end
400400

401401
def getresource(name, typeclass)
402-
each_resources(name, typeclass) {|resource| return resource}
402+
each_resource(name, typeclass) {|resource| return resource}
403403
raise ResolvError.new("DNS result has no information for #{name}")
404404
end
405405

406406
def getresources(name, typeclass)
407407
ret = []
408-
each_resources(name, typeclass) {|resource| ret << resource}
408+
each_resource(name, typeclass) {|resource| ret << resource}
409409
return ret
410410
end
411411

412-
def each_resources(name, typeclass, &proc)
412+
def each_resource(name, typeclass, &proc)
413413
lazy_initialize
414414
q = Queue.new
415415
senders = {}
@@ -1594,7 +1594,7 @@ def self.create(arg)
15941594

15951595
def initialize(address)
15961596
unless address.kind_of?(String) && address.length == 16
1597-
raise ArgumentError.new('IPv4 address muse be 16 bytes')
1597+
raise ArgumentError.new('IPv6 address muse be 16 bytes')
15981598
end
15991599
@address = address
16001600
end

lib/weakref.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,11 @@ def __getobj__
6060
unless ID_MAP[@__id]
6161
raise RefError, "Illegal Reference - probably recycled", caller(2)
6262
end
63-
ObjectSpace._id2ref(@__id)
63+
begin
64+
ObjectSpace._id2ref(@__id)
65+
rescue RangeError
66+
raise RefError, "Illegal Reference - probably recycled", caller(2)
67+
end
6468
end
6569

6670
def weakref_alive?

0 commit comments

Comments
 (0)