[ruby/stringio] Fix ascii_only? flag in strio_write

(https://github.com/ruby/stringio/pull/77)

Followup of #79

`rb_str_resize()` was changed by b0b9f7201a  .

```c
rb_str_resize(string, shorter) // clear ENC_CODERANGE in some case
rb_str_resize(string, longer) // does not clear ENC_CODERANGE anymore
```

```c
// rb_str_resize in string.c
if (slen > len && ENC_CODERANGE(str) != ENC_CODERANGE_7BIT) {
  ENC_CODERANGE_CLEAR(str);
}
```

I think this change is based on an assumption that appending null bytes
will not change flag `ascii_only?`.

`strio_extend()` will make the string longer if needed, and update the
flags correctly for appending null bytes.
Before `memmove()`, we need to `rb_str_modify()` because updated flags are not
updated for `memmove()`.

https://github.com/ruby/stringio/commit/b31a538576
This commit is contained in:
tomoya ishida 2024-01-18 12:42:15 +09:00 коммит произвёл git
Родитель 4095191f2c
Коммит fd1bafc11f
2 изменённых файлов: 7 добавлений и 9 удалений

Просмотреть файл

@ -915,9 +915,6 @@ strio_extend(struct StringIO *ptr, long pos, long len)
if (pos > olen)
MEMZERO(RSTRING_PTR(ptr->string) + olen, char, pos - olen);
}
else {
rb_str_modify(ptr->string);
}
}
/*
@ -1464,14 +1461,9 @@ strio_write(VALUE self, VALUE str)
}
}
else {
int cr0 = ENC_CODERANGE(ptr->string);
int cr = ENC_CODERANGE_UNKNOWN;
if (rb_enc_asciicompat(enc) && rb_enc_asciicompat(enc2)) {
cr = ENC_CODERANGE_AND(cr0, ENC_CODERANGE(str));
}
strio_extend(ptr, ptr->pos, len);
rb_str_modify(ptr->string);
memmove(RSTRING_PTR(ptr->string)+ptr->pos, RSTRING_PTR(str), len);
if (cr != cr0) ENC_CODERANGE_SET(ptr->string, cr);
}
RB_GC_GUARD(str);
ptr->pos += len;

Просмотреть файл

@ -961,6 +961,12 @@ class TestStringIO < Test::Unit::TestCase
assert_predicate(s.string, :ascii_only?)
s.write "\u{431 43e 433 443 441}"
assert_not_predicate(s.string, :ascii_only?)
s = StringIO.new("\u{3042}")
s.rewind
assert_not_predicate(s.string, :ascii_only?)
s.write('aaaa')
assert_predicate(s.string, :ascii_only?)
end
def assert_string(content, encoding, str, mesg = nil)