diff --git a/CHANGELOG.md b/CHANGELOG.md index cb51f777..2e9d9726 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ The git repositories are hosted at the following sites: ### Security ### Added + +* Added library specific string-to functions similar to stdlib. + Added library specific string-to functions for BACnet primitives. (#1151) + ### Changed * Changed basic object API for units properties to use BACNET_ENGINEERING_UNITS diff --git a/src/bacnet/bacapp.c b/src/bacnet/bacapp.c index 6a92729d..80fc3050 100644 --- a/src/bacnet/bacapp.c +++ b/src/bacnet/bacapp.c @@ -11,7 +11,6 @@ #include #include /* for strtol */ #include /* for isalnum */ -#include #include #if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__) #include @@ -4285,60 +4284,6 @@ parse_weeklyschedule(char *str, BACNET_APPLICATION_DATA_VALUE *value) } #endif -#if defined(BACAPP_SIGNED) || defined(BACAPP_BOOLEAN) -static bool strtol_checked(const char *s, long *out) -{ - char *end; - errno = 0; - *out = strtol(s, &end, 0); - if (end == s) { - /* Conversion was not possible */ - return false; - } - if (errno == ERANGE) { - /* Number too large */ - return false; - } - return true; -} -#endif - -#if defined(BACAPP_UNSIGNED) || defined(BACAPP_ENUMERATED) -static bool strtoul_checked(const char *s, BACNET_UNSIGNED_INTEGER *out) -{ - char *end; - errno = 0; - *out = strtoul(s, &end, 0); - if (end == s) { - /* Conversion was not possible */ - return false; - } - if (errno == ERANGE) { - /* Number too large */ - return false; - } - return true; -} -#endif - -#if defined(BACAPP_REAL) || defined(BACAPP_DOUBLE) -static bool strtod_checked(const char *s, double *out) -{ - char *end; - errno = 0; - *out = strtod(s, &end); - if (end == s) { - /* Conversion was not possible */ - return false; - } - if (errno == ERANGE) { - /* Number too large */ - return false; - } - return true; -} -#endif - #if defined(BACAPP_SCALE) /** * @brief Parse a string into a BACnetScale value @@ -4577,7 +4522,7 @@ bool bacapp_parse_application_data( bacnet_stricmp(argv, "inactive") == 0) { value->type.Boolean = false; } else { - status = strtol_checked(argv, &long_value); + status = bacnet_strtol(argv, &long_value); if (!status) { return false; } @@ -4591,7 +4536,7 @@ bool bacapp_parse_application_data( #endif #if defined(BACAPP_UNSIGNED) case BACNET_APPLICATION_TAG_UNSIGNED_INT: - status = strtoul_checked(argv, &unsigned_long_value); + status = bacnet_string_to_unsigned(argv, &unsigned_long_value); if (!status) { return false; } @@ -4603,7 +4548,7 @@ bool bacapp_parse_application_data( #endif #if defined(BACAPP_SIGNED) case BACNET_APPLICATION_TAG_SIGNED_INT: - status = strtol_checked(argv, &long_value); + status = bacnet_strtol(argv, &long_value); if (!status || long_value > INT32_MAX || long_value < INT32_MIN) { return false; @@ -4613,7 +4558,7 @@ bool bacapp_parse_application_data( #endif #if defined(BACAPP_REAL) case BACNET_APPLICATION_TAG_REAL: - status = strtod_checked(argv, &double_value); + status = bacnet_strtod(argv, &double_value); if (!status) { return false; } @@ -4622,7 +4567,7 @@ bool bacapp_parse_application_data( #endif #if defined(BACAPP_DOUBLE) case BACNET_APPLICATION_TAG_DOUBLE: - status = strtod_checked(argv, &double_value); + status = bacnet_strtod(argv, &double_value); if (!status) { return false; } @@ -4648,7 +4593,7 @@ bool bacapp_parse_application_data( #endif #if defined(BACAPP_ENUMERATED) case BACNET_APPLICATION_TAG_ENUMERATED: - status = strtoul_checked(argv, &unsigned_long_value); + status = bacnet_string_to_unsigned(argv, &unsigned_long_value); if (!status || unsigned_long_value > UINT32_MAX) { return false; } diff --git a/src/bacnet/bacstr.c b/src/bacnet/bacstr.c index b3ed9dd4..e5f9aef0 100644 --- a/src/bacnet/bacstr.c +++ b/src/bacnet/bacstr.c @@ -14,6 +14,7 @@ #include #include #include +#include /* BACnet Stack defines - first */ #include "bacnet/bacdef.h" /* BACnet Stack API */ @@ -1366,3 +1367,411 @@ size_t bacnet_strnlen(const char *str, size_t maxlen) } return (p - str); } + +/** + * @brief Attempt to convert a numeric string into a unsigned long value + * @param str - string to convert + * @param long_value - where to put the converted value + * @return true if converted and value is set + * @return false if not converted and value is not set + */ +bool bacnet_strtoul(const char *str, unsigned long *long_value) +{ + char *endptr; + unsigned long value; + + errno = 0; + value = strtoul(str, &endptr, 0); + if (endptr == str) { + /* Conversion was not possible */ + return false; + } + if (errno == ERANGE) { + /* Conversion is outside the range of representable values + so errno set to [ERANGE] */ + return false; + } + if (*endptr != '\0') { + /* Extra text found */ + return false; + } + if (long_value) { + *long_value = value; + } + + return true; +} + +/** + * @brief Attempt to convert a numeric string into a signed long integer + * @param str - string to convert + * @param long_value - where to put the converted value + * @return true if converted and value is set + * @return false if not converted and value is not set + */ +bool bacnet_strtol(const char *str, long *long_value) +{ + char *endptr; + long value; + + errno = 0; + value = strtol(str, &endptr, 0); + if (endptr == str) { + /* No digits found */ + return false; + } + if (errno == ERANGE) { + /* Conversion is outside the range of representable values + so errno set to [ERANGE] */ + return false; + } + if (*endptr != '\0') { + /* Extra text found */ + return false; + } + if (long_value) { + *long_value = value; + } + + return true; +} + +/** + * @brief Attempt to convert a numeric string into a finite floating point value + * @param str - string to convert + * @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 + */ +bool bacnet_strtof(const char *str, float *float_value) +{ + char *endptr; + float value; + + errno = 0; + value = strtof(str, &endptr); + if (endptr == str) { + /* No digits found */ + return false; + } + if (errno == ERANGE) { + /* Conversion is outside the range of representable values + so errno set to [ERANGE] */ + return false; + } + if (*endptr != '\0') { + /* Extra text found */ + return false; + } + if (float_value) { + *float_value = value; + } + + return true; +} + +/** + * @brief Attempt to convert a numeric string into a finite double precision + * floating point value + * @param str - string to convert + * @param 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 + */ +bool bacnet_strtod(const char *str, double *double_value) +{ + char *endptr; + double value; + + errno = 0; + value = strtod(str, &endptr); + if (endptr == str) { + /* No digits found */ + return false; + } + if (errno == ERANGE) { + /* Conversion is outside the range of representable values + so errno set to [ERANGE] */ + return false; + } + if (*endptr != '\0') { + /* Extra text found */ + return false; + } + if (double_value) { + *double_value = value; + } + + return true; +} + +/** + * @brief Attempt to convert a numeric string into a finite double precision + * floating point value + * @param str - string to convert + * @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 + */ +bool bacnet_strtold(const char *str, long double *long_double_value) +{ + char *endptr; + long double value; + + errno = 0; + value = strtold(str, &endptr); + if (endptr == str) { + /* No digits found */ + return false; + } + if (errno == ERANGE) { + /* Conversion is outside the range of representable values + so errno set to [ERANGE] */ + return false; + } + if (*endptr != '\0') { + /* Extra text found */ + return false; + } + if (long_double_value) { + *long_double_value = value; + } + + return true; +} + +/** + * @brief Attempt to convert a numeric string into a uint8_t value + * @param str - string to convert + * @param uint32_value - where to put the converted value + * @return true if converted and value is set + * @return false if not converted and value is not set + */ +bool bacnet_string_to_uint8(const char *str, uint8_t *uint8_value) +{ + char *endptr; + unsigned long value; + + errno = 0; + value = strtoul(str, &endptr, 0); + if (endptr == str) { + /* No digits found */ + return false; + } + if (errno == ERANGE) { + /* Conversion is outside the range of representable values + so errno set to [ERANGE] */ + return false; + } + if (value > UINT8_MAX) { + /* If the value is outside the range of this datatype */ + return false; + } + if (*endptr != '\0') { + /* Extra text found */ + return false; + } + if (uint8_value) { + *uint8_value = (uint8_t)value; + } + + return true; +} + +/** + * @brief Attempt to convert a numeric string into a uint16_t value + * @param str - string to convert + * @param uint32_value - where to put the converted value + * @return true if converted and value is set + * @return false if not converted and value is not set + */ +bool bacnet_string_to_uint16(const char *str, uint16_t *uint16_value) +{ + char *endptr; + unsigned long value; + + errno = 0; + value = strtoul(str, &endptr, 0); + if (endptr == str) { + /* No digits found */ + return false; + } + if (errno == ERANGE) { + /* Conversion is outside the range of representable values + so errno set to [ERANGE] */ + return false; + } + if (value > UINT16_MAX) { + /* If the value is outside the range of this datatype */ + return false; + } + if (*endptr != '\0') { + /* Extra text found */ + return false; + } + if (uint16_value) { + *uint16_value = (uint16_t)value; + } + + return true; +} + +/** + * @brief Attempt to convert a numeric string into a uint32_t value + * @param str - string to convert + * @param uint32_value - where to put the converted value + * @return true if converted and value is set + * @return false if not converted and value is not set + */ +bool bacnet_string_to_uint32(const char *str, uint32_t *uint32_value) +{ + char *endptr; + unsigned long value; + + errno = 0; + value = strtoul(str, &endptr, 0); + if (endptr == str) { + /* No digits found */ + return false; + } + if (errno == ERANGE) { + /* Conversion is outside the range of representable values + so errno set to [ERANGE] */ + return false; + } + if (value > UINT32_MAX) { + /* If the value is outside the range of this datatype */ + return false; + } + if (*endptr != '\0') { + /* Extra text found */ + return false; + } + if (uint32_value) { + *uint32_value = (uint32_t)value; + } + + return true; +} + +/** + * @brief Attempt to convert a numeric string into an int32_t value + * @param str - string to convert + * @param int32_value - where to put the converted value + * @return true if converted and value is set + * @return false if not converted and value is not set + */ +bool bacnet_string_to_int32(const char *str, int32_t *int32_value) +{ + char *endptr; + long value; + + errno = 0; + value = strtol(str, &endptr, 0); + if (endptr == str) { + /* No digits found */ + return false; + } + if (errno == ERANGE) { + /* Conversion is outside the range of representable values + so errno set to [ERANGE] */ + return false; + } + if (value < INT32_MIN || value > INT32_MAX) { + /* The correct value is outside the range of this data type */ + return false; + } + if (*endptr != '\0') { + /* Extra text found */ + return false; + } + if (int32_value) { + *int32_value = (int32_t)value; + } + return true; +} + +/** + * @brief Attempt to convert a numeric string into an bool value + * @param str - string to convert + * @param bool_value - where to put the converted value + * @return true if converted and value is set + * @return false if not converted and value is not set + */ +bool bacnet_string_to_bool(const char *str, bool *bool_value) +{ + bool status = false; + long long_value = 0; + + if (bacnet_stricmp(str, "true") == 0 || + bacnet_stricmp(str, "active") == 0) { + status = true; + if (bool_value) { + *bool_value = true; + } + } else if ( + bacnet_stricmp(str, "false") == 0 || + bacnet_stricmp(str, "inactive") == 0) { + status = true; + if (bool_value) { + *bool_value = false; + } + } else { + status = bacnet_strtol(str, &long_value); + if (!status) { + return false; + } + if (bool_value) { + if (long_value) { + *bool_value = true; + } else { + *bool_value = false; + } + } + } + + return status; +} + +/** + * @brief Attempt to convert a numeric string into a unsigned long value + * @param str - string to convert + * @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 + */ +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; + } + if (errno == ERANGE) { + /* Conversion is outside the range of representable values + so errno set to [ERANGE] */ + return false; + } + if (*endptr != '\0') { + /* Extra text found */ + return false; + } + if (unsigned_int) { + *unsigned_int = (BACNET_UNSIGNED_INTEGER)value; + } + + return true; +} diff --git a/src/bacnet/bacstr.h b/src/bacnet/bacstr.h index 30592205..9888be8c 100644 --- a/src/bacnet/bacstr.h +++ b/src/bacnet/bacstr.h @@ -176,9 +176,35 @@ BACNET_STACK_EXPORT int bacnet_stricmp(const char *a, const char *b); BACNET_STACK_EXPORT int bacnet_strnicmp(const char *a, const char *b, size_t length); + BACNET_STACK_EXPORT size_t bacnet_strnlen(const char *str, size_t maxlen); +BACNET_STACK_EXPORT +bool bacnet_strtoul(const char *str, unsigned long *long_value); +BACNET_STACK_EXPORT +bool bacnet_strtol(const char *str, long *long_value); +BACNET_STACK_EXPORT +bool bacnet_strtof(const char *str, float *float_value); +BACNET_STACK_EXPORT +bool bacnet_strtod(const char *str, double *double_value); +BACNET_STACK_EXPORT +bool bacnet_strtold(const char *str, long double *long_double_value); + +BACNET_STACK_EXPORT +bool bacnet_string_to_uint8(const char *str, uint8_t *uint8_value); +BACNET_STACK_EXPORT +bool bacnet_string_to_uint16(const char *str, uint16_t *uint16_value); +BACNET_STACK_EXPORT +bool bacnet_string_to_uint32(const char *str, uint32_t *uint32_value); +BACNET_STACK_EXPORT +bool bacnet_string_to_int32(const char *str, int32_t *int32_value); +BACNET_STACK_EXPORT +bool bacnet_string_to_bool(const char *str, bool *bool_value); +BACNET_STACK_EXPORT +bool bacnet_string_to_unsigned( + const char *str, BACNET_UNSIGNED_INTEGER *unsigned_int); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/bacnet/bactext.c b/src/bacnet/bactext.c index 9d296dc4..b39ad9f9 100644 --- a/src/bacnet/bactext.c +++ b/src/bacnet/bactext.c @@ -9,52 +9,22 @@ #include #include "bacnet/indtext.h" #include "bacnet/bacenum.h" +#include "bacnet/bacstr.h" #include "bacnet/bactext.h" static const char *ASHRAE_Reserved_String = "Reserved for Use by ASHRAE"; static const char *Vendor_Proprietary_String = "Vendor Proprietary Value"; -/** - * @brief Attempt to convert a numeric string into a uint32_t value - * @param search_name - string to convert - * @param found_index - where to put the converted value - * @return true if converted and found_index is set - * @return false if not converted and found_index is not set - */ -bool bactext_strtoul(const char *search_name, uint32_t *found_index) -{ - char *endptr; - unsigned long value; - - value = strtoul(search_name, &endptr, 0); - if (endptr == search_name) { - /* No digits found */ - return false; - } - if (value == ULONG_MAX) { - /* If the correct value is outside the range of representable values, - {ULONG_MAX} shall be returned */ - return false; - } - if (*endptr != '\0') { - /* Extra text found */ - return false; - } - *found_index = (uint32_t)value; - - return true; -} - /* Search for a text value first based on the corresponding text list, then by * attempting to convert to an integer value. */ -static bool bactext_strtoul_index( +static bool bactext_string_to_uint32_index( INDTEXT_DATA *istring, const char *search_name, uint32_t *found_index) { if (indtext_by_istring(istring, search_name, found_index) == true) { return true; } - return bactext_strtoul(search_name, found_index); + return bacnet_string_to_uint32(search_name, found_index); } INDTEXT_DATA bacnet_confirmed_service_names[] = { @@ -364,7 +334,7 @@ bool bactext_object_type_index(const char *search_name, uint32_t *found_index) bool bactext_object_type_strtol(const char *search_name, uint32_t *found_index) { - return bactext_strtoul_index( + return bactext_string_to_uint32_index( bacnet_object_type_names, search_name, found_index); } @@ -963,7 +933,7 @@ bool bactext_property_index(const char *search_name, uint32_t *found_index) bool bactext_property_strtol(const char *search_name, uint32_t *found_index) { - return bactext_strtoul_index( + return bactext_string_to_uint32_index( bacnet_property_names, search_name, found_index); } @@ -1885,6 +1855,12 @@ bool bactext_notify_type_index(const char *search_name, uint32_t *found_index) bacnet_notify_type_names, search_name, found_index); } +bool bactext_notify_type_strtol(const char *search_name, uint32_t *found_index) +{ + return bactext_string_to_uint32_index( + bacnet_notify_type_names, search_name, found_index); +} + INDTEXT_DATA bacnet_event_transition_names[] = { { TRANSITION_TO_OFFNORMAL, "offnormal" }, { TRANSITION_TO_NORMAL, "normal" }, @@ -1929,7 +1905,7 @@ bool bactext_event_state_index(const char *search_name, uint32_t *found_index) bool bactext_event_state_strtol(const char *search_name, uint32_t *found_index) { - return bactext_strtoul_index( + return bactext_string_to_uint32_index( bacnet_event_state_names, search_name, found_index); } @@ -1970,6 +1946,12 @@ bool bactext_event_type_index(const char *search_name, uint32_t *found_index) bacnet_event_type_names, search_name, found_index); } +bool bactext_event_type_strtol(const char *search_name, uint32_t *found_index) +{ + return bactext_string_to_uint32_index( + bacnet_event_type_names, search_name, found_index); +} + INDTEXT_DATA bacnet_binary_present_value_names[] = { { BINARY_INACTIVE, "inactive" }, { BINARY_ACTIVE, "active" }, { 0, NULL } }; @@ -2339,7 +2321,7 @@ const char *bactext_lighting_operation_name(uint32_t index) bool bactext_lighting_operation_strtol( const char *search_name, uint32_t *found_index) { - return bactext_strtoul_index( + return bactext_string_to_uint32_index( bacnet_lighting_operation_names, search_name, found_index); } @@ -2369,7 +2351,7 @@ const char *bactext_binary_lighting_pv_name(uint32_t index) bool bactext_binary_lighting_pv_names_strtol( const char *search_name, uint32_t *found_index) { - return bactext_strtoul_index( + return bactext_string_to_uint32_index( bacnet_binary_lighting_pv_names, search_name, found_index); } @@ -2782,23 +2764,23 @@ bool bactext_object_property_strtoul( switch (object_property) { case PROP_PROPERTY_LIST: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bacnet_property_names, search_name, found_index); break; case PROP_OBJECT_TYPE: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bacnet_object_type_names, search_name, found_index); break; case PROP_EVENT_STATE: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bacnet_event_state_names, search_name, found_index); break; case PROP_UNITS: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bacnet_engineering_unit_names, search_name, found_index); break; case PROP_POLARITY: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bacnet_binary_polarity_names, search_name, found_index); break; case PROP_PRESENT_VALUE: @@ -2807,12 +2789,12 @@ bool bactext_object_property_strtoul( case OBJECT_BINARY_INPUT: case OBJECT_BINARY_OUTPUT: case OBJECT_BINARY_VALUE: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bacnet_binary_present_value_names, search_name, found_index); break; case OBJECT_BINARY_LIGHTING_OUTPUT: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bacnet_binary_lighting_pv_names, search_name, found_index); break; @@ -2821,47 +2803,47 @@ bool bactext_object_property_strtoul( } break; case PROP_RELIABILITY: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bacnet_reliability_names, search_name, found_index); break; case PROP_SYSTEM_STATUS: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bacnet_device_status_names, search_name, found_index); break; case PROP_SEGMENTATION_SUPPORTED: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bacnet_segmentation_names, search_name, found_index); break; case PROP_NODE_TYPE: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bacnet_node_type_names, search_name, found_index); break; case PROP_TRANSITION: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bacnet_lighting_transition_names, search_name, found_index); break; case PROP_IN_PROGRESS: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bacnet_lighting_in_progress_names, search_name, found_index); break; case PROP_LOGGING_TYPE: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bactext_logging_type_names, search_name, found_index); break; case PROP_MODE: case PROP_ACCEPTED_MODES: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bactext_life_safety_mode_names, search_name, found_index); break; case PROP_OPERATION_EXPECTED: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bactext_life_safety_operation_names, search_name, found_index); break; case PROP_TRACKING_VALUE: switch (object_type) { case OBJECT_LIFE_SAFETY_POINT: case OBJECT_LIFE_SAFETY_ZONE: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bactext_life_safety_state_names, search_name, found_index); break; @@ -2870,47 +2852,47 @@ bool bactext_object_property_strtoul( } break; case PROP_PROGRAM_CHANGE: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bactext_program_request_names, search_name, found_index); break; case PROP_PROGRAM_STATE: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bactext_program_state_names, search_name, found_index); break; case PROP_REASON_FOR_HALT: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bactext_program_error_names, search_name, found_index); break; case PROP_NETWORK_NUMBER_QUALITY: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bactext_network_number_quality_names, search_name, found_index); break; case PROP_NETWORK_TYPE: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bactext_network_port_type_names, search_name, found_index); break; case PROP_PROTOCOL_LEVEL: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bactext_protocol_level_names, search_name, found_index); break; case PROP_EVENT_TYPE: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bacnet_event_type_names, search_name, found_index); break; case PROP_NOTIFY_TYPE: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bacnet_notify_type_names, search_name, found_index); break; case PROP_TIMER_STATE: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bactext_timer_state_names, search_name, found_index); break; case PROP_LAST_STATE_CHANGE: - status = bactext_strtoul_index( + status = bactext_string_to_uint32_index( bactext_timer_transition_names, search_name, found_index); break; default: - status = bactext_strtoul(search_name, found_index); + status = bacnet_string_to_uint32(search_name, found_index); break; } diff --git a/src/bacnet/bactext.h b/src/bacnet/bactext.h index daa22ca4..82467c19 100644 --- a/src/bacnet/bactext.h +++ b/src/bacnet/bactext.h @@ -80,6 +80,8 @@ const char *bactext_notify_type_name(uint32_t index); BACNET_STACK_EXPORT bool bactext_notify_type_index(const char *search_name, uint32_t *found_index); BACNET_STACK_EXPORT +bool bactext_notify_type_strtol(const char *search_name, uint32_t *found_index); +BACNET_STACK_EXPORT const char *bactext_event_state_name(uint32_t index); BACNET_STACK_EXPORT bool bactext_event_state_index(const char *search_name, uint32_t *found_index); @@ -90,6 +92,8 @@ const char *bactext_event_type_name(uint32_t index); BACNET_STACK_EXPORT bool bactext_event_type_index(const char *search_name, uint32_t *found_index); BACNET_STACK_EXPORT +bool bactext_event_type_strtol(const char *search_name, uint32_t *found_index); +BACNET_STACK_EXPORT const char *bactext_binary_present_value_name(uint32_t index); BACNET_STACK_EXPORT const char *bactext_binary_polarity_name(uint32_t index); @@ -205,8 +209,6 @@ const char *bactext_timer_transition_name(uint32_t index); BACNET_STACK_EXPORT const char *bactext_timer_state_name(uint32_t index); -BACNET_STACK_EXPORT -bool bactext_strtoul(const char *search_name, uint32_t *found_index); BACNET_STACK_EXPORT bool bactext_object_property_strtoul( BACNET_OBJECT_TYPE object_type, diff --git a/src/bacnet/datalink/bvlc.c b/src/bacnet/datalink/bvlc.c index 28bb9d7e..151fd0b6 100644 --- a/src/bacnet/datalink/bvlc.c +++ b/src/bacnet/datalink/bvlc.c @@ -2474,10 +2474,11 @@ bool bvlc_address_port_from_ascii( unsigned long port = 0; if (bvlc_address_from_ascii(addr, addrstr)) { - port = strtoul(portstr, NULL, 0); - if (port <= UINT16_MAX) { - addr->port = port; - status = true; + if (bacnet_strtoul(portstr, &port)) { + if (port <= UINT16_MAX) { + addr->port = (uint16_t)port; + status = true; + } } }