diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2024-11-22 17:47:51 +0300 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2024-11-23 02:41:42 +0300 |
commit | a61a81ec33188e8e93ec02912c60053107ae0485 (patch) | |
tree | a67fd9d37f434f1c169a05b2d6088a68fe34a798 | |
parent | 1cfe37610253c20a4fcb0d937c29e70894ecc4f5 (diff) | |
download | sciteco-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.c | 7 | ||||
-rw-r--r-- | src/qreg.c | 29 | ||||
-rw-r--r-- | tests/testsuite.at | 6 |
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)) @@ -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) |