mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/stringio/stringio.c: fixed frozen string bug. ungetc no
longer raises on readonly stream unless modifies actually. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2198 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
bce7601f73
commit
4f0870f74b
2 changed files with 51 additions and 14 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
Thu Mar 14 12:32:59 2002 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
||||||
|
|
||||||
|
* ext/stringio/stringio.c: fixed frozen string bug. ungetc no
|
||||||
|
longer raises on readonly stream unless modifies actually.
|
||||||
|
|
||||||
Thu Mar 14 08:57:41 2002 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
Thu Mar 14 08:57:41 2002 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
||||||
|
|
||||||
* dir.c (rb_push_glob): avoid SEGV when a block given.
|
* dir.c (rb_push_glob): avoid SEGV when a block given.
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
$Author$
|
$Author$
|
||||||
$Date$
|
$Date$
|
||||||
|
$RoughId: stringio.c,v 1.13 2002/03/14 03:24:18 nobu Exp $
|
||||||
created at: Tue Feb 19 04:10:38 JST 2002
|
created at: Tue Feb 19 04:10:38 JST 2002
|
||||||
|
|
||||||
All the files in this distribution are covered under the Ruby's
|
All the files in this distribution are covered under the Ruby's
|
||||||
|
@ -89,11 +90,15 @@ get_strio(self)
|
||||||
|
|
||||||
#define StringIO(obj) get_strio(obj)
|
#define StringIO(obj) get_strio(obj)
|
||||||
|
|
||||||
|
#define CLOSED(ptr) NIL_P((ptr)->string)
|
||||||
|
#define READABLE(ptr) (!CLOSED(ptr) && ((ptr)->flags & FMODE_READABLE))
|
||||||
|
#define WRITABLE(ptr) (!CLOSED(ptr) && ((ptr)->flags & FMODE_WRITABLE))
|
||||||
|
|
||||||
static struct StringIO*
|
static struct StringIO*
|
||||||
readable(ptr)
|
readable(ptr)
|
||||||
struct StringIO *ptr;
|
struct StringIO *ptr;
|
||||||
{
|
{
|
||||||
if (NIL_P(ptr->string) || !(ptr->flags & FMODE_READABLE)) {
|
if (!READABLE(ptr)) {
|
||||||
rb_raise(rb_eIOError, "not opened for reading");
|
rb_raise(rb_eIOError, "not opened for reading");
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
|
@ -103,7 +108,7 @@ static struct StringIO*
|
||||||
writable(ptr)
|
writable(ptr)
|
||||||
struct StringIO *ptr;
|
struct StringIO *ptr;
|
||||||
{
|
{
|
||||||
if (NIL_P(ptr->string) || !(ptr->flags & FMODE_WRITABLE)) {
|
if (!WRITABLE(ptr)) {
|
||||||
rb_raise(rb_eIOError, "not opened for writing");
|
rb_raise(rb_eIOError, "not opened for writing");
|
||||||
}
|
}
|
||||||
if (!OBJ_TAINTED(ptr->string)) {
|
if (!OBJ_TAINTED(ptr->string)) {
|
||||||
|
@ -112,6 +117,16 @@ writable(ptr)
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct StringIO*
|
||||||
|
check_modifiable(ptr)
|
||||||
|
struct StringIO *ptr;
|
||||||
|
{
|
||||||
|
if (OBJ_FROZEN(ptr->string)) {
|
||||||
|
rb_raise(rb_eIOError, "not modifiable string");
|
||||||
|
}
|
||||||
|
rb_str_modify(ptr->string);
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE strio_s_allocate _((VALUE));
|
static VALUE strio_s_allocate _((VALUE));
|
||||||
static VALUE strio_s_open _((int, VALUE *, VALUE));
|
static VALUE strio_s_open _((int, VALUE *, VALUE));
|
||||||
static VALUE strio_initialize _((int, VALUE *, VALUE));
|
static VALUE strio_initialize _((int, VALUE *, VALUE));
|
||||||
|
@ -199,6 +214,10 @@ strio_initialize(argc, argv, self)
|
||||||
StringValue(mode);
|
StringValue(mode);
|
||||||
StringValue(string);
|
StringValue(string);
|
||||||
ptr->flags = rb_io_mode_flags(RSTRING(mode)->ptr);
|
ptr->flags = rb_io_mode_flags(RSTRING(mode)->ptr);
|
||||||
|
if (ptr->flags & FMODE_WRITABLE && OBJ_FROZEN(string)) {
|
||||||
|
errno = EACCES;
|
||||||
|
rb_sys_fail(0);
|
||||||
|
}
|
||||||
switch (*RSTRING(mode)->ptr) {
|
switch (*RSTRING(mode)->ptr) {
|
||||||
case 'a':
|
case 'a':
|
||||||
ptr->flags |= STRIO_APPEND;
|
ptr->flags |= STRIO_APPEND;
|
||||||
|
@ -210,7 +229,7 @@ strio_initialize(argc, argv, self)
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
StringValue(string);
|
StringValue(string);
|
||||||
ptr->flags = FMODE_READWRITE;
|
ptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE;
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
string = rb_str_new("", 0);
|
string = rb_str_new("", 0);
|
||||||
|
@ -310,7 +329,7 @@ strio_close(self)
|
||||||
VALUE self;
|
VALUE self;
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = StringIO(self);
|
struct StringIO *ptr = StringIO(self);
|
||||||
if (NIL_P(ptr->string)) {
|
if (CLOSED(ptr)) {
|
||||||
rb_raise(rb_eIOError, "closed stream");
|
rb_raise(rb_eIOError, "closed stream");
|
||||||
}
|
}
|
||||||
ptr->string = Qnil;
|
ptr->string = Qnil;
|
||||||
|
@ -322,7 +341,10 @@ static VALUE
|
||||||
strio_close_read(self)
|
strio_close_read(self)
|
||||||
VALUE self;
|
VALUE self;
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = readable(StringIO(self));
|
struct StringIO *ptr = StringIO(self);
|
||||||
|
if (!READABLE(ptr)) {
|
||||||
|
rb_raise(rb_eIOError, "closing non-duplex IO for reading");
|
||||||
|
}
|
||||||
if (!((ptr->flags &= ~FMODE_READABLE) & FMODE_READWRITE)) {
|
if (!((ptr->flags &= ~FMODE_READABLE) & FMODE_READWRITE)) {
|
||||||
ptr->string = Qnil;
|
ptr->string = Qnil;
|
||||||
}
|
}
|
||||||
|
@ -333,7 +355,10 @@ static VALUE
|
||||||
strio_close_write(self)
|
strio_close_write(self)
|
||||||
VALUE self;
|
VALUE self;
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = writable(StringIO(self));
|
struct StringIO *ptr = StringIO(self);
|
||||||
|
if (!WRITABLE(ptr)) {
|
||||||
|
rb_raise(rb_eIOError, "closing non-duplex IO for writing");
|
||||||
|
}
|
||||||
if (!((ptr->flags &= ~FMODE_WRITABLE) & FMODE_READWRITE)) {
|
if (!((ptr->flags &= ~FMODE_WRITABLE) & FMODE_READWRITE)) {
|
||||||
ptr->string = Qnil;
|
ptr->string = Qnil;
|
||||||
}
|
}
|
||||||
|
@ -345,7 +370,7 @@ strio_closed(self)
|
||||||
VALUE self;
|
VALUE self;
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = StringIO(self);
|
struct StringIO *ptr = StringIO(self);
|
||||||
if (!NIL_P(ptr->string)) return Qfalse;
|
if (!CLOSED(ptr)) return Qfalse;
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,7 +379,7 @@ strio_closed_read(self)
|
||||||
VALUE self;
|
VALUE self;
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = StringIO(self);
|
struct StringIO *ptr = StringIO(self);
|
||||||
if (ptr->flags & FMODE_READABLE) return Qfalse;
|
if (READABLE(ptr)) return Qfalse;
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,7 +388,7 @@ strio_closed_write(self)
|
||||||
VALUE self;
|
VALUE self;
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = StringIO(self);
|
struct StringIO *ptr = StringIO(self);
|
||||||
if (ptr->flags & FMODE_WRITABLE) return Qfalse;
|
if (WRITABLE(ptr)) return Qfalse;
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,9 +396,7 @@ static VALUE
|
||||||
strio_eof(self)
|
strio_eof(self)
|
||||||
VALUE self;
|
VALUE self;
|
||||||
{
|
{
|
||||||
struct StringIO *ptr = StringIO(self);
|
struct StringIO *ptr = readable(StringIO(self));
|
||||||
if (!(ptr->flags & FMODE_READABLE)) return Qtrue;
|
|
||||||
if (NIL_P(ptr->string)) return Qtrue;
|
|
||||||
if (ptr->pos < RSTRING(ptr->string)->len) return Qfalse;
|
if (ptr->pos < RSTRING(ptr->string)->len) return Qfalse;
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
|
@ -521,8 +544,11 @@ strio_ungetc(self, ch)
|
||||||
int cc = NUM2INT(ch);
|
int cc = NUM2INT(ch);
|
||||||
|
|
||||||
if (cc != EOF && ptr->pos > 0) {
|
if (cc != EOF && ptr->pos > 0) {
|
||||||
rb_str_modify(ptr->string);
|
if ((unsigned char)RSTRING(ptr->string)->ptr[--ptr->pos] !=
|
||||||
RSTRING(ptr->string)->ptr[--ptr->pos] = cc;
|
(unsigned char)cc) {
|
||||||
|
check_modifiable(ptr);
|
||||||
|
RSTRING(ptr->string)->ptr[ptr->pos] = cc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
@ -708,6 +734,8 @@ strio_write(self, str)
|
||||||
if (TYPE(str) != T_STRING)
|
if (TYPE(str) != T_STRING)
|
||||||
str = rb_obj_as_string(str);
|
str = rb_obj_as_string(str);
|
||||||
len = RSTRING(str)->len;
|
len = RSTRING(str)->len;
|
||||||
|
if (!len) return INT2FIX(0);
|
||||||
|
check_modifiable(ptr);
|
||||||
if (ptr->flags & STRIO_APPEND) {
|
if (ptr->flags & STRIO_APPEND) {
|
||||||
ptr->pos = RSTRING(ptr->string)->len;
|
ptr->pos = RSTRING(ptr->string)->len;
|
||||||
}
|
}
|
||||||
|
@ -732,6 +760,10 @@ strio_putc(self, ch)
|
||||||
struct StringIO *ptr = writable(StringIO(self));
|
struct StringIO *ptr = writable(StringIO(self));
|
||||||
int c = NUM2CHR(ch);
|
int c = NUM2CHR(ch);
|
||||||
|
|
||||||
|
check_modifiable(ptr);
|
||||||
|
if (ptr->flags & STRIO_APPEND) {
|
||||||
|
ptr->pos = RSTRING(ptr->string)->len;
|
||||||
|
}
|
||||||
if (ptr->pos >= RSTRING(ptr->string)->len) {
|
if (ptr->pos >= RSTRING(ptr->string)->len) {
|
||||||
rb_str_resize(ptr->string, ptr->pos + 1);
|
rb_str_resize(ptr->string, ptr->pos + 1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue