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;
|
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
|
* 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
|
BACNET_STACK_EXPORT
|
||||||
size_t characterstring_length(const BACNET_CHARACTER_STRING *char_string);
|
size_t characterstring_length(const BACNET_CHARACTER_STRING *char_string);
|
||||||
BACNET_STACK_EXPORT
|
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);
|
uint8_t characterstring_encoding(const BACNET_CHARACTER_STRING *char_string);
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
size_t characterstring_capacity(const BACNET_CHARACTER_STRING *char_string);
|
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
|
is absent or if the password is incorrect. For those devices that
|
||||||
do not require a password, this parameter shall be ignored.*/
|
do not require a password, this parameter shall be ignored.*/
|
||||||
if (Reinit_Password && strlen(Reinit_Password) > 0) {
|
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_class = ERROR_CLASS_SERVICES;
|
||||||
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
rd_data->error_code = ERROR_CODE_PARAMETER_OUT_OF_RANGE;
|
||||||
} else if (characterstring_ansi_same(
|
} else if (characterstring_ansi_same(
|
||||||
|
|||||||
@@ -24,7 +24,13 @@
|
|||||||
#include "bacnet/basic/services.h"
|
#include "bacnet/basic/services.h"
|
||||||
#include "bacnet/datalink/datalink.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.
|
/** 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.
|
* @param new_password [in] The new DCC password, of up to 31 characters.
|
||||||
|
|||||||
+5
-2
@@ -8,9 +8,11 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
/* BACnet Stack defines - first */
|
/* BACnet Stack defines - first */
|
||||||
#include "bacnet/bacdef.h"
|
#include "bacnet/bacdef.h"
|
||||||
|
#include "bacnet/bacstr.h"
|
||||||
/* BACnet Stack API */
|
/* BACnet Stack API */
|
||||||
#include "bacnet/bacdcode.h"
|
#include "bacnet/bacdcode.h"
|
||||||
#include "bacnet/dcc.h"
|
#include "bacnet/dcc.h"
|
||||||
|
/** @file dcc.c Enable/Disable Device Communication Control (DCC) */
|
||||||
|
|
||||||
/* note: the disable and time are not expected to survive
|
/* note: the disable and time are not expected to survive
|
||||||
over a power cycle or reinitialization. */
|
over a power cycle or reinitialization. */
|
||||||
@@ -267,7 +269,6 @@ int dcc_decode_service_request(
|
|||||||
uint32_t len_value_type = 0;
|
uint32_t len_value_type = 0;
|
||||||
BACNET_UNSIGNED_INTEGER decoded_unsigned = 0;
|
BACNET_UNSIGNED_INTEGER decoded_unsigned = 0;
|
||||||
uint32_t decoded_enum = 0;
|
uint32_t decoded_enum = 0;
|
||||||
uint32_t password_length = 0;
|
|
||||||
|
|
||||||
if (apdu && apdu_len_max) {
|
if (apdu && apdu_len_max) {
|
||||||
/* Tag 0: timeDuration, in minutes --optional-- */
|
/* Tag 0: timeDuration, in minutes --optional-- */
|
||||||
@@ -321,7 +322,9 @@ int dcc_decode_service_request(
|
|||||||
&apdu[apdu_len], apdu_len_max - apdu_len,
|
&apdu[apdu_len], apdu_len_max - apdu_len,
|
||||||
len_value_type, password);
|
len_value_type, password);
|
||||||
if (len > 0) {
|
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)) {
|
if ((password_length >= 1) && (password_length <= 20)) {
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+2
-1
@@ -51,7 +51,8 @@ int reinitialize_device_encode(
|
|||||||
}
|
}
|
||||||
/* password [1] CharacterString (SIZE (1..20)) OPTIONAL */
|
/* password [1] CharacterString (SIZE (1..20)) OPTIONAL */
|
||||||
if (password) {
|
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);
|
len = encode_context_character_string(apdu, 1, password);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user