summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-12-31 07:34:41 -0800
committerKaz Kylheku <kaz@kylheku.com>2014-12-31 07:34:41 -0800
commit99c41ec1654df41ab027c18559227254d976e59a (patch)
treed9f7d5f312d7d4e01479e6fb94aef1a6255514c8 /lib.c
parentbf5a03f450f26e07a1ccc6f00d9bd0c5659e8591 (diff)
downloadtxr-99c41ec1654df41ab027c18559227254d976e59a.tar.gz
txr-99c41ec1654df41ab027c18559227254d976e59a.tar.bz2
txr-99c41ec1654df41ab027c18559227254d976e59a.zip
* lib.c (replace_str, replace_vec): Bugfix. The replacement item
sequence may be an infinite list in the case that the from argument specifies a list of indices. We must avoid trying to calculate its length before we have detected this case.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c178
1 files changed, 91 insertions, 87 deletions
diff --git a/lib.c b/lib.c
index dd038866..a6f01a66 100644
--- a/lib.c
+++ b/lib.c
@@ -2607,8 +2607,6 @@ val replace_str(val str_in, val items, val from, val to)
{
val itseq = toseq(items);
val len = length_str(str_in);
- val len_it = length(itseq);
- val len_rep;
if (type(str_in) != STR) {
uw_throwf(error_s, lit("replace-str: ~s of type ~s is not "
@@ -2651,53 +2649,57 @@ val replace_str(val str_in, val items, val from, val to)
from = max2(zero, min2(from, len));
to = max2(zero, min2(to, len));
- len_rep = minus(to, from);
- if (gt(len_rep, len_it)) {
- val len_diff = minus(len_rep, len_it);
- cnum t = c_num(to);
- cnum l = c_num(len);
-
- wmemmove(str_in->st.str + t - c_num(len_diff),
- str_in->st.str + t, (l - t) + 1);
- set(mkloc(str_in->st.len, str_in), minus(len, len_diff));
- to = plus(from, len_it);
- } else if (lt(len_rep, len_it)) {
- val len_diff = minus(len_it, len_rep);
- cnum t = c_num(to);
- cnum l = c_num(len);
-
- string_extend(str_in, plus(len, len_diff));
- wmemmove(str_in->st.str + t + c_num(len_diff),
- str_in->st.str + t, (l - t) + 1);
- to = plus(from, len_it);
- }
+ {
+ val len_rep = minus(to, from);
+ val len_it = length(itseq);
+
+ if (gt(len_rep, len_it)) {
+ val len_diff = minus(len_rep, len_it);
+ cnum t = c_num(to);
+ cnum l = c_num(len);
+
+ wmemmove(str_in->st.str + t - c_num(len_diff),
+ str_in->st.str + t, (l - t) + 1);
+ set(mkloc(str_in->st.len, str_in), minus(len, len_diff));
+ to = plus(from, len_it);
+ } else if (lt(len_rep, len_it)) {
+ val len_diff = minus(len_it, len_rep);
+ cnum t = c_num(to);
+ cnum l = c_num(len);
+
+ string_extend(str_in, plus(len, len_diff));
+ wmemmove(str_in->st.str + t + c_num(len_diff),
+ str_in->st.str + t, (l - t) + 1);
+ to = plus(from, len_it);
+ }
- if (zerop(len_it))
- return str_in;
- if (stringp(itseq)) {
- wmemcpy(str_in->st.str + c_num(from), c_str(itseq), c_num(len_it));
- } else {
- val iter;
- cnum f = c_num(from);
- cnum t = c_num(to);
- cnum s;
-
- if (listp(itseq)) {
- for (iter = itseq; iter && f != t; iter = cdr(iter), f++)
- str_in->st.str[f] = c_chr(car(iter));
- } else if (vectorp(itseq)) {
- for (s = 0; f != t; f++, s++)
- str_in->st.str[f] = c_chr(vecref(itseq, num(s)));
+ if (zerop(len_it))
+ return str_in;
+ if (stringp(itseq)) {
+ wmemcpy(str_in->st.str + c_num(from), c_str(itseq), c_num(len_it));
} else {
- uw_throwf(error_s, lit("replace-str: source object ~s not supported"),
- itseq, nao);
+ val iter;
+ cnum f = c_num(from);
+ cnum t = c_num(to);
+ cnum s;
+
+ if (listp(itseq)) {
+ for (iter = itseq; iter && f != t; iter = cdr(iter), f++)
+ str_in->st.str[f] = c_chr(car(iter));
+ } else if (vectorp(itseq)) {
+ for (s = 0; f != t; f++, s++)
+ str_in->st.str[f] = c_chr(vecref(itseq, num(s)));
+ } else {
+ uw_throwf(error_s, lit("replace-str: source object ~s not supported"),
+ itseq, nao);
+ }
}
}
+
return str_in;
}
-
val cat_str(val list, val sep)
{
cnum total = 0;
@@ -4950,8 +4952,6 @@ val replace_vec(val vec_in, val items, val from, val to)
{
val it_seq = toseq(items);
val len = length_vec(vec_in);
- val len_it = length(it_seq);
- val len_rep;
if (consp(from)) {
val where = from;
@@ -4988,55 +4988,59 @@ val replace_vec(val vec_in, val items, val from, val to)
from = max2(zero, min2(from, len));
to = max2(zero, min2(to, len));
- len_rep = minus(to, from);
-
- if (gt(len_rep, len_it)) {
- val len_diff = minus(len_rep, len_it);
- cnum t = c_num(to);
- cnum l = c_num(len);
-
- memmove(vec_in->v.vec + t - c_num(len_diff),
- vec_in->v.vec + t,
- (l - t) * sizeof vec_in->v.vec);
+ {
+ val len_rep = minus(to, from);
+ val len_it = length(it_seq);
+
+ if (gt(len_rep, len_it)) {
+ val len_diff = minus(len_rep, len_it);
+ cnum t = c_num(to);
+ cnum l = c_num(len);
+
+ memmove(vec_in->v.vec + t - c_num(len_diff),
+ vec_in->v.vec + t,
+ (l - t) * sizeof vec_in->v.vec);
+
+ vec_in->v.vec[vec_length] = minus(len, len_diff);
+ to = plus(from, len_it);
+ } else if (lt(len_rep, len_it)) {
+ val len_diff = minus(len_it, len_rep);
+ cnum t = c_num(to);
+ cnum l = c_num(len);
+
+ vec_set_length(vec_in, plus(len, len_diff));
+
+ memmove(vec_in->v.vec + t + c_num(len_diff),
+ vec_in->v.vec + t,
+ (l - t) * sizeof vec_in->v.vec);
+ to = plus(from, len_it);
+ }
- vec_in->v.vec[vec_length] = minus(len, len_diff);
- to = plus(from, len_it);
- } else if (lt(len_rep, len_it)) {
- val len_diff = minus(len_it, len_rep);
- cnum t = c_num(to);
- cnum l = c_num(len);
+ if (zerop(len_it))
+ return vec_in;
+ if (vectorp(it_seq)) {
+ memcpy(vec_in->v.vec + c_num(from), it_seq->v.vec,
+ sizeof *vec_in->v.vec * c_num(len_it));
+ mut(vec_in);
+ } else if (stringp(it_seq)) {
+ cnum f = c_num(from);
+ cnum t = c_num(to);
+ cnum s;
+ const wchar_t *str = c_str(it_seq);
- vec_set_length(vec_in, plus(len, len_diff));
+ for (s = 0; f != t; f++, s++)
+ vec_in->v.vec[f] = chr(str[s]);
+ } else {
+ val iter;
+ cnum f = c_num(from);
+ cnum t = c_num(to);
- memmove(vec_in->v.vec + t + c_num(len_diff),
- vec_in->v.vec + t,
- (l - t) * sizeof vec_in->v.vec);
- to = plus(from, len_it);
+ for (iter = it_seq; iter && f != t; iter = cdr(iter), f++)
+ vec_in->v.vec[f] = car(iter);
+ mut(vec_in);
+ }
}
- if (zerop(len_it))
- return vec_in;
- if (vectorp(it_seq)) {
- memcpy(vec_in->v.vec + c_num(from), it_seq->v.vec,
- sizeof *vec_in->v.vec * c_num(len_it));
- mut(vec_in);
- } else if (stringp(it_seq)) {
- cnum f = c_num(from);
- cnum t = c_num(to);
- cnum s;
- const wchar_t *str = c_str(it_seq);
-
- for (s = 0; f != t; f++, s++)
- vec_in->v.vec[f] = chr(str[s]);
- } else {
- val iter;
- cnum f = c_num(from);
- cnum t = c_num(to);
-
- for (iter = it_seq; iter && f != t; iter = cdr(iter), f++)
- vec_in->v.vec[f] = car(iter);
- mut(vec_in);
- }
return vec_in;
}