summaryrefslogtreecommitdiff
path: root/ext/-test-
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-05-30 07:20:28 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-05-30 07:20:28 +0000
commit79a85b18cc6ad27f1a70a703270680dc30a1263e (patch)
tree4fbfcaf67c80822fe2ea7b2de20a9c49304aa734 /ext/-test-
parentbfc9c3766f3efd58002bd6e58074c16322abd852 (diff)
string.c: return reallocated pointer
* string.c (str_fill_term): return new pointer reallocated by filling terminator. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55212 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/-test-')
-rw-r--r--ext/-test-/string/cstr.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/ext/-test-/string/cstr.c b/ext/-test-/string/cstr.c
index 9bd33a3..fc47d52 100644
--- a/ext/-test-/string/cstr.c
+++ b/ext/-test-/string/cstr.c
@@ -50,6 +50,28 @@ bug_str_cstr_term_char(VALUE str)
}
static VALUE
+bug_str_unterminated_substring(VALUE str, VALUE vbeg, VALUE vlen)
+{
+ long beg = NUM2LONG(vbeg);
+ long len = NUM2LONG(vlen);
+ rb_str_modify(str);
+ if (len < 0) rb_raise(rb_eArgError, "negative length: %ld", len);
+ if (RSTRING_LEN(str) < beg) rb_raise(rb_eIndexError, "beg: %ld", beg);
+ if (RSTRING_LEN(str) < beg + len) rb_raise(rb_eIndexError, "end: %ld", beg + len);
+ str = rb_str_new_shared(str);
+ if (STR_EMBED_P(str)) {
+ RSTRING(str)->basic.flags &= ~RSTRING_EMBED_LEN_MASK;
+ RSTRING(str)->basic.flags |= len << RSTRING_EMBED_LEN_SHIFT;
+ memmove(RSTRING(str)->as.ary, RSTRING(str)->as.ary + beg, len);
+ }
+ else {
+ RSTRING(str)->as.heap.ptr += beg;
+ RSTRING(str)->as.heap.len = len;
+ }
+ return str;
+}
+
+static VALUE
bug_str_s_cstr_term(VALUE self, VALUE str)
{
Check_Type(str, T_STRING);
@@ -114,6 +136,7 @@ Init_cstr(VALUE klass)
rb_define_method(klass, "cstr_term", bug_str_cstr_term, 0);
rb_define_method(klass, "cstr_unterm", bug_str_cstr_unterm, 1);
rb_define_method(klass, "cstr_term_char", bug_str_cstr_term_char, 0);
+ rb_define_method(klass, "unterminated_substring", bug_str_unterminated_substring, 2);
rb_define_singleton_method(klass, "cstr_term", bug_str_s_cstr_term, 1);
rb_define_singleton_method(klass, "cstr_unterm", bug_str_s_cstr_unterm, 2);
rb_define_singleton_method(klass, "cstr_term_char", bug_str_s_cstr_term_char, 1);