* 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
Родитель eb050525c0
Коммит 67dcad92b7
11 изменённых файлов: 113 добавлений и 47 удалений

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

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

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

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

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

8
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];

2
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);
}

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

20
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)

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

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

2
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));

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

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