diff options
| author | nagachika <nagachika@ruby-lang.org> | 2023-09-30 13:51:18 +0900 |
|---|---|---|
| committer | nagachika <nagachika@ruby-lang.org> | 2023-09-30 13:51:18 +0900 |
| commit | ddbab4f837460f070942e8127de9a9f1b9868fff (patch) | |
| tree | edfc27866027033b4c319dbd0b1848762acc26e0 /string.c | |
| parent | 128d8728d39c2da21e5433c7af169f73e18fd133 (diff) | |
merge revision(s) 6b66b5fdedb2c9a9ee48e290d57ca7f8d55e01a2: [Backport #19902]
[Bug #19902] Update the coderange regarding the changed region
---
ext/-test-/string/set_len.c | 10 ++++++++++
string.c | 27 +++++++++++++++++++++++++++
test/-ext-/string/test_set_len.rb | 29 +++++++++++++++++++++++++++++
3 files changed, 66 insertions(+)
Diffstat (limited to 'string.c')
| -rw-r--r-- | string.c | 27 |
1 files changed, 27 insertions, 0 deletions
@@ -3029,6 +3029,33 @@ rb_str_set_len(VALUE str, long len) if (len > (capa = (long)str_capacity(str, termlen)) || len < 0) { rb_bug("probable buffer overflow: %ld for %ld", len, capa); } + + int cr = ENC_CODERANGE(str); + if (cr == ENC_CODERANGE_UNKNOWN) { + /* Leave unknown. */ + } + else if (len > RSTRING_LEN(str)) { + if (ENC_CODERANGE_CLEAN_P(cr)) { + /* Update the coderange regarding the extended part. */ + const char *const prev_end = RSTRING_END(str); + const char *const new_end = RSTRING_PTR(str) + len; + rb_encoding *enc = rb_enc_get(str); + rb_str_coderange_scan_restartable(prev_end, new_end, enc, &cr); + ENC_CODERANGE_SET(str, cr); + } + else if (cr == ENC_CODERANGE_BROKEN) { + /* May be valid now, by appended part. */ + ENC_CODERANGE_SET(str, ENC_CODERANGE_UNKNOWN); + } + } + else if (len < RSTRING_LEN(str)) { + if (cr != ENC_CODERANGE_7BIT) { + /* ASCII-only string is keeping after truncated. Valid + * and broken may be invalid or valid, leave unknown. */ + ENC_CODERANGE_SET(str, ENC_CODERANGE_UNKNOWN); + } + } + STR_SET_LEN(str, len); TERM_FILL(&RSTRING_PTR(str)[len], termlen); } |
