* ext/stringio/stringio.c (strio_initialize): RSTRING(mode)->ptr

can be NULL.

* ext/stringio/stringio.c (strio_ungetc): fix buffer overflow.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2758 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2002-08-28 10:14:06 +00:00
Родитель 4c59a65d04
Коммит 343f505fb8
2 изменённых файлов: 24 добавлений и 6 удалений

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

@ -1,3 +1,10 @@
Wed Aug 28 19:12:46 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* ext/stringio/stringio.c (strio_initialize): RSTRING(mode)->ptr
can be NULL.
* ext/stringio/stringio.c (strio_ungetc): fix buffer overflow.
Wed Aug 28 18:19:55 2002 Michal Rokos <michal@ruby-lang.org> Wed Aug 28 18:19:55 2002 Michal Rokos <michal@ruby-lang.org>
* file.c: fix memory leak in rb_stat_init. * file.c: fix memory leak in rb_stat_init.

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

@ -205,6 +205,7 @@ strio_initialize(argc, argv, self)
{ {
struct StringIO *ptr = check_strio(self); struct StringIO *ptr = check_strio(self);
VALUE string, mode; VALUE string, mode;
const char* m;
if (!ptr) { if (!ptr) {
DATA_PTR(self) = ptr = strio_alloc(); DATA_PTR(self) = ptr = strio_alloc();
@ -214,12 +215,13 @@ strio_initialize(argc, argv, self)
case 2: case 2:
StringValue(mode); StringValue(mode);
StringValue(string); StringValue(string);
ptr->flags = rb_io_mode_flags(RSTRING(mode)->ptr); if (!(m = RSTRING(mode)->ptr)) m = "";
ptr->flags = rb_io_mode_flags(m);
if (ptr->flags & FMODE_WRITABLE && OBJ_FROZEN(string)) { if (ptr->flags & FMODE_WRITABLE && OBJ_FROZEN(string)) {
errno = EACCES; errno = EACCES;
rb_sys_fail(0); rb_sys_fail(0);
} }
switch (*RSTRING(mode)->ptr) { switch (*m) {
case 'a': case 'a':
ptr->flags |= STRIO_APPEND; ptr->flags |= STRIO_APPEND;
break; break;
@ -543,14 +545,23 @@ strio_ungetc(self, ch)
{ {
struct StringIO *ptr = readable(StringIO(self)); struct StringIO *ptr = readable(StringIO(self));
int cc = NUM2INT(ch); int cc = NUM2INT(ch);
long len, pos = ptr->pos;
if (cc != EOF && ptr->pos > 0) { if (cc != EOF && pos > 0) {
if ((unsigned char)RSTRING(ptr->string)->ptr[--ptr->pos] != if ((len = RSTRING(ptr->string)->len) < pos ||
(unsigned char)RSTRING(ptr->string)->ptr[pos - 1] !=
(unsigned char)cc) { (unsigned char)cc) {
check_modifiable(ptr); check_modifiable(ptr);
rb_str_modify(ptr->string); if (len < pos) {
RSTRING(ptr->string)->ptr[ptr->pos] = cc; rb_str_resize(ptr->string, pos);
MEMZERO(RSTRING(ptr->string)->ptr + len, char, pos - len - 1);
}
else {
rb_str_modify(ptr->string);
}
RSTRING(ptr->string)->ptr[pos - 1] = cc;
} }
--ptr->pos;
} }
return Qnil; return Qnil;
} }