exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit 32e1bb04f13ad9e19df9eb34cd86380ae56e51ae
parent 5666f7a3efab6a04b328c0d7356b00b6b2194e53
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu, 29 Oct 2026 19:46:24 +0100

avoid isalnum() to prevent locale-dependence

Diffstat:
Msrc/util/test_slug.c | 7+++++++
Msrc/util/util.c | 25+++++++++++++++++++++++--
2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/src/util/test_slug.c b/src/util/test_slug.c @@ -50,6 +50,11 @@ check_slug (void) {"a#b", false}, {"a&b", false}, {"a@b", false}, + /* Bytes >= 0x80 are rejected whatever the locale says about them: + "\u00e4" in UTF-8, and the same two bytes are each a letter in + ISO-8859-1. */ + {"a\xc3\xa4b", false}, + {"\xe4", false}, }; unsigned int failed = 0; @@ -98,6 +103,8 @@ check_session_id (void) {"a#b", false}, {"a&b", false}, {"a@b", false}, + {"a\xc3\xa4b", false}, + {"\xe4", false}, }; unsigned int failed = 0; diff --git a/src/util/util.c b/src/util/util.c @@ -474,6 +474,27 @@ TALER_words_destroy (char **args) } +/** + * Is @a c an ASCII letter or digit? + * + * Deliberately not isalnum(): that function is locale-dependent, and + * GNUNET_PROGRAM_run() calls setlocale(LC_ALL, "") when NLS is enabled. + * Under a single-byte non-ASCII locale (ISO-8859-x) isalnum() accepts + * bytes >= 0x80, which would make the slug and session ID character sets + * depend on the environment the service happens to run in. + * + * @param c character to test + * @return true if @a c is in [A-Za-z0-9] + */ +static bool +is_ascii_alnum (unsigned char c) +{ + return ( ( ('a' <= c) && ('z' >= c) ) || + ( ('A' <= c) && ('Z' >= c) ) || + ( ('0' <= c) && ('9' >= c) ) ); +} + + bool TALER_is_slug (const char *slug) { @@ -491,7 +512,7 @@ TALER_is_slug (const char *slug) { unsigned char c = *p; - if (isalnum (c)) + if (is_ascii_alnum (c)) continue; switch (c) @@ -534,7 +555,7 @@ TALER_is_session_id (const char *session_id) { unsigned char c = *p; - if (isalnum (c)) + if (is_ascii_alnum (c)) continue; switch (c)