summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--ext/stringio/stringio.c23
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 <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>
* 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;
}