say.c: Fix cents off-by-one due to floating point rounding.

Some of the money announcements can be off by one cent,
due to the use of floating point in the money calculations,
which is bad for obvious reasons.

This replaces floating point with simple string parsing
to ensure the cents value is converted accurately.

Resolves: #525
This commit is contained in:
Naveen Albert
2024-01-10 08:26:05 -05:00
committed by asterisk-org-access-app[bot]
parent 01ff5c8140
commit 7cffbabe5c
2 changed files with 106 additions and 13 deletions

View File

@@ -356,6 +356,14 @@ AST_TEST_DEFINE(test_SAYFILES_function)
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(.42,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/40&digits/2&cents") != 0) {
ast_test_status_update(test, "SAYFILES(.42,money) test failed ('%s')\n",
ast_str_buffer(result));
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(1.00,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/1&letters/dollar") != 0) {
@@ -380,6 +388,14 @@ AST_TEST_DEFINE(test_SAYFILES_function)
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(2,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/2&dollars") != 0) {
ast_test_status_update(test, "SAYFILES(2,money) test failed ('%s')\n",
ast_str_buffer(result));
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(2.42,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/2&dollars&and&digits/40&digits/2&cents") != 0) {
@@ -388,6 +404,63 @@ AST_TEST_DEFINE(test_SAYFILES_function)
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(2.05,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/2&dollars&and&digits/5&cents") != 0) {
ast_test_status_update(test, "SAYFILES(2.05,money) test failed ('%s')\n",
ast_str_buffer(result));
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(2.051,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/2&dollars&and&digits/5&cents") != 0) {
ast_test_status_update(test, "SAYFILES(2.051,money) test failed ('%s')\n",
ast_str_buffer(result));
res = AST_TEST_FAIL;
}
/* Invalid amounts */
ast_str_set(&expr, 0, "${SAYFILES(blah,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/0&cents") != 0) {
ast_test_status_update(test, "SAYFILES(blah,money) test failed ('%s')\n",
ast_str_buffer(result));
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(2blah.05,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/2&dollars") != 0) {
ast_test_status_update(test, "SAYFILES(2blah.05,money) test failed ('%s')\n",
ast_str_buffer(result));
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(2.-05,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/2&dollars") != 0) {
ast_test_status_update(test, "SAYFILES(2.-05,money) test failed ('%s')\n",
ast_str_buffer(result));
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(2. 05,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/2&dollars") != 0) {
ast_test_status_update(test, "SAYFILES(2. 05,money) test failed ('%s')\n",
ast_str_buffer(result));
res = AST_TEST_FAIL;
}
ast_str_set(&expr, 0, "${SAYFILES(. 05,money)}");
ast_str_substitute_variables(&result, 0, NULL, ast_str_buffer(expr));
if (strcmp(ast_str_buffer(result), "digits/0&cents") != 0) {
ast_test_status_update(test, "SAYFILES(. 05,money) test failed ('%s')\n",
ast_str_buffer(result));
res = AST_TEST_FAIL;
}
ast_free(expr);
ast_free(result);