summaryrefslogtreecommitdiffstats
path: root/arith.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-06-15 22:16:34 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-06-15 23:35:15 -0700
commit40c1dee7647ddb7d4768a2eadf9915ab29e62f59 (patch)
tree0617a1f06b1dea5067def8028c0d71b9dfb653e6 /arith.c
parent79d832988eaa51f564eca913dec112e4df33593e (diff)
downloadtxr-40c1dee7647ddb7d4768a2eadf9915ab29e62f59.tar.gz
txr-40c1dee7647ddb7d4768a2eadf9915ab29e62f59.tar.bz2
txr-40c1dee7647ddb7d4768a2eadf9915ab29e62f59.zip
math: forbid dubious inequality comparisons.
The issue, reported by Paul A. Patience, is that code like (< 1 "abc") is successfully producing a result. The root cause is that 1 is an iterable object, and so is treated as a sequence opposite to the "abc" operand. We should allow only true sequences in this situation. * arith.c (seq_lt_compat_check): New static function. Checks that neither of two sequences is SEQ_NOTSEQ or SEQ_HASHLIKE. (seq_lt, seq_le): Use seq_lt_compat_check to reject dubious inputs. * txr.1: Minor wording change in the related documentation, removing a gratuitous adjective. * tests/016/arith.tl: Inequality tests.
Diffstat (limited to 'arith.c')
-rw-r--r--arith.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/arith.c b/arith.c
index 225d6586..941ed681 100644
--- a/arith.c
+++ b/arith.c
@@ -1884,12 +1884,24 @@ val pppred(val num)
return minus(num, three);
}
+static void seq_lt_compat_check(seq_iter_t *ita, seq_iter_t *itb,
+ val a, val b, val self)
+{
+ if (ita->inf.kind == SEQ_NOTSEQ || ita->inf.kind == SEQ_HASHLIKE ||
+ itb->inf.kind == SEQ_NOTSEQ || itb->inf.kind == SEQ_HASHLIKE)
+ {
+ uw_throwf(error_s, lit("~a: invalid operands ~s ~s"), self, a, b, nao);
+ }
+}
+
static val seq_lt(val self, val aseq, val bseq)
{
seq_iter_t ita, itb;
seq_iter_init(self, &ita, aseq);
seq_iter_init(self, &itb, bseq);
+ seq_lt_compat_check(&ita, &itb, aseq, bseq, self);
+
for (;;) {
val aelem, belem;
switch (seq_peek(&ita, &aelem) << 1 | seq_peek(&itb, &belem)) {
@@ -1919,6 +1931,8 @@ static val seq_le(val self, val aseq, val bseq)
seq_iter_init(self, &ita, aseq);
seq_iter_init(self, &itb, bseq);
+ seq_lt_compat_check(&ita, &itb, aseq, bseq, self);
+
for (;;) {
val aelem, belem;
switch (seq_peek(&ita, &aelem) << 1 | seq_peek(&itb, &belem)) {