diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-03-04 01:10:01 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-03-04 01:10:01 -0800 |
commit | b111bddfcc737b7f4ab854ce823094bcc8a9de48 (patch) | |
tree | fd2fe324b8623a0b803736e2fc8dc30e32ba174b /lib.h | |
parent | cf126a147c108497ef8a387dc869a4c24a9622ed (diff) | |
download | txr-b111bddfcc737b7f4ab854ce823094bcc8a9de48.tar.gz txr-b111bddfcc737b7f4ab854ce823094bcc8a9de48.tar.bz2 txr-b111bddfcc737b7f4ab854ce823094bcc8a9de48.zip |
lib: defend against locale-specific wcstod.
The wcstod function has locale-specific behavior. It uses a
locale-specific decimal separator character, which may not be
the period. Though in TXR we never call setlocale in order to
activate localization, it is a good idea to put in code to
defend against this. If locale is ever unleashed on the code,
it really botches our floating-point handling. However, let's
keep that defensive logic disabled for now using the
preprocessor.
The strategy is to inquire about the locale's decimal
character at startup. Then, in the flo_str function, we
preprocess the input by converting the decimal period to
the locale-specific character before calling wcstod. On the
output side, we also deal with it in the format function; we
call sprintf, and then convert the locale-specific characer
to period.
I tested all this by temporarily introducing the setlocale
call, and switching to a locale with a comma as the separator,
geting make tests to pass, and doing some interactive testing.
This is not going to receive coverage in the test suite.
* lib.c (dec_point): New global variable.
(flo_str): If dec_point isn't '.', we must copy the
string into a local buffer, which we get from alloca, and
edit any '.' that it contains to dec_point.
(locale_init): New function; initializes dec_point.
(init): Call locale_init.
* lib.h (dec_point): Declared.
* stream.c (formatv): Don't look for a '.' in the result of
printing a double using %e; look for dec_point. Post-process
floating-point sprinf by substituting occurrences of dec_point
with the period.
Diffstat (limited to 'lib.h')
-rw-r--r-- | lib.h | 2 |
1 files changed, 2 insertions, 0 deletions
@@ -538,6 +538,8 @@ extern val list_f, less_f, greater_f; extern val prog_string; +extern char dec_point; + #if HAVE_ULONGLONG_T typedef ulonglong_t alloc_bytes_t; #define SIZEOF_ALLOC_BYTES_T SIZEOF_LONGLONG_T |