summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2024-07-08 00:07:28 -0700
committerKaz Kylheku <kaz@kylheku.com>2024-07-08 00:07:28 -0700
commit76789e6db8533da2ba9fd20cf66573d90ce22b4a (patch)
treef9fb3352868f44c6cb38072108460caa2143ab15 /lib.c
parent17369f7c13b842646b0d6384614bd16dddb7d753 (diff)
downloadtxr-76789e6db8533da2ba9fd20cf66573d90ce22b4a.tar.gz
txr-76789e6db8533da2ba9fd20cf66573d90ce22b4a.tar.bz2
txr-76789e6db8533da2ba9fd20cf66573d90ce22b4a.zip
partition, split, split*: infinite looping regression.
This is a bug introduced in 9cfa3435 on 2024-02-24. The underlying cause is lack of test coverage for these functions. * lib.c (partition_func, split_func, split_star_func): The original code iterated through the indies using the pop macro, thus extracting the next index and stepping in one step. The iter_begin rewrite wrongly moved the iter_step into one of the cases. The index iteration must be stepped in the case where the loop is continued vi continue, otherwise an infinite loop results.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/lib.c b/lib.c
index 52f984e3..c0a4d850 100644
--- a/lib.c
+++ b/lib.c
@@ -4209,6 +4209,8 @@ static val partition_func(val base, val lcons)
raw_index);
val index_rebased = minus(index, base);
+ indices = iter_step(indices);
+
if (le(index_rebased, zero)) {
continue;
} else {
@@ -4218,8 +4220,7 @@ static val partition_func(val base, val lcons)
if (rest) {
val fun = us_lcons_fun(lcons);
us_func_set_env(fun, index);
- us_rplacd(lcons, make_lazy_cons_car_cdr(fun, rest,
- iter_step(indices)));
+ us_rplacd(lcons, make_lazy_cons_car_cdr(fun, rest, indices));
} else {
us_rplacd(lcons, nil);
}
@@ -4249,6 +4250,8 @@ static val split_func(val base, val lcons)
raw_index);
val index_rebased = minus(index, base);
+ indices = iter_step(indices);
+
if (minusp(index_rebased)) {
continue;
} else {
@@ -4259,8 +4262,7 @@ static val split_func(val base, val lcons)
if (rest) {
val fun = us_lcons_fun(lcons);
us_func_set_env(fun, index);
- us_rplacd(lcons, make_lazy_cons_car_cdr(fun, rest,
- iter_step(indices)));
+ us_rplacd(lcons, make_lazy_cons_car_cdr(fun, rest, indices));
} else {
us_rplacd(lcons, cons(rsub, nil));
}
@@ -4290,6 +4292,8 @@ static val split_star_func(val base, val lcons)
raw_index);
val index_rebased = minus(index, base);
+ indices = iter_step(indices);
+
if (minusp(index_rebased)) {
continue;
} else {
@@ -4300,8 +4304,7 @@ static val split_star_func(val base, val lcons)
if (rest) {
val fun = us_lcons_fun(lcons);
us_func_set_env(fun, succ(index));
- us_rplacd(lcons, make_lazy_cons_car_cdr(fun, rest,
- iter_step(indices)));
+ us_rplacd(lcons, make_lazy_cons_car_cdr(fun, rest, indices));
} else {
us_rplacd(lcons, cons(rsub, nil));
}