summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2017-01-02 17:48:27 +0900
committerGitHub <[email protected]>2017-01-02 17:48:27 +0900
commit158a6ab2ed64a448d7345d56d1d7430a9f52d4b8 (patch)
tree3e9f7031a42b8e2a6c2726d23e7873586c2cdf19 /src
parent07167b8f5eb7e0ff7b4048ffcfefe9a38c904a75 (diff)
parent8a9a24152a23595fba0802f555d49e0c263836af (diff)
downloadmruby-158a6ab2ed64a448d7345d56d1d7430a9f52d4b8.tar.gz
mruby-158a6ab2ed64a448d7345d56d1d7430a9f52d4b8.zip
Merge pull request #3367 from ksss/str-modify
Fix segv on str_buf_cat
Diffstat (limited to 'src')
-rw-r--r--src/string.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/src/string.c b/src/string.c
index 072bf2226..ae2e5ccc8 100644
--- a/src/string.c
+++ b/src/string.c
@@ -154,10 +154,7 @@ str_buf_cat(mrb_state *mrb, struct RString *s, const char *ptr, size_t len)
off = ptr - RSTR_PTR(s);
}
- if (RSTR_EMBED_P(s))
- capa = RSTRING_EMBED_LEN_MAX;
- else
- capa = s->as.heap.aux.capa;
+ capa = RSTR_CAPA(s);
if (capa <= RSTRING_EMBED_LEN_MAX)
capa = RSTRING_EMBED_LEN_MAX+1;
@@ -698,14 +695,21 @@ mrb_str_modify(mrb_state *mrb, struct RString *s)
}
if (RSTR_NOFREE_P(s)) {
char *p = s->as.heap.ptr;
+ mrb_int len = s->as.heap.len;
- s->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)s->as.heap.len+1);
+ RSTR_UNSET_NOFREE_FLAG(s);
+ if (len < RSTRING_EMBED_LEN_MAX) {
+ RSTR_SET_EMBED_FLAG(s);
+ RSTR_SET_EMBED_LEN(s, len);
+ }
+ else {
+ s->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
+ s->as.heap.aux.capa = len;
+ }
if (p) {
- memcpy(RSTR_PTR(s), p, s->as.heap.len);
+ memcpy(RSTR_PTR(s), p, len);
}
- RSTR_PTR(s)[s->as.heap.len] = '\0';
- s->as.heap.aux.capa = s->as.heap.len;
- RSTR_UNSET_NOFREE_FLAG(s);
+ RSTR_PTR(s)[len] = '\0';
return;
}
}