From 343f505fb8a6162d2a3ecbef360813eec81f221c Mon Sep 17 00:00:00 2001 From: nobu Date: Wed, 28 Aug 2002 10:14:06 +0000 Subject: [PATCH] * 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 --- ChangeLog | 7 +++++++ ext/stringio/stringio.c | 23 +++++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 95a970dd6c..7dd1637c8f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Wed Aug 28 19:12:46 2002 Nobuyoshi Nakada + + * 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 * file.c: fix memory leak in rb_stat_init. diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c index 6a50fabaed..a6ba07307e 100644 --- a/ext/stringio/stringio.c +++ b/ext/stringio/stringio.c @@ -205,6 +205,7 @@ strio_initialize(argc, argv, self) { struct StringIO *ptr = check_strio(self); VALUE string, mode; + const char* m; if (!ptr) { DATA_PTR(self) = ptr = strio_alloc(); @@ -214,12 +215,13 @@ strio_initialize(argc, argv, self) case 2: StringValue(mode); 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)) { errno = EACCES; rb_sys_fail(0); } - switch (*RSTRING(mode)->ptr) { + switch (*m) { case 'a': ptr->flags |= STRIO_APPEND; break; @@ -543,14 +545,23 @@ strio_ungetc(self, ch) { struct StringIO *ptr = readable(StringIO(self)); int cc = NUM2INT(ch); + long len, pos = ptr->pos; - if (cc != EOF && ptr->pos > 0) { - if ((unsigned char)RSTRING(ptr->string)->ptr[--ptr->pos] != + if (cc != EOF && pos > 0) { + if ((len = RSTRING(ptr->string)->len) < pos || + (unsigned char)RSTRING(ptr->string)->ptr[pos - 1] != (unsigned char)cc) { check_modifiable(ptr); - rb_str_modify(ptr->string); - RSTRING(ptr->string)->ptr[ptr->pos] = cc; + if (len < pos) { + 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; }