diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2000-08-07 05:05:04 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2000-08-07 05:05:04 +0000 |
commit | c67251edb478509b4abd9910e0b499a116112a3c (patch) | |
tree | 81d59bfb40b0efc64b3acfc9cbe4dd7d3628af85 /string.c | |
parent | 14fe04bdacfb1bbe1e568c4e1dd4092a64c5ede7 (diff) |
matz
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@876 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'string.c')
-rw-r--r-- | string.c | 50 |
1 files changed, 31 insertions, 19 deletions
@@ -97,7 +97,12 @@ rb_str_new4(orig) VALUE orig; { if (OBJ_FROZEN(orig)) return orig; - if (RSTRING(orig)->orig && !FL_TEST(orig, STR_NO_ORIG)) { + if (RSTRING(orig)->orig) { + if (FL_TEST(orig, STR_NO_ORIG)) { + orig = rb_str_new(RSTRING(orig)->ptr, RSTRING(orig)->len); + OBJ_FREEZE(orig); + return orig; + } OBJ_FREEZE(RSTRING(orig)->orig); return RSTRING(orig)->orig; } @@ -349,24 +354,32 @@ rb_str_substr(str, beg, len) return str2; } +static int +str_independent(str) + VALUE str; +{ + if (OBJ_FROZEN(str)) rb_error_frozen("string"); + if (!OBJ_TAINTED(str) && rb_safe_level() >= 4) + rb_raise(rb_eSecurityError, "Insecure: can't modify string"); + if (!RSTRING(str)->orig || FL_TEST(str, STR_NO_ORIG)) return 1; + if (TYPE(RSTRING(str)->orig) != T_STRING) rb_bug("non string str->orig"); + RSTRING(str)->orig = 0; + return 0; +} + void rb_str_modify(str) VALUE str; { char *ptr; - if (OBJ_FROZEN(str)) rb_error_frozen("string"); - if (!OBJ_TAINTED(str) && rb_safe_level() >= 4) - rb_raise(rb_eSecurityError, "Insecure: can't modify string"); - if (!RSTRING(str)->orig || FL_TEST(str, STR_NO_ORIG)) return; - if (TYPE(RSTRING(str)->orig) != T_STRING) abort(); + if (str_independent(str)) return; ptr = ALLOC_N(char, RSTRING(str)->len+1); if (RSTRING(str)->ptr) { memcpy(ptr, RSTRING(str)->ptr, RSTRING(str)->len); } ptr[RSTRING(str)->len] = 0; RSTRING(str)->ptr = ptr; - RSTRING(str)->orig = 0; } VALUE @@ -1250,8 +1263,9 @@ str_gsub(argc, argv, str, bang) } rb_backref_set(match); if (bang) { - rb_str_modify(str); - free(RSTRING(str)->ptr); + if (str_independent(str)) { + free(RSTRING(str)->ptr); + } } else { NEWOBJ(dup, struct RString); @@ -1325,13 +1339,12 @@ rb_f_sub(argc, argv) int argc; VALUE *argv; { - VALUE str = uscore_get(); - VALUE dup = rb_str_dup(str); + VALUE str = rb_str_dup(uscore_get()); - if (NIL_P(rb_str_sub_bang(argc, argv, dup))) + if (NIL_P(rb_str_sub_bang(argc, argv, str))) return str; - rb_lastline_set(dup); - return dup; + rb_lastline_set(str); + return str; } static VALUE @@ -1347,13 +1360,12 @@ rb_f_gsub(argc, argv) int argc; VALUE *argv; { - VALUE str = uscore_get(); - VALUE dup = rb_str_dup(str); + VALUE str = rb_str_dup(uscore_get()); - if (NIL_P(rb_str_gsub_bang(argc, argv, dup))) + if (NIL_P(rb_str_gsub_bang(argc, argv, str))) return str; - rb_lastline_set(dup); - return dup; + rb_lastline_set(str); + return str; } static VALUE |