diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-07-05 07:45:58 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-07-05 07:45:58 -0700 |
commit | 3182bdf1e39559179c8e7f97ea9eb5f4bff0ef7f (patch) | |
tree | 128bff8650f4f35a265123baf96a9b6f0bf76919 | |
parent | aa179ce68abcefc3edd30f01cdde35461af9cc2f (diff) | |
download | txr-3182bdf1e39559179c8e7f97ea9eb5f4bff0ef7f.tar.gz txr-3182bdf1e39559179c8e7f97ea9eb5f4bff0ef7f.tar.bz2 txr-3182bdf1e39559179c8e7f97ea9eb5f4bff0ef7f.zip |
replace: deal with overlapping.
* buf.c (replace_buf): In the same-type case, use memmove
rather than memcpy in case the objects overlap, so we
don't invoke C undefined behavior.
* lib.c (replace_str, replace_vec): Likewise.
* txr.1: Specify that if the replacement sequence overlaps
with the target range of the destination sequence, or
with any portion that has to be relocated if range
changes size, then the behavior is unspecified.
-rw-r--r-- | buf.c | 2 | ||||
-rw-r--r-- | lib.c | 6 | ||||
-rw-r--r-- | txr.1 | 12 |
3 files changed, 16 insertions, 4 deletions
@@ -339,7 +339,7 @@ val replace_buf(val buf, val items, val from, val to) if (zerop(len_it)) return buf; if (bufp(items)) { - memcpy(buf->b.data + c_num(from), items->b.data, c_num(len_it)); + memmove(buf->b.data + c_num(from), items->b.data, c_num(len_it)); } else { seq_iter_t item_iter; seq_iter_init(self, &item_iter, items); @@ -3857,7 +3857,7 @@ val replace_str(val str_in, val items, val from, val to) if (zerop(len_it)) return str_in; if (stringp(items)) { - wmemcpy(str_in->st.str + c_num(from), c_str(items), c_num(len_it)); + wmemmove(str_in->st.str + c_num(from), c_str(items), c_num(len_it)); } else { seq_iter_t item_iter; seq_iter_init(self, &item_iter, items); @@ -7289,8 +7289,8 @@ val replace_vec(val vec_in, val items, val from, val to) if (zerop(len_it)) return vec_in; if (vectorp(items)) { - memcpy(vec_in->v.vec + c_num(from), items->v.vec, - sizeof *vec_in->v.vec * c_num(len_it)); + memmove(vec_in->v.vec + c_num(from), items->v.vec, + sizeof *vec_in->v.vec * c_num(len_it)); mut(vec_in); } else { seq_iter_t item_iter; @@ -28195,6 +28195,18 @@ be monotonically increasing, after consideration of the displacement of negative values. If +.meta replacement-sequence +shares storage with the target range of +.metn sequence , +or, in the case when that range is resized by the +.code replace +operation, shares storage with any portion of +.meta sequence +above that range, then the effect of +.code replace +on either object is unspecified. + +If .meta sequence is a .code carray |