aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2024-11-22 17:47:51 +0300
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2024-11-23 02:41:42 +0300
commita61a81ec33188e8e93ec02912c60053107ae0485 (patch)
treea67fd9d37f434f1c169a05b2d6088a68fe34a798
parent1cfe37610253c20a4fcb0d937c29e70894ecc4f5 (diff)
downloadsciteco-a61a81ec33188e8e93ec02912c60053107ae0485.tar.gz
disallow setting the radix to values lower than 2
* This would actually causes crashes when trying to format numbers. * The ^R local register has a custom set_integer() method now, so that the check is performed also when using nU.^X.
-rw-r--r--src/core-commands.c7
-rw-r--r--src/qreg.c29
-rw-r--r--tests/testsuite.at6
3 files changed, 34 insertions, 8 deletions
diff --git a/src/core-commands.c b/src/core-commands.c
index ba7aaa8..fa2f8b5 100644
--- a/src/core-commands.c
+++ b/src/core-commands.c
@@ -1741,7 +1741,7 @@ teco_state_control_decimal(teco_machine_main_t *ctx, GError **error)
* radix^R -- Set and get radix
* ^R -> radix
*
- * Set current radix to arbitrary value <radix>.
+ * Set current radix to any value <radix> larger than or equal to 2.
* If <radix> is omitted, the command instead
* returns the current radix.
*
@@ -1764,11 +1764,6 @@ teco_state_control_radix(teco_machine_main_t *ctx, GError **error)
return;
teco_expressions_push(radix);
} else {
- /*
- * FIXME: We should restrict the allowed values.
- * 0^R 23\ crashes for instance.
- * The ^R register should consequently also be "special".
- */
if (!teco_expressions_pop_num_calc(&radix, 0, error) ||
!qreg->vtable->undo_set_integer(qreg, error) ||
!qreg->vtable->set_integer(qreg, radix, error))
diff --git a/src/qreg.c b/src/qreg.c
index 2c5d4a5..1ce727f 100644
--- a/src/qreg.c
+++ b/src/qreg.c
@@ -399,6 +399,32 @@ teco_qreg_plain_new(const gchar *name, gsize len)
}
static gboolean
+teco_qreg_radix_set_integer(teco_qreg_t *qreg, teco_int_t value, GError **error)
+{
+ if (value < 2) {
+ g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED,
+ "Invalid radix");
+ return FALSE;
+ }
+
+ qreg->integer = value;
+ return TRUE;
+}
+
+/** @static @memberof teco_qreg_t */
+static teco_qreg_t *
+teco_qreg_radix_new(void)
+{
+ static teco_qreg_vtable_t vtable = TECO_INIT_QREG(
+ .set_integer = teco_qreg_radix_set_integer
+ );
+
+ teco_qreg_t *qreg = teco_qreg_new(&vtable, "\x12", 1); /* ^R */
+ qreg->integer = 10;
+ return qreg;
+}
+
+static gboolean
teco_qreg_external_edit(teco_qreg_t *qreg, GError **error)
{
g_auto(teco_string_t) str = {NULL, 0};
@@ -913,8 +939,7 @@ teco_qreg_table_init_locals(teco_qreg_table_t *table, gboolean must_undo)
/* search mode ("^X") */
teco_qreg_table_insert(table, teco_qreg_plain_new("\x18", 1));
/* numeric radix ("^R") */
- table->radix = teco_qreg_plain_new("\x12", 1);
- table->radix->vtable->set_integer(table->radix, 10, NULL);
+ table->radix = teco_qreg_radix_new();
teco_qreg_table_insert(table, table->radix);
}
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 22f14e2..31ce257 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -33,6 +33,12 @@ AT_CHECK([$SCITECO -e "(1,) \"~|(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "1,(2)=="], 0, ignore, ignore)
AT_CLEANUP
+AT_SETUP([Radix])
+AT_CHECK([$SCITECO -e "0^R"], 1, ignore, ignore)
+AT_CHECK([$SCITECO -e "0U.^R"], 1, ignore, ignore)
+AT_CHECK([$SCITECO -e "23 (2^R)\^D .-5\"N(0/0)"], 0, ignore, ignore)
+AT_CLEANUP
+
AT_SETUP([Exponentiation])
AT_CHECK([$SCITECO -e "-1^*0 - (-1)\"N(0/0)'"], 0, ignore, ignore)
AT_CHECK([$SCITECO -e "-1^*-5 - (-1)\"N(0/0)'"], 0, ignore, ignore)