From 81c42566a71d90e0b395c1dba4b6ce8427d0f736 Mon Sep 17 00:00:00 2001 From: Steve Karg Date: Wed, 21 Jan 2026 12:12:06 -0600 Subject: [PATCH] Enhance C89 compatibility by replacing strtof and strtold with strtod in conversion functions (#1207) --- CHANGELOG.md | 5 ++++- src/bacnet/bacstr.c | 29 +++++++++++++++-------------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cbe7f58..9db9d344 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,7 +77,10 @@ The git repositories are hosted at the following sites: ### Changed -* Changed RGB color clamp function to avoid Zephyr RTOS name collisions.(#1201) +* Changed bacnet_strtof and bacnet_strtold functions to use strtod to + improve compatibility with C89 standards while ensuring proper type + casting and range checking. (#1207) +* Changed RGB color clamp function to avoid Zephyr RTOS name collisions. (#1201) * Changed the load control object AbleToMeetShed to only check for immediate shed ability and added CanNowComplyWithShed function to attempt to meet the shed request while in the non-compliant state. (#1191) diff --git a/src/bacnet/bacstr.c b/src/bacnet/bacstr.c index 03c27d5e..74518dda 100644 --- a/src/bacnet/bacstr.c +++ b/src/bacnet/bacstr.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include /* BACnet Stack defines - first */ @@ -1565,14 +1567,15 @@ bool bacnet_strtol(const char *str, long *long_value) * @param float_value - where to put the converted value * @return true if converted and finite value is set * @return false if not converted and finite value is not set + * @note Uses strtod() for C89 compatibility and casts to float */ bool bacnet_strtof(const char *str, float *float_value) { char *endptr; - float value; + double value; errno = 0; - value = strtof(str, &endptr); + value = strtod(str, &endptr); if (endptr == str) { /* No digits found */ return false; @@ -1586,8 +1589,12 @@ bool bacnet_strtof(const char *str, float *float_value) /* Extra text found */ return false; } + if (fabs(value) > FLT_MAX) { + /* Value exceeds float range */ + return false; + } if (float_value) { - *float_value = value; + *float_value = (float)value; } return true; @@ -1635,14 +1642,15 @@ bool bacnet_strtod(const char *str, double *double_value) * @param long_double_value - where to put the converted value * @return true if converted and finite value is set * @return false if not converted and finite value is not set + * @note Uses strtod() for C89 compatibility and casts to long double */ bool bacnet_strtold(const char *str, long double *long_double_value) { char *endptr; - long double value; + double value; errno = 0; - value = strtold(str, &endptr); + value = strtod(str, &endptr); if (endptr == str) { /* No digits found */ return false; @@ -1657,7 +1665,7 @@ bool bacnet_strtold(const char *str, long double *long_double_value) return false; } if (long_double_value) { - *long_double_value = value; + *long_double_value = (long double)value; } return true; @@ -1862,23 +1870,16 @@ bool bacnet_string_to_bool(const char *str, bool *bool_value) * @param unsigned_int - where to put the converted value * @return true if converted and value is set * @return false if not converted and value is not set + * @note the conversion is limited to the strtoul() range for C89 compatibility */ bool bacnet_string_to_unsigned( const char *str, BACNET_UNSIGNED_INTEGER *unsigned_int) { char *endptr; -#ifdef UINT64_MAX - unsigned long long value; -#else unsigned long value; -#endif errno = 0; -#ifdef UINT64_MAX - value = strtoull(str, &endptr, 0); -#else value = strtoul(str, &endptr, 0); -#endif if (endptr == str) { /* No digits found */ return false;