summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Kokubun <[email protected]>2024-05-29 10:19:49 -0700
committerTakashi Kokubun <[email protected]>2024-05-29 10:19:49 -0700
commitf12c947192aa47b355015384e5c82cbf674023f1 (patch)
treea45c0fdbc4318c53a15e7a69779bafea9dba0e04
parenta8b2317d16fa172edd3cd7e6fcb3bc694287d109 (diff)
merge revision(s) e04146129ec6898dd6a9739dad2983c6e9b68056: [Backport #20292]
[Bug #20292] Truncate embedded string to new capacity
-rw-r--r--string.c12
-rw-r--r--test/ruby/test_string.rb7
-rw-r--r--version.h2
3 files changed, 12 insertions, 9 deletions
diff --git a/string.c b/string.c
index 702024671a..cae234687d 100644
--- a/string.c
+++ b/string.c
@@ -1860,17 +1860,13 @@ rb_str_init(int argc, VALUE *argv, VALUE str)
if (orig == str) n = 0;
}
str_modifiable(str);
- if (STR_EMBED_P(str)) { /* make noembed always */
- char *new_ptr = ALLOC_N(char, (size_t)capa + termlen);
- assert(RSTRING_LEN(str) + 1 <= str_embed_capa(str));
- memcpy(new_ptr, RSTRING(str)->as.embed.ary, RSTRING_LEN(str) + 1);
- RSTRING(str)->as.heap.ptr = new_ptr;
- }
- else if (FL_TEST(str, STR_SHARED|STR_NOFREE)) {
+ if (STR_EMBED_P(str) || FL_TEST(str, STR_SHARED|STR_NOFREE)) {
+ /* make noembed always */
const size_t size = (size_t)capa + termlen;
const char *const old_ptr = RSTRING_PTR(str);
const size_t osize = RSTRING_LEN(str) + TERM_LEN(str);
- char *new_ptr = ALLOC_N(char, (size_t)capa + termlen);
+ char *new_ptr = ALLOC_N(char, size);
+ if (STR_EMBED_P(str)) RUBY_ASSERT(osize <= str_embed_capa(str));
memcpy(new_ptr, old_ptr, osize < size ? osize : size);
FL_UNSET_RAW(str, STR_SHARED|STR_NOFREE);
RSTRING(str)->as.heap.ptr = new_ptr;
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb
index 42f2544b5a..85a72b09cc 100644
--- a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -80,6 +80,13 @@ class TestString < Test::Unit::TestCase
assert_equal("mystring", str.__send__(:initialize, "mystring", capacity: 1000))
str = S("mystring")
assert_equal("mystring", str.__send__(:initialize, str, capacity: 1000))
+
+ if @cls == String
+ 100.times {
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".
+ __send__(:initialize, capacity: -1)
+ }
+ end
end
def test_initialize_shared
diff --git a/version.h b/version.h
index 71ce08f055..beff9a3d4e 100644
--- a/version.h
+++ b/version.h
@@ -11,7 +11,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 1
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 61
+#define RUBY_PATCHLEVEL 62
#include "ruby/version.h"
#include "ruby/internal/abi.h"