summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in2
-rw-r--r--bignum.c13
-rw-r--r--configure.in4
-rw-r--r--dir.c22
-rw-r--r--doc/NEWS33
-rw-r--r--eval.c4
-rw-r--r--file.c78
-rw-r--r--lib/resolv.rb14
-rw-r--r--lib/weakref.rb6
-rw-r--r--parse.y66
-rw-r--r--process.c9
-rw-r--r--ruby.h17
-rw-r--r--sample/test.rb10
-rw-r--r--string.c10
-rw-r--r--util.c15
-rw-r--r--util.h3
-rw-r--r--version.h4
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
diff --git a/bignum.c b/bignum.c
index 372d578e37..d553c2b869 100644
--- a/bignum.c
+++ b/bignum.c
@@ -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'
diff --git a/dir.c b/dir.c
index 428f4aaaa6..a7673175e5 100644
--- a/dir.c
+++ b/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
diff --git a/doc/NEWS b/doc/NEWS
index 113e4545e1..0e84050c59 100644
--- a/doc/NEWS
+++ b/doc/NEWS
@@ -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.
diff --git a/eval.c b/eval.c
index 90f17e5be4..e9e11e89a7 100644
--- a/eval.c
+++ b/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();
diff --git a/file.c b/file.c
index 9f44028a2a..24d3de2ab8 100644
--- a/file.c
+++ b/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(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?
diff --git a/parse.y b/parse.y
index 917848605b..89c63ab34c 100644
--- a/parse.y
+++ b/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
{
diff --git a/process.c b/process.c
index 2525c9cd42..f598914f1a 100644
--- a/process.c
+++ b/process.c
@@ -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++;
diff --git a/ruby.h b/ruby.h
index 3f6742deea..65b4d3b2ef 100644
--- a/ruby.h
+++ b/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
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
diff --git a/string.c b/string.c
index 3981e54d01..183db6a7fe 100644
--- a/string.c
+++ b/string.c
@@ -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;
diff --git a/util.c b/util.c
index ddc919584c..9c22285a18 100644
--- a/util.c
+++ b/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;
+}
diff --git a/util.h b/util.h
index 09fa410f67..ba408359a9 100644
--- a/util.h
+++ b/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 */
diff --git a/version.h b/version.h
index 446b65ead3..2e038a2f51 100644
--- a/version.h
+++ b/version.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