Fixed UTF-8 passwords for DeviceCommunicationControl to hold up to 20 UTF-8 characters (#767)
This commit is contained in:
committed by
GitHub
parent
b9adcc8097
commit
f4325f00b5
@@ -587,6 +587,29 @@ bool characterstring_ansi_same(
|
||||
return same_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of UTF8 code points in a character string.
|
||||
*
|
||||
* @param dest Pointer to the string to count the UTF8 code points.
|
||||
*
|
||||
* @return Length of the character string in utf8 codepoints
|
||||
*/
|
||||
size_t characterstring_utf8_length(const BACNET_CHARACTER_STRING *str)
|
||||
{
|
||||
size_t count = 0;
|
||||
int i = 0;
|
||||
|
||||
while ((i < MAX_CHARACTER_STRING_BYTES) && (str->value[i] != '\0')) {
|
||||
if ((str->value[i] & 0xc0) != 0x80) {
|
||||
count++;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append some characters to the end of the characterstring
|
||||
*
|
||||
|
||||
@@ -118,6 +118,8 @@ const char *characterstring_value(const BACNET_CHARACTER_STRING *char_string);
|
||||
BACNET_STACK_EXPORT
|
||||
size_t characterstring_length(const BACNET_CHARACTER_STRING *char_string);
|
||||
BACNET_STACK_EXPORT
|
||||
size_t characterstring_utf8_length(const BACNET_CHARACTER_STRING *str);
|
||||
BACNET_STACK_EXPORT
|
||||
uint8_t characterstring_encoding(const BACNET_CHARACTER_STRING *char_string);
|
||||
BACNET_STACK_EXPORT
|
||||
size_t characterstring_capacity(const BACNET_CHARACTER_STRING *char_string);
|
||||
|
||||
@@ -667,7 +667,7 @@ bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
|
||||
is absent or if the password is incorrect. For those devices that
|
||||
do not require a password, this parameter shall be ignored.*/
|
||||
if (Reinit_Password && strlen(Reinit_Password) > 0) {
|
||||
if (characterstring_length(&rd_data->password) > 20) {
|
||||
if (characterstring_utf8_length(&rd_data->password) > 20) {
|
||||
rd_data->error_class = ERROR_CLASS_SERVICES;
|
||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||
} else if (characterstring_ansi_same(
|
||||
|
||||
@@ -24,7 +24,13 @@
|
||||
#include "bacnet/basic/services.h"
|
||||
#include "bacnet/datalink/datalink.h"
|
||||
|
||||
static char My_Password[32] = "filister";
|
||||
/* The byte length of a UTF-8 character can vary.
|
||||
* In UTF-8, the number of bytes used to represent a character can range from 1
|
||||
* to 4 bytes. Commonly used characters in the ASCII set are represented by 1
|
||||
* byte,xi while other Unicode characters may require 2, 3, or 4 bytes. Let's
|
||||
* add space for the null '\0' termination byte.
|
||||
* */
|
||||
static char My_Password[20 * 4 + 1] = "filister";
|
||||
|
||||
/** Sets (non-volatile hold) the password to be used for DCC requests.
|
||||
* @param new_password [in] The new DCC password, of up to 31 characters.
|
||||
|
||||
+5
-2
@@ -8,9 +8,11 @@
|
||||
#include <stdint.h>
|
||||
/* BACnet Stack defines - first */
|
||||
#include "bacnet/bacdef.h"
|
||||
#include "bacnet/bacstr.h"
|
||||
/* BACnet Stack API */
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/dcc.h"
|
||||
/** @file dcc.c Enable/Disable Device Communication Control (DCC) */
|
||||
|
||||
/* note: the disable and time are not expected to survive
|
||||
over a power cycle or reinitialization. */
|
||||
@@ -267,7 +269,6 @@ int dcc_decode_service_request(
|
||||
uint32_t len_value_type = 0;
|
||||
BACNET_UNSIGNED_INTEGER decoded_unsigned = 0;
|
||||
uint32_t decoded_enum = 0;
|
||||
uint32_t password_length = 0;
|
||||
|
||||
if (apdu && apdu_len_max) {
|
||||
/* Tag 0: timeDuration, in minutes --optional-- */
|
||||
@@ -321,7 +322,9 @@ int dcc_decode_service_request(
|
||||
&apdu[apdu_len], apdu_len_max - apdu_len,
|
||||
len_value_type, password);
|
||||
if (len > 0) {
|
||||
password_length = len_value_type - 1;
|
||||
size_t password_length =
|
||||
characterstring_utf8_length(password);
|
||||
/* UTF-8 code points can be up to 4 bytes long */
|
||||
if ((password_length >= 1) && (password_length <= 20)) {
|
||||
apdu_len += len;
|
||||
} else {
|
||||
|
||||
+2
-1
@@ -51,7 +51,8 @@ int reinitialize_device_encode(
|
||||
}
|
||||
/* password [1] CharacterString (SIZE (1..20)) OPTIONAL */
|
||||
if (password) {
|
||||
if ((password->length >= 1) && (password->length <= 20)) {
|
||||
if ((password->length >= 1) &&
|
||||
(characterstring_utf8_length(password) <= 20)) {
|
||||
len = encode_context_character_string(apdu, 1, password);
|
||||
apdu_len += len;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user