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