diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2024-07-08 00:07:28 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2024-07-08 00:07:28 -0700 |
commit | 76789e6db8533da2ba9fd20cf66573d90ce22b4a (patch) | |
tree | f9fb3352868f44c6cb38072108460caa2143ab15 /lib.c | |
parent | 17369f7c13b842646b0d6384614bd16dddb7d753 (diff) | |
download | txr-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.c | 15 |
1 files changed, 9 insertions, 6 deletions
@@ -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)); } |