diff options
| author | Masamitsu MURASE <[email protected]> | 2012-06-28 01:01:56 +0900 |
|---|---|---|
| committer | Masamitsu MURASE <[email protected]> | 2012-06-30 21:42:10 +0900 |
| commit | 866f797125093cca9563c753716e3cede1cc5a3f (patch) | |
| tree | 976d08e1b95da5ad830fa6893b3fb58a10be688a /src/string.c | |
| parent | 4bfd992284ee05148aaddfe98d69630353272288 (diff) | |
| download | mruby-866f797125093cca9563c753716e3cede1cc5a3f.tar.gz mruby-866f797125093cca9563c753716e3cede1cc5a3f.zip | |
Fix str_replace in string.c
- Increment refcnt of shared string.
- Free buffer before replacing.
- Clear MRB_STR_SHARED after decref is called.
- Fix target of aux.capa.
Diffstat (limited to 'src/string.c')
| -rw-r--r-- | src/string.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/string.c b/src/string.c index 8e61e6bb9..02f71ef96 100644 --- a/src/string.c +++ b/src/string.c @@ -1549,10 +1549,17 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) { if (s2->flags & MRB_STR_SHARED) { L_SHARE: + if (s1->flags & MRB_STR_SHARED){ + mrb_str_decref(mrb, s1->aux.shared); + } + else { + mrb_free(mrb, s1->ptr); + } s1->ptr = s2->ptr; s1->len = s2->len; s1->aux.shared = s2->aux.shared; s1->flags |= MRB_STR_SHARED; + s1->aux.shared->refcnt++; } else if (s2->len > STR_REPLACE_SHARED_MIN) { str_make_shared(mrb, s2); @@ -1561,6 +1568,7 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) else { if (s1->flags & MRB_STR_SHARED) { mrb_str_decref(mrb, s1->aux.shared); + s1->flags &= ~MRB_STR_SHARED; s1->ptr = mrb_malloc(mrb, s2->len+1); } else { @@ -1569,7 +1577,7 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) memcpy(s1->ptr, s2->ptr, s2->len); s1->ptr[s2->len] = 0; s1->len = s2->len; - s2->aux.capa = s2->len; + s1->aux.capa = s2->len; } return mrb_obj_value(s1); } |
