summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog34
-rw-r--r--dln.c1
-rw-r--r--error.c2
-rw-r--r--eval.c8
-rw-r--r--file.c2
-rw-r--r--hash.c14
-rw-r--r--io.c20
-rw-r--r--pack.c22
-rw-r--r--ruby.c9
-rw-r--r--ruby.h2
-rw-r--r--string.c46
11 files changed, 113 insertions, 47 deletions
diff --git a/ChangeLog b/ChangeLog
index a5e6bc2aa4..b931484b2c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,40 @@ Mon Jun 23 13:45:30 2003 Tanaka Akira <akr@m17n.org>
* time.c (time_arg): initialize v[6] even when argc is 10 to
avoid valgrind error.
+Mon Jun 23 08:24:01 2003 Florian Frank <flori@nixe.ping.de>
+
+ * string.c (rb_str_upto): generate sequence according to "succ"
+ order. formerly check was done by dictionary order.
+ [ruby-talk:74138]
+
+Mon Jun 23 00:27:32 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * string.c (rb_string_value): fill constant empty string along
+ with setting ELTS_SHARED if str->ptr is NULL. [ruby-core:01179]
+
+ * string.c (rb_string_value_ptr): ditto.
+
+ * string.c (rb_check_string_type): ditto.
+
+Sun Jun 22 23:42:20 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
+
+ * string.c (str_gsub): move END(0) check before mbclen2().
+
+ * string.c (scan_once): reduce END(0) check.
+
+ * io.c (rb_io_initialize): accept fixnum mode.
+
+ * eval.c (error_print): replace strchr() by memchr(), einfo may
+ contain "\0".
+
+ * pack.c (pack_unpack): range check for "@" move; initialize check
+ for "m".
+
+ * error.c (syserr_initialize): avoid buffer overflow.
+
+ * file.c (rb_file_s_readlink): expand buffer until readlink
+ succeed.
+
Sat Jun 21 23:15:08 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (proc_invoke): should not propagate distination tag if
diff --git a/dln.c b/dln.c
index f6950e1863..267b9f64e8 100644
--- a/dln.c
+++ b/dln.c
@@ -1662,6 +1662,7 @@ dln_find_1(fname, path, exe_flag)
const char* mac_fullpath;
#endif
+ if (!fname) return fname;
if (fname[0] == '/') return fname;
if (strncmp("./", fname, 2) == 0 || strncmp("../", fname, 3) == 0)
return fname;
diff --git a/error.c b/error.c
index d9c673c807..f62150f3e5 100644
--- a/error.c
+++ b/error.c
@@ -582,7 +582,7 @@ syserr_initialize(argc, argv, self)
if (!NIL_P(mesg)) {
StringValue(mesg);
buf = ALLOCA_N(char, strlen(err)+RSTRING(mesg)->len+4);
- sprintf(buf, "%s - %s", err, RSTRING(mesg)->ptr);
+ sprintf(buf, "%s - %.*s", err, RSTRING(mesg)->len, RSTRING(mesg)->ptr);
mesg = rb_str_new2(buf);
}
else {
diff --git a/eval.c b/eval.c
index 6f95f0fc9a..4186b2e9e3 100644
--- a/eval.c
+++ b/eval.c
@@ -1094,7 +1094,7 @@ error_print()
long len = elen;
if (RSTRING(epath)->ptr[0] == '#') epath = 0;
- if (tail = strchr(einfo, '\n')) {
+ if (tail = memchr(einfo, '\n', elen)) {
len = tail - einfo;
tail++; /* skip newline */
}
@@ -3357,11 +3357,11 @@ rb_eval(self, n)
switch (nd_type(node)) {
case NODE_DREGX:
result = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
- node->nd_cflag);
+ node->nd_cflag);
break;
case NODE_DREGX_ONCE: /* regexp expand once */
result = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
- node->nd_cflag);
+ node->nd_cflag);
nd_set_type(node, NODE_LIT);
node->nd_lit = result;
break;
@@ -4673,7 +4673,7 @@ rb_f_missing(argc, argv, obj)
*ruby_frame = *_frame.prev->prev;
{
char buf[BUFSIZ];
- int noclass = (!d || desc[0]=='#');
+ int noclass = (!desc || desc[0]=='#');
int n = 0;
VALUE args[3];
diff --git a/file.c b/file.c
index 156b329f86..ad14138731 100644
--- a/file.c
+++ b/file.c
@@ -1275,7 +1275,7 @@ rb_file_s_readlink(klass, path)
SafeStringValue(path);
buf = xmalloc(size);
- if ((rv = readlink(RSTRING(path)->ptr, buf, size)) == size) {
+ while ((rv = readlink(RSTRING(path)->ptr, buf, size)) == size) {
size *= 2;
buf = xrealloc(buf, size);
}
diff --git a/hash.c b/hash.c
index cf7a14bb34..8f636e1590 100644
--- a/hash.c
+++ b/hash.c
@@ -997,6 +997,7 @@ static VALUE
env_str_new2(ptr)
const char *ptr;
{
+ if (!ptr) return Qnil;
return env_str_new(ptr, strlen(ptr));
}
@@ -1606,7 +1607,7 @@ env_index(dmy, value)
char **env;
VALUE str;
- if (TYPE(value) != T_STRING) return Qnil;
+ StringValue(value);
env = GET_ENVIRON(environ);
while (*env) {
char *s = strchr(*env, '=')+1;
@@ -1638,15 +1639,12 @@ env_indexes(argc, argv)
rb_warn("ENV.%s is deprecated; use ENV.values_at",
rb_id2name(rb_frame_last_func()));
for (i=0;i<argc;i++) {
- char *v = 0;
- if (TYPE(argv[i]) == T_STRING) {
- v = getenv(RSTRING(argv[i])->ptr);
- }
- if (v) {
- RARRAY(indexes)->ptr[i] = env_str_new2(v);
+ VALUE tmp = rb_check_string_type(argv[i]);
+ if (NIL_P(tmp)) {
+ RARRAY(indexes)->ptr[i] = Qnil;
}
else {
- RARRAY(indexes)->ptr[i] = Qnil;
+ RARRAY(indexes)->ptr[i] = env_str_new2(getenv(RSTRING(tmp)->ptr));
}
RARRAY(indexes)->len = i+1;
}
diff --git a/io.c b/io.c
index 8fac72a0ce..662930a353 100644
--- a/io.c
+++ b/io.c
@@ -2231,7 +2231,13 @@ rb_open_file(argc, argv, io)
path = RSTRING(fname)->ptr;
if (FIXNUM_P(vmode) || !NIL_P(perm)) {
- flags = FIXNUM_P(vmode) ? NUM2INT(vmode) : rb_io_mode_modenum(StringValuePtr(vmode));
+ if (FIXNUM_P(vmode)) {
+ flags = NUM2INT(vmode);
+ }
+ else {
+ SafeStringValue(vmode);
+ rb_io_mode_modenum(RSTRING(vmode)->ptr);
+ }
fmode = NIL_P(perm) ? 0666 : NUM2INT(perm);
rb_file_sysopen_internal(io, path, flags, fmode);
@@ -2272,7 +2278,8 @@ rb_io_s_sysopen(argc, argv)
if (NIL_P(vmode)) flags = O_RDONLY;
else if (FIXNUM_P(vmode)) flags = NUM2INT(vmode);
else {
- flags = rb_io_mode_modenum(StringValuePtr(vmode));
+ SafeStringValue(vmode);
+ flags = rb_io_mode_modenum(RSTRING(vmode)->ptr);
}
if (NIL_P(perm)) fmode = 0666;
else fmode = NUM2INT(perm);
@@ -2833,8 +2840,13 @@ rb_io_initialize(argc, argv, io)
rb_scan_args(argc, argv, "11", &fnum, &mode);
fd = NUM2INT(fnum);
if (argc == 2) {
- SafeStringValue(mode);
- flags = rb_io_mode_modenum(RSTRING(mode)->ptr);
+ if (FIXNUM_P(mode)) {
+ flags = FIX2LONG(mode);
+ }
+ else {
+ SafeStringValue(mode);
+ flags = rb_io_mode_modenum(RSTRING(mode)->ptr);
+ }
}
else {
#if defined(HAVE_FCNTL) && defined(F_GETFL)
diff --git a/pack.c b/pack.c
index b0b51c1b2a..86726518ce 100644
--- a/pack.c
+++ b/pack.c
@@ -889,8 +889,7 @@ pack_pack(ary, fmt)
t = 0;
}
else {
- StringValue(from);
- t = RSTRING(from)->ptr;
+ t = StringValuePtr(from);
}
if (!associates) {
associates = rb_ary_new();
@@ -1610,7 +1609,7 @@ pack_unpack(str, fmt)
{
VALUE buf = infected_str_new(0, (send - s)*3/4, str);
char *ptr = RSTRING(buf)->ptr;
- int a,b,c = 0,d;
+ int a = -1,b = -1,c = 0,d;
static int first = 1;
static int b64_xtable[256];
@@ -1625,7 +1624,7 @@ pack_unpack(str, fmt)
b64_xtable[(int)b64_table[i]] = i;
}
}
- for (;;) {
+ while (s < send) {
while (s[0] == '\r' || s[0] == '\n') { s++; }
if ((a = b64_xtable[(int)s[0]]) == -1) break;
if ((b = b64_xtable[(int)s[1]]) == -1) break;
@@ -1636,12 +1635,13 @@ pack_unpack(str, fmt)
*ptr++ = c << 6 | d;
s += 4;
}
- if (a != -1 && b != -1 && s[2] == '=') {
- *ptr++ = a << 2 | b >> 4;
- }
- if (a != -1 && b != -1 && c != -1 && s[3] == '=') {
- *ptr++ = a << 2 | b >> 4;
- *ptr++ = b << 4 | c >> 2;
+ if (a != -1 && b != -1) {
+ if (s + 2 < send && s[2] == '=')
+ *ptr++ = a << 2 | b >> 4;
+ if (c != -1 && s + 3 < send && s[3] == '=') {
+ *ptr++ = a << 2 | b >> 4;
+ *ptr++ = b << 4 | c >> 2;
+ }
}
*ptr = '\0';
RSTRING(buf)->len = ptr - RSTRING(buf)->ptr;
@@ -1677,6 +1677,8 @@ pack_unpack(str, fmt)
break;
case '@':
+ if (len > RSTRING(str)->len)
+ rb_raise(rb_eArgError, "@ outside of string");
s = RSTRING(str)->ptr + len;
break;
diff --git a/ruby.c b/ruby.c
index f48898e3f1..0437b5bb04 100644
--- a/ruby.c
+++ b/ruby.c
@@ -704,8 +704,8 @@ proc_options(argc, argv)
}
if (rb_safe_level() >= 4) {
- OBJ_TAINT(rb_argv);
- OBJ_TAINT(rb_load_path);
+ OBJ_TAINT(rb_argv);
+ OBJ_TAINT(rb_load_path);
}
if (!e_script) {
@@ -758,8 +758,8 @@ proc_options(argc, argv)
xflag = 0;
if (rb_safe_level() >= 4) {
- FL_UNSET(rb_argv, FL_TAINT);
- FL_UNSET(rb_load_path, FL_TAINT);
+ FL_UNSET(rb_argv, FL_TAINT);
+ FL_UNSET(rb_load_path, FL_TAINT);
}
}
@@ -774,6 +774,7 @@ load_file(fname, script)
VALUE f;
int line_start = 1;
+ if (!fname) rb_load_fail(fname);
if (strcmp(fname, "-") == 0) {
f = rb_stdin;
}
diff --git a/ruby.h b/ruby.h
index 76ea5d8b7c..ee6f572c5f 100644
--- a/ruby.h
+++ b/ruby.h
@@ -214,7 +214,7 @@ VALUE rb_str_to_str _((VALUE));
VALUE rb_string_value _((volatile VALUE*));
char *rb_string_value_ptr _((volatile VALUE*));
-#define StringValue(v) if (TYPE(v) != T_STRING) rb_string_value(&(v))
+#define StringValue(v) rb_string_value(&(v))
#define StringValuePtr(v) rb_string_value_ptr(&(v))
void rb_check_safe_obj _((VALUE));
diff --git a/string.c b/string.c
index 0bbd9f5513..eed7a0e887 100644
--- a/string.c
+++ b/string.c
@@ -158,7 +158,7 @@ rb_str_new4(orig)
VALUE klass, str;
klass = rb_obj_class(orig);
- if (FL_TEST(orig, ELTS_SHARED)) {
+ if (FL_TEST(orig, ELTS_SHARED) && RSTRING(orig)->aux.shared) {
long ofs;
str = RSTRING(orig)->aux.shared;
ofs = RSTRING(str)->len - RSTRING(orig)->len;
@@ -445,11 +445,18 @@ rb_str_associated(str)
return Qfalse;
}
+static char *null_str = "";
+
VALUE
rb_string_value(ptr)
volatile VALUE *ptr;
{
- return *ptr = rb_str_to_str(*ptr);
+ *ptr = rb_str_to_str(*ptr);
+ if (!RSTRING(*ptr)->ptr) {
+ FL_SET(*ptr, ELTS_SHARED);
+ RSTRING(*ptr)->ptr = null_str;
+ }
+ return *ptr;
}
char *
@@ -462,7 +469,8 @@ rb_string_value_ptr(ptr)
*ptr = s;
}
if (!RSTRING(s)->ptr) {
- str_make_independent(s);
+ FL_SET(s, ELTS_SHARED);
+ RSTRING(s)->ptr = null_str;
}
return RSTRING(s)->ptr;
}
@@ -471,7 +479,12 @@ VALUE
rb_check_string_type(str)
VALUE str;
{
- return rb_check_convert_type(str, T_STRING, "String", "to_str");
+ str = rb_check_convert_type(str, T_STRING, "String", "to_str");
+ if (!NIL_P(str) && !RSTRING(str)->ptr) {
+ FL_SET(str, ELTS_SHARED);
+ RSTRING(str)->ptr = null_str;
+ }
+ return str;
}
VALUE
@@ -498,7 +511,7 @@ rb_str_substr(str, beg, len)
if (len > sizeof(struct RString)/2 &&
beg + len == RSTRING(str)->len &&
!FL_TEST(str, STR_ASSOC)) {
- if (FL_TEST(str, ELTS_SHARED))
+ if (FL_TEST(str, ELTS_SHARED) && RSTRING(str)->aux.shared)
str = RSTRING(str)->aux.shared;
else
str = str_new4(rb_obj_class(str), str);
@@ -525,7 +538,7 @@ VALUE
rb_str_dup_frozen(str)
VALUE str;
{
- if (FL_TEST(str, ELTS_SHARED)) {
+ if (FL_TEST(str, ELTS_SHARED) && RSTRING(str)->aux.shared) {
VALUE shared = RSTRING(str)->aux.shared;
if (RSTRING(shared)->len == RSTRING(str)->len) {
OBJ_FREEZE(shared);
@@ -1142,12 +1155,14 @@ rb_str_upto(beg, end, excl)
VALUE beg, end;
int excl;
{
- VALUE current;
+ VALUE current, after_end;
ID succ = rb_intern("succ");
StringValue(end);
+ if (rb_str_cmp(beg, end) > 0) return beg;
+ after_end = rb_funcall(end, succ, 0, 0);
current = beg;
- while (rb_str_cmp(current, end) <= 0) {
+ while (!rb_str_equal(current, after_end)) {
rb_yield(current);
if (!excl && rb_str_equal(current, end)) break;
current = rb_funcall(current, succ, 0, 0);
@@ -1163,7 +1178,7 @@ static VALUE
rb_str_upto_m(beg, end)
VALUE beg, end;
{
- return rb_str_upto(beg, end, 0);
+ return rb_str_upto(beg, end, Qfalse);
}
static VALUE
@@ -1615,11 +1630,10 @@ str_gsub(argc, argv, str, bang)
* Always consume at least one character of the input string
* in order to prevent infinite loops.
*/
+ if (RSTRING(str)->len <= END(0)) break;
len = mbclen2(RSTRING(str)->ptr[END(0)], pat);
- if (RSTRING(str)->len > END(0)) {
- memcpy(bp, RSTRING(str)->ptr+END(0), len);
- bp += len;
- }
+ memcpy(bp, RSTRING(str)->ptr+END(0), len);
+ bp += len;
offset = END(0) + len;
}
else {
@@ -1770,6 +1784,7 @@ rb_str_reverse_bang(str)
char *s, *e;
char c;
+ if (RSTRING(str)->len <= 1) return Qnil;
rb_str_modify(str);
s = RSTRING(str)->ptr;
e = s + RSTRING(str)->len - 1;
@@ -2976,7 +2991,10 @@ scan_once(str, pat, start)
/*
* Always consume at least one character of the input string
*/
- *start = END(0)+mbclen2(RSTRING(str)->ptr[END(0)],pat);
+ if (RSTRING(str)->len < END(0))
+ *start = END(0)+mbclen2(RSTRING(str)->ptr[END(0)],pat);
+ else
+ *start = END(0)+1;
}
else {
*start = END(0);