@@ -49,6 +49,13 @@ static long strio_write(VALUE self, VALUE str);
49
49
#define IS_STRIO (obj ) (rb_typeddata_is_kind_of((obj), &strio_data_type))
50
50
#define error_inval (msg ) (rb_syserr_fail(EINVAL, msg))
51
51
#define get_enc (ptr ) ((ptr)->enc ? (ptr)->enc : !NIL_P((ptr)->string) ? rb_enc_get((ptr)->string) : NULL)
52
+ #ifndef HAVE_RB_STR_CHILLED_P
53
+ static int
54
+ rb_str_chilled_p (VALUE str )
55
+ {
56
+ return 0 ;
57
+ }
58
+ #endif
52
59
53
60
static struct StringIO *
54
61
strio_alloc (void )
@@ -166,8 +173,14 @@ writable(VALUE strio)
166
173
static void
167
174
check_modifiable (struct StringIO * ptr )
168
175
{
169
- if (OBJ_FROZEN (ptr -> string )) {
170
- rb_raise (rb_eIOError , "not modifiable string" );
176
+ if (NIL_P (ptr -> string )) {
177
+ /* Null device StringIO */
178
+ }
179
+ else if (rb_str_chilled_p (ptr -> string )) {
180
+ rb_str_modify (ptr -> string );
181
+ }
182
+ else if (OBJ_FROZEN_RAW (ptr -> string )) {
183
+ rb_raise (rb_eIOError , "not modifiable string" );
171
184
}
172
185
}
173
186
@@ -287,7 +300,8 @@ strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
287
300
else if (!argc ) {
288
301
string = rb_enc_str_new ("" , 0 , rb_default_external_encoding ());
289
302
}
290
- if (!NIL_P (string ) && OBJ_FROZEN_RAW (string )) {
303
+
304
+ if (!NIL_P (string ) && OBJ_FROZEN_RAW (string ) && !rb_str_chilled_p (string )) {
291
305
if (ptr -> flags & FMODE_WRITABLE ) {
292
306
rb_syserr_fail (EACCES , 0 );
293
307
}
@@ -481,7 +495,7 @@ strio_set_string(VALUE self, VALUE string)
481
495
rb_io_taint_check (self );
482
496
ptr -> flags &= ~FMODE_READWRITE ;
483
497
StringValue (string );
484
- ptr -> flags = OBJ_FROZEN (string ) ? FMODE_READABLE : FMODE_READWRITE ;
498
+ ptr -> flags = OBJ_FROZEN (string ) && ! rb_str_chilled_p ( string ) ? FMODE_READABLE : FMODE_READWRITE ;
485
499
ptr -> pos = 0 ;
486
500
ptr -> lineno = 0 ;
487
501
RB_OBJ_WRITE (self , & ptr -> string , string );
0 commit comments