diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2020-04-07 21:37:48 +0200 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2020-04-07 21:37:48 +0200 |
commit | d78ac827e94a8c8ebedfea296e7447aa85c87fb5 (patch) | |
tree | e17214199941e40f21813ce91c14b8f4a1a33d1c /tests | |
parent | e998417f5c02f26d47384306ba04fb6bbb2c6abd (diff) | |
download | weechat-d78ac827e94a8c8ebedfea296e7447aa85c87fb5.zip |
core: fix memory leak in calculation of expression on FreeBSD (closes #1469)
The memory leak was caused by a bug in function setlocale on FreeBSD:
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=243195
The fix is the following:
* Remove the calls to setlocale when formatting the result.
* The function snprintf is still called, and then is now locale dependent,
for example in French the decimal separator is a comma instead of a dot.
* A new function calc_sanitize_decimal_number is introduced to "sanitize" a
decimal number: keep only the decimal separator (replace it by a dot) and
remove any other separator found.
Unit tests are added on these functions:
* calc_sanitize_decimal_number
* calc_format_result
Diffstat (limited to 'tests')
-rw-r--r-- | tests/unit/core/test-core-calc.cpp | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/tests/unit/core/test-core-calc.cpp b/tests/unit/core/test-core-calc.cpp index 53f5beaca..d50a43aa9 100644 --- a/tests/unit/core/test-core-calc.cpp +++ b/tests/unit/core/test-core-calc.cpp @@ -24,8 +24,21 @@ extern "C" { #include "src/core/wee-calc.h" + +extern int calc_sanitize_decimal_number (char *string); +extern void calc_format_result (double value, char *result, int max_size); } +#define WEE_CHECK_SANITIZE_DECIMAL_NUMBER(__result, __result_string, \ + __number) \ + snprintf (str_number, sizeof (str_number), "%s", __number); \ + LONGS_EQUAL(__result, calc_sanitize_decimal_number (str_number)); \ + STRCMP_EQUAL(__result_string, str_number); + +#define WEE_CHECK_FORMAT_RESULT(__result, __value) \ + calc_format_result (__value, str_result, sizeof (str_result)); \ + STRCMP_EQUAL(__result, str_result); + #define WEE_CHECK_CALC(__result, __expr) \ value = calc_expression (__expr); \ STRCMP_EQUAL(__result, value); \ @@ -37,6 +50,53 @@ TEST_GROUP(CoreCalc) /* * Tests functions: + * calc_sanitize_decimal_number + */ + +TEST(CoreCalc, SanitizeDecimalNumber) +{ + char str_number[1024]; + + WEE_CHECK_SANITIZE_DECIMAL_NUMBER(0, "0", "0"); + WEE_CHECK_SANITIZE_DECIMAL_NUMBER(1, "0.0", "0.0"); + WEE_CHECK_SANITIZE_DECIMAL_NUMBER(1, "0.0", "0,0"); + WEE_CHECK_SANITIZE_DECIMAL_NUMBER(1, "1.23", "1.23"); + WEE_CHECK_SANITIZE_DECIMAL_NUMBER(1, "1.23", "1,23"); + WEE_CHECK_SANITIZE_DECIMAL_NUMBER(1, "1234.56", "1.234,56"); + WEE_CHECK_SANITIZE_DECIMAL_NUMBER(0, "123456789", "123.456.789"); + WEE_CHECK_SANITIZE_DECIMAL_NUMBER(0, "123456789", "123,456,789"); + WEE_CHECK_SANITIZE_DECIMAL_NUMBER(1, "1234567.89", "1.234.567,89"); + WEE_CHECK_SANITIZE_DECIMAL_NUMBER(1, "1234567.89", "1,234,567.89"); + WEE_CHECK_SANITIZE_DECIMAL_NUMBER(1, "-2345.67", "-2.345,67"); +} + +/* + * Tests functions: + * calc_format_result + */ + +TEST(CoreCalc, FormatResult) +{ + char str_result[64]; + + WEE_CHECK_FORMAT_RESULT("0", 0); + WEE_CHECK_FORMAT_RESULT("0", 0.0); + WEE_CHECK_FORMAT_RESULT("0", -0.0); + WEE_CHECK_FORMAT_RESULT("12.5", 12.5); + WEE_CHECK_FORMAT_RESULT("12.005", 12.005000); + WEE_CHECK_FORMAT_RESULT("-12.005", -12.005000); + WEE_CHECK_FORMAT_RESULT("0.0000000001", 0.0000000001); + WEE_CHECK_FORMAT_RESULT("0", 0.00000000001); + WEE_CHECK_FORMAT_RESULT("123456789012345", 123456789012345); + + setlocale (LC_ALL, "fr_FR.UTF-8"); + WEE_CHECK_FORMAT_RESULT("12.5", 12.5); + WEE_CHECK_FORMAT_RESULT("-12.5", -12.5); + setlocale (LC_ALL, ""); +} + +/* + * Tests functions: * calc_expression */ @@ -146,4 +206,10 @@ TEST(CoreCalc, Expression) WEE_CHECK_CALC("21", "(5+2)*3"); WEE_CHECK_CALC("3.15", "(1.5+2)*(1.8/2)"); WEE_CHECK_CALC("-1.26", "(1.5+2)*(1.8/(2-7))"); + + /* with French locale: the result must always have "." instead of "," */ + setlocale (LC_ALL, "fr_FR.UTF-8"); + WEE_CHECK_CALC("12.5", "10.5+2"); + WEE_CHECK_CALC("-12.5", "-10.5-2"); + setlocale (LC_ALL, ""); } |