* string.c (rb_str_upto): generate sequence according to "succ"

order.  formerly check was done by dictionary order.
  [ruby-talk:74138]

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

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


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3982 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2003-06-23 06:52:39 +00:00
parent eb050525c0
commit 67dcad92b7
11 changed files with 113 additions and 47 deletions

View File

@ -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 * time.c (time_arg): initialize v[6] even when argc is 10 to
avoid valgrind error. 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> Sat Jun 21 23:15:08 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (proc_invoke): should not propagate distination tag if * eval.c (proc_invoke): should not propagate distination tag if

1
dln.c
View File

@ -1662,6 +1662,7 @@ dln_find_1(fname, path, exe_flag)
const char* mac_fullpath; const char* mac_fullpath;
#endif #endif
if (!fname) return fname;
if (fname[0] == '/') return fname; if (fname[0] == '/') return fname;
if (strncmp("./", fname, 2) == 0 || strncmp("../", fname, 3) == 0) if (strncmp("./", fname, 2) == 0 || strncmp("../", fname, 3) == 0)
return fname; return fname;

View File

@ -582,7 +582,7 @@ syserr_initialize(argc, argv, self)
if (!NIL_P(mesg)) { if (!NIL_P(mesg)) {
StringValue(mesg); StringValue(mesg);
buf = ALLOCA_N(char, strlen(err)+RSTRING(mesg)->len+4); 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); mesg = rb_str_new2(buf);
} }
else { else {

8
eval.c
View File

@ -1094,7 +1094,7 @@ error_print()
long len = elen; long len = elen;
if (RSTRING(epath)->ptr[0] == '#') epath = 0; if (RSTRING(epath)->ptr[0] == '#') epath = 0;
if (tail = strchr(einfo, '\n')) { if (tail = memchr(einfo, '\n', elen)) {
len = tail - einfo; len = tail - einfo;
tail++; /* skip newline */ tail++; /* skip newline */
} }
@ -3357,11 +3357,11 @@ rb_eval(self, n)
switch (nd_type(node)) { switch (nd_type(node)) {
case NODE_DREGX: case NODE_DREGX:
result = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len, result = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
node->nd_cflag); node->nd_cflag);
break; break;
case NODE_DREGX_ONCE: /* regexp expand once */ case NODE_DREGX_ONCE: /* regexp expand once */
result = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len, result = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
node->nd_cflag); node->nd_cflag);
nd_set_type(node, NODE_LIT); nd_set_type(node, NODE_LIT);
node->nd_lit = result; node->nd_lit = result;
break; break;
@ -4673,7 +4673,7 @@ rb_f_missing(argc, argv, obj)
*ruby_frame = *_frame.prev->prev; *ruby_frame = *_frame.prev->prev;
{ {
char buf[BUFSIZ]; char buf[BUFSIZ];
int noclass = (!d || desc[0]=='#'); int noclass = (!desc || desc[0]=='#');
int n = 0; int n = 0;
VALUE args[3]; VALUE args[3];

2
file.c
View File

@ -1275,7 +1275,7 @@ rb_file_s_readlink(klass, path)
SafeStringValue(path); SafeStringValue(path);
buf = xmalloc(size); buf = xmalloc(size);
if ((rv = readlink(RSTRING(path)->ptr, buf, size)) == size) { while ((rv = readlink(RSTRING(path)->ptr, buf, size)) == size) {
size *= 2; size *= 2;
buf = xrealloc(buf, size); buf = xrealloc(buf, size);
} }

14
hash.c
View File

@ -997,6 +997,7 @@ static VALUE
env_str_new2(ptr) env_str_new2(ptr)
const char *ptr; const char *ptr;
{ {
if (!ptr) return Qnil;
return env_str_new(ptr, strlen(ptr)); return env_str_new(ptr, strlen(ptr));
} }
@ -1606,7 +1607,7 @@ env_index(dmy, value)
char **env; char **env;
VALUE str; VALUE str;
if (TYPE(value) != T_STRING) return Qnil; StringValue(value);
env = GET_ENVIRON(environ); env = GET_ENVIRON(environ);
while (*env) { while (*env) {
char *s = strchr(*env, '=')+1; char *s = strchr(*env, '=')+1;
@ -1638,15 +1639,12 @@ env_indexes(argc, argv)
rb_warn("ENV.%s is deprecated; use ENV.values_at", rb_warn("ENV.%s is deprecated; use ENV.values_at",
rb_id2name(rb_frame_last_func())); rb_id2name(rb_frame_last_func()));
for (i=0;i<argc;i++) { for (i=0;i<argc;i++) {
char *v = 0; VALUE tmp = rb_check_string_type(argv[i]);
if (TYPE(argv[i]) == T_STRING) { if (NIL_P(tmp)) {
v = getenv(RSTRING(argv[i])->ptr); RARRAY(indexes)->ptr[i] = Qnil;
}
if (v) {
RARRAY(indexes)->ptr[i] = env_str_new2(v);
} }
else { else {
RARRAY(indexes)->ptr[i] = Qnil; RARRAY(indexes)->ptr[i] = env_str_new2(getenv(RSTRING(tmp)->ptr));
} }
RARRAY(indexes)->len = i+1; RARRAY(indexes)->len = i+1;
} }

20
io.c
View File

@ -2231,7 +2231,13 @@ rb_open_file(argc, argv, io)
path = RSTRING(fname)->ptr; path = RSTRING(fname)->ptr;
if (FIXNUM_P(vmode) || !NIL_P(perm)) { 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); fmode = NIL_P(perm) ? 0666 : NUM2INT(perm);
rb_file_sysopen_internal(io, path, flags, fmode); 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; if (NIL_P(vmode)) flags = O_RDONLY;
else if (FIXNUM_P(vmode)) flags = NUM2INT(vmode); else if (FIXNUM_P(vmode)) flags = NUM2INT(vmode);
else { else {
flags = rb_io_mode_modenum(StringValuePtr(vmode)); SafeStringValue(vmode);
flags = rb_io_mode_modenum(RSTRING(vmode)->ptr);
} }
if (NIL_P(perm)) fmode = 0666; if (NIL_P(perm)) fmode = 0666;
else fmode = NUM2INT(perm); else fmode = NUM2INT(perm);
@ -2833,8 +2840,13 @@ rb_io_initialize(argc, argv, io)
rb_scan_args(argc, argv, "11", &fnum, &mode); rb_scan_args(argc, argv, "11", &fnum, &mode);
fd = NUM2INT(fnum); fd = NUM2INT(fnum);
if (argc == 2) { if (argc == 2) {
SafeStringValue(mode); if (FIXNUM_P(mode)) {
flags = rb_io_mode_modenum(RSTRING(mode)->ptr); flags = FIX2LONG(mode);
}
else {
SafeStringValue(mode);
flags = rb_io_mode_modenum(RSTRING(mode)->ptr);
}
} }
else { else {
#if defined(HAVE_FCNTL) && defined(F_GETFL) #if defined(HAVE_FCNTL) && defined(F_GETFL)

22
pack.c
View File

@ -889,8 +889,7 @@ pack_pack(ary, fmt)
t = 0; t = 0;
} }
else { else {
StringValue(from); t = StringValuePtr(from);
t = RSTRING(from)->ptr;
} }
if (!associates) { if (!associates) {
associates = rb_ary_new(); associates = rb_ary_new();
@ -1610,7 +1609,7 @@ pack_unpack(str, fmt)
{ {
VALUE buf = infected_str_new(0, (send - s)*3/4, str); VALUE buf = infected_str_new(0, (send - s)*3/4, str);
char *ptr = RSTRING(buf)->ptr; 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 first = 1;
static int b64_xtable[256]; static int b64_xtable[256];
@ -1625,7 +1624,7 @@ pack_unpack(str, fmt)
b64_xtable[(int)b64_table[i]] = i; b64_xtable[(int)b64_table[i]] = i;
} }
} }
for (;;) { while (s < send) {
while (s[0] == '\r' || s[0] == '\n') { s++; } while (s[0] == '\r' || s[0] == '\n') { s++; }
if ((a = b64_xtable[(int)s[0]]) == -1) break; if ((a = b64_xtable[(int)s[0]]) == -1) break;
if ((b = b64_xtable[(int)s[1]]) == -1) break; if ((b = b64_xtable[(int)s[1]]) == -1) break;
@ -1636,12 +1635,13 @@ pack_unpack(str, fmt)
*ptr++ = c << 6 | d; *ptr++ = c << 6 | d;
s += 4; s += 4;
} }
if (a != -1 && b != -1 && s[2] == '=') { if (a != -1 && b != -1) {
*ptr++ = a << 2 | b >> 4; if (s + 2 < send && s[2] == '=')
} *ptr++ = a << 2 | b >> 4;
if (a != -1 && b != -1 && c != -1 && s[3] == '=') { if (c != -1 && s + 3 < send && s[3] == '=') {
*ptr++ = a << 2 | b >> 4; *ptr++ = a << 2 | b >> 4;
*ptr++ = b << 4 | c >> 2; *ptr++ = b << 4 | c >> 2;
}
} }
*ptr = '\0'; *ptr = '\0';
RSTRING(buf)->len = ptr - RSTRING(buf)->ptr; RSTRING(buf)->len = ptr - RSTRING(buf)->ptr;
@ -1677,6 +1677,8 @@ pack_unpack(str, fmt)
break; break;
case '@': case '@':
if (len > RSTRING(str)->len)
rb_raise(rb_eArgError, "@ outside of string");
s = RSTRING(str)->ptr + len; s = RSTRING(str)->ptr + len;
break; break;

9
ruby.c
View File

@ -704,8 +704,8 @@ proc_options(argc, argv)
} }
if (rb_safe_level() >= 4) { if (rb_safe_level() >= 4) {
OBJ_TAINT(rb_argv); OBJ_TAINT(rb_argv);
OBJ_TAINT(rb_load_path); OBJ_TAINT(rb_load_path);
} }
if (!e_script) { if (!e_script) {
@ -758,8 +758,8 @@ proc_options(argc, argv)
xflag = 0; xflag = 0;
if (rb_safe_level() >= 4) { if (rb_safe_level() >= 4) {
FL_UNSET(rb_argv, FL_TAINT); FL_UNSET(rb_argv, FL_TAINT);
FL_UNSET(rb_load_path, FL_TAINT); FL_UNSET(rb_load_path, FL_TAINT);
} }
} }
@ -774,6 +774,7 @@ load_file(fname, script)
VALUE f; VALUE f;
int line_start = 1; int line_start = 1;
if (!fname) rb_load_fail(fname);
if (strcmp(fname, "-") == 0) { if (strcmp(fname, "-") == 0) {
f = rb_stdin; f = rb_stdin;
} }

2
ruby.h
View File

@ -214,7 +214,7 @@ VALUE rb_str_to_str _((VALUE));
VALUE rb_string_value _((volatile VALUE*)); VALUE rb_string_value _((volatile VALUE*));
char *rb_string_value_ptr _((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)) #define StringValuePtr(v) rb_string_value_ptr(&(v))
void rb_check_safe_obj _((VALUE)); void rb_check_safe_obj _((VALUE));

View File

@ -158,7 +158,7 @@ rb_str_new4(orig)
VALUE klass, str; VALUE klass, str;
klass = rb_obj_class(orig); klass = rb_obj_class(orig);
if (FL_TEST(orig, ELTS_SHARED)) { if (FL_TEST(orig, ELTS_SHARED) && RSTRING(orig)->aux.shared) {
long ofs; long ofs;
str = RSTRING(orig)->aux.shared; str = RSTRING(orig)->aux.shared;
ofs = RSTRING(str)->len - RSTRING(orig)->len; ofs = RSTRING(str)->len - RSTRING(orig)->len;
@ -445,11 +445,18 @@ rb_str_associated(str)
return Qfalse; return Qfalse;
} }
static char *null_str = "";
VALUE VALUE
rb_string_value(ptr) rb_string_value(ptr)
volatile 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 * char *
@ -462,7 +469,8 @@ rb_string_value_ptr(ptr)
*ptr = s; *ptr = s;
} }
if (!RSTRING(s)->ptr) { if (!RSTRING(s)->ptr) {
str_make_independent(s); FL_SET(s, ELTS_SHARED);
RSTRING(s)->ptr = null_str;
} }
return RSTRING(s)->ptr; return RSTRING(s)->ptr;
} }
@ -471,7 +479,12 @@ VALUE
rb_check_string_type(str) rb_check_string_type(str)
VALUE 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 VALUE
@ -498,7 +511,7 @@ rb_str_substr(str, beg, len)
if (len > sizeof(struct RString)/2 && if (len > sizeof(struct RString)/2 &&
beg + len == RSTRING(str)->len && beg + len == RSTRING(str)->len &&
!FL_TEST(str, STR_ASSOC)) { !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; str = RSTRING(str)->aux.shared;
else else
str = str_new4(rb_obj_class(str), str); str = str_new4(rb_obj_class(str), str);
@ -525,7 +538,7 @@ VALUE
rb_str_dup_frozen(str) rb_str_dup_frozen(str)
VALUE 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; VALUE shared = RSTRING(str)->aux.shared;
if (RSTRING(shared)->len == RSTRING(str)->len) { if (RSTRING(shared)->len == RSTRING(str)->len) {
OBJ_FREEZE(shared); OBJ_FREEZE(shared);
@ -1142,12 +1155,14 @@ rb_str_upto(beg, end, excl)
VALUE beg, end; VALUE beg, end;
int excl; int excl;
{ {
VALUE current; VALUE current, after_end;
ID succ = rb_intern("succ"); ID succ = rb_intern("succ");
StringValue(end); StringValue(end);
if (rb_str_cmp(beg, end) > 0) return beg;
after_end = rb_funcall(end, succ, 0, 0);
current = beg; current = beg;
while (rb_str_cmp(current, end) <= 0) { while (!rb_str_equal(current, after_end)) {
rb_yield(current); rb_yield(current);
if (!excl && rb_str_equal(current, end)) break; if (!excl && rb_str_equal(current, end)) break;
current = rb_funcall(current, succ, 0, 0); current = rb_funcall(current, succ, 0, 0);
@ -1163,7 +1178,7 @@ static VALUE
rb_str_upto_m(beg, end) rb_str_upto_m(beg, end)
VALUE beg, end; VALUE beg, end;
{ {
return rb_str_upto(beg, end, 0); return rb_str_upto(beg, end, Qfalse);
} }
static VALUE static VALUE
@ -1615,11 +1630,10 @@ str_gsub(argc, argv, str, bang)
* Always consume at least one character of the input string * Always consume at least one character of the input string
* in order to prevent infinite loops. * in order to prevent infinite loops.
*/ */
if (RSTRING(str)->len <= END(0)) break;
len = mbclen2(RSTRING(str)->ptr[END(0)], pat); len = mbclen2(RSTRING(str)->ptr[END(0)], pat);
if (RSTRING(str)->len > END(0)) { memcpy(bp, RSTRING(str)->ptr+END(0), len);
memcpy(bp, RSTRING(str)->ptr+END(0), len); bp += len;
bp += len;
}
offset = END(0) + len; offset = END(0) + len;
} }
else { else {
@ -1770,6 +1784,7 @@ rb_str_reverse_bang(str)
char *s, *e; char *s, *e;
char c; char c;
if (RSTRING(str)->len <= 1) return Qnil;
rb_str_modify(str); rb_str_modify(str);
s = RSTRING(str)->ptr; s = RSTRING(str)->ptr;
e = s + RSTRING(str)->len - 1; 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 * 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 { else {
*start = END(0); *start = END(0);