Skip to content

Commit 8d64eb6

Browse files
nobumatzbot
authored andcommitted
[ruby/stringio] Allow read-only methods to work with frozen StringIO
Fix ruby/stringio#120 ruby/stringio@b0e3ce88b3
1 parent 571ce8d commit 8d64eb6

1 file changed

Lines changed: 28 additions & 19 deletions

File tree

ext/stringio/stringio.c

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ struct StringIO {
6262
int count;
6363
};
6464

65+
static struct StringIO *get_strio_for_read(VALUE self);
6566
static VALUE strio_init(int, VALUE *, struct StringIO *, VALUE);
6667
static VALUE strio_unget_bytes(struct StringIO *, const char *, long);
6768
static long strio_write(VALUE self, VALUE str);
@@ -126,8 +127,14 @@ static const rb_data_type_t strio_data_type = {
126127
static struct StringIO*
127128
get_strio(VALUE self)
128129
{
129-
struct StringIO *ptr = check_strio(rb_io_taint_check(self));
130+
rb_check_frozen(self);
131+
return get_strio_for_read(self);
132+
}
130133

134+
static struct StringIO*
135+
get_strio_for_read(VALUE self)
136+
{
137+
struct StringIO *ptr = check_strio(self);
131138
if (!ptr) {
132139
rb_raise(rb_eIOError, "uninitialized stream");
133140
}
@@ -155,6 +162,7 @@ strio_substr(struct StringIO *ptr, long pos, long len, rb_encoding *enc)
155162
}
156163

157164
#define StringIO(obj) get_strio(obj)
165+
#define StringIOForRead(obj) get_strio_for_read(obj)
158166

159167
#define STRIO_READABLE FL_USER4
160168
#define STRIO_WRITABLE FL_USER5
@@ -182,7 +190,7 @@ static VALUE sym_exception;
182190
static struct StringIO*
183191
readable(VALUE strio)
184192
{
185-
struct StringIO *ptr = StringIO(strio);
193+
struct StringIO *ptr = StringIOForRead(strio);
186194
if (!READABLE(strio)) {
187195
rb_raise(rb_eIOError, "not opened for reading");
188196
}
@@ -387,7 +395,8 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
387395
static VALUE
388396
strio_finalize(VALUE self)
389397
{
390-
struct StringIO *ptr = StringIO(self);
398+
struct StringIO *ptr = check_strio(self);
399+
if (!ptr) return Qnil;
391400
RB_OBJ_WRITE(self, &ptr->string, Qnil);
392401
ptr->flags &= ~FMODE_READWRITE;
393402
return self;
@@ -439,7 +448,7 @@ strio_s_new(int argc, VALUE *argv, VALUE klass)
439448
static VALUE
440449
strio_false(VALUE self)
441450
{
442-
StringIO(self);
451+
StringIOForRead(self);
443452
return Qfalse;
444453
}
445454

@@ -449,7 +458,7 @@ strio_false(VALUE self)
449458
static VALUE
450459
strio_nil(VALUE self)
451460
{
452-
StringIO(self);
461+
StringIOForRead(self);
453462
return Qnil;
454463
}
455464

@@ -459,7 +468,7 @@ strio_nil(VALUE self)
459468
static VALUE
460469
strio_self(VALUE self)
461470
{
462-
StringIO(self);
471+
StringIOForRead(self);
463472
return self;
464473
}
465474

@@ -469,7 +478,7 @@ strio_self(VALUE self)
469478
static VALUE
470479
strio_0(VALUE self)
471480
{
472-
StringIO(self);
481+
StringIOForRead(self);
473482
return INT2FIX(0);
474483
}
475484

@@ -479,7 +488,7 @@ strio_0(VALUE self)
479488
static VALUE
480489
strio_first(VALUE self, VALUE arg)
481490
{
482-
StringIO(self);
491+
StringIOForRead(self);
483492
return arg;
484493
}
485494

@@ -489,7 +498,7 @@ strio_first(VALUE self, VALUE arg)
489498
static VALUE
490499
strio_unimpl(int argc, VALUE *argv, VALUE self)
491500
{
492-
StringIO(self);
501+
StringIOForRead(self);
493502
rb_notimplement();
494503

495504
UNREACHABLE;
@@ -517,7 +526,7 @@ strio_unimpl(int argc, VALUE *argv, VALUE self)
517526
static VALUE
518527
strio_get_string(VALUE self)
519528
{
520-
return StringIO(self)->string;
529+
return StringIOForRead(self)->string;
521530
}
522531

523532
/*
@@ -650,7 +659,7 @@ strio_close_write(VALUE self)
650659
static VALUE
651660
strio_closed(VALUE self)
652661
{
653-
StringIO(self);
662+
StringIOForRead(self);
654663
if (!CLOSED(self)) return Qfalse;
655664
return Qtrue;
656665
}
@@ -671,7 +680,7 @@ strio_closed(VALUE self)
671680
static VALUE
672681
strio_closed_read(VALUE self)
673682
{
674-
StringIO(self);
683+
StringIOForRead(self);
675684
if (READABLE(self)) return Qfalse;
676685
return Qtrue;
677686
}
@@ -692,7 +701,7 @@ strio_closed_read(VALUE self)
692701
static VALUE
693702
strio_closed_write(VALUE self)
694703
{
695-
StringIO(self);
704+
StringIOForRead(self);
696705
if (WRITABLE(self)) return Qfalse;
697706
return Qtrue;
698707
}
@@ -738,7 +747,7 @@ strio_copy(VALUE copy, VALUE orig)
738747

739748
orig = rb_convert_type(orig, T_DATA, "StringIO", "to_strio");
740749
if (copy == orig) return copy;
741-
ptr = StringIO(orig);
750+
ptr = StringIOForRead(orig);
742751
old_ptr = check_strio(copy);
743752
if (old_ptr) {
744753
old_string = old_ptr->string;
@@ -762,7 +771,7 @@ strio_copy(VALUE copy, VALUE orig)
762771
static VALUE
763772
strio_get_lineno(VALUE self)
764773
{
765-
return LONG2NUM(StringIO(self)->lineno);
774+
return LONG2NUM(StringIOForRead(self)->lineno);
766775
}
767776

768777
/*
@@ -850,7 +859,7 @@ strio_reopen(int argc, VALUE *argv, VALUE self)
850859
static VALUE
851860
strio_get_pos(VALUE self)
852861
{
853-
return LONG2NUM(StringIO(self)->pos);
862+
return LONG2NUM(StringIOForRead(self)->pos);
854863
}
855864

856865
/*
@@ -942,7 +951,7 @@ strio_seek(int argc, VALUE *argv, VALUE self)
942951
static VALUE
943952
strio_get_sync(VALUE self)
944953
{
945-
StringIO(self);
954+
StringIOForRead(self);
946955
return Qtrue;
947956
}
948957

@@ -1863,7 +1872,7 @@ strio_syswrite_nonblock(int argc, VALUE *argv, VALUE self)
18631872
static VALUE
18641873
strio_size(VALUE self)
18651874
{
1866-
VALUE string = StringIO(self)->string;
1875+
VALUE string = StringIOForRead(self)->string;
18671876
if (NIL_P(string)) {
18681877
return INT2FIX(0);
18691878
}
@@ -1915,7 +1924,7 @@ strio_truncate(VALUE self, VALUE len)
19151924
static VALUE
19161925
strio_external_encoding(VALUE self)
19171926
{
1918-
struct StringIO *ptr = StringIO(self);
1927+
struct StringIO *ptr = StringIOForRead(self);
19191928
return rb_enc_from_encoding(get_enc(ptr));
19201929
}
19211930

0 commit comments

Comments
 (0)