Fixed GetEvent initialization of linked list (#1026)

* Fixed GetEvent usage of linked list by initializing next in all the examples and unit test.

* Secured GetEventInformation encoders by accepting NULL for APDU for determining the size, and exploit the NULL APDU for size checking during encoding. Secured the GetEventInformation decoders and removed the use of deprecated decoder API.
This commit is contained in:
Steve Karg
2025-06-20 13:34:39 -05:00
committed by GitHub
parent b0a97c6f75
commit 14f033ceda
7 changed files with 498 additions and 300 deletions
+55 -47
View File
@@ -64,27 +64,25 @@ static int getevent_ack_decode_apdu(
BACNET_GET_EVENT_INFORMATION_DATA *get_event_data,
bool *moreEvents)
{
int len = 0;
int offset = 0;
if (!apdu) {
return -1;
return BACNET_STATUS_ERROR;
}
if (apdu_len < 3) {
return BACNET_STATUS_ERROR; /* too short */
}
/* optional checking - most likely was already done prior to this call */
if (apdu[0] != PDU_TYPE_COMPLEX_ACK) {
return -1;
return BACNET_STATUS_ERROR;
}
if (invoke_id) {
*invoke_id = apdu[1];
}
*invoke_id = apdu[1];
if (apdu[2] != SERVICE_CONFIRMED_GET_EVENT_INFORMATION) {
return -1;
}
offset = 3;
if (apdu_len > offset) {
len = getevent_ack_decode_service_request(
&apdu[offset], apdu_len - offset, get_event_data, moreEvents);
return BACNET_STATUS_ERROR;
}
return len;
return getevent_ack_decode_service_request(
&apdu[3], apdu_len - 3, get_event_data, moreEvents);
}
#if defined(CONFIG_ZTEST_NEW_API)
@@ -94,46 +92,48 @@ static void testGetEventInformationAck(void)
#endif
{
uint8_t apdu[480] = { 0 };
int len = 0;
int apdu_len = 0;
int len = 0, apdu_len = 0, null_len = 0;
uint8_t invoke_id = 1;
uint8_t test_invoke_id = 0;
BACNET_GET_EVENT_INFORMATION_DATA event_data;
BACNET_GET_EVENT_INFORMATION_DATA test_event_data;
BACNET_GET_EVENT_INFORMATION_DATA event_data[1] = { 0 };
BACNET_GET_EVENT_INFORMATION_DATA test_event_data[1] = { 0 };
bool moreEvents = false;
bool test_moreEvents = false;
unsigned i = 0;
event_data.objectIdentifier.type = OBJECT_BINARY_INPUT;
event_data.objectIdentifier.instance = 1;
event_data.eventState = EVENT_STATE_NORMAL;
bitstring_init(&event_data.acknowledgedTransitions);
bitstring_set_bit(
&event_data.acknowledgedTransitions, TRANSITION_TO_OFFNORMAL, false);
bitstring_set_bit(
&event_data.acknowledgedTransitions, TRANSITION_TO_FAULT, false);
bitstring_set_bit(
&event_data.acknowledgedTransitions, TRANSITION_TO_NORMAL, false);
for (i = 0; i < 3; i++) {
event_data.eventTimeStamps[i].tag = TIME_STAMP_SEQUENCE;
event_data.eventTimeStamps[i].value.sequenceNum = 0;
}
event_data.notifyType = NOTIFY_ALARM;
bitstring_init(&event_data.eventEnable);
bitstring_set_bit(&event_data.eventEnable, TRANSITION_TO_OFFNORMAL, true);
bitstring_set_bit(&event_data.eventEnable, TRANSITION_TO_FAULT, true);
bitstring_set_bit(&event_data.eventEnable, TRANSITION_TO_NORMAL, true);
for (i = 0; i < 3; i++) {
event_data.eventPriorities[i] = 1;
}
event_data.next = NULL;
getevent_information_link_array(
&test_event_data[0], ARRAY_SIZE(test_event_data));
getevent_information_link_array(&event_data[0], ARRAY_SIZE(event_data));
event_data[0].objectIdentifier.type = OBJECT_BINARY_INPUT;
event_data[0].objectIdentifier.instance = 1;
event_data[0].eventState = EVENT_STATE_NORMAL;
bitstring_init(&event_data[0].acknowledgedTransitions);
bitstring_set_bit(
&event_data[0].acknowledgedTransitions, TRANSITION_TO_OFFNORMAL, false);
bitstring_set_bit(
&event_data[0].acknowledgedTransitions, TRANSITION_TO_FAULT, false);
bitstring_set_bit(
&event_data[0].acknowledgedTransitions, TRANSITION_TO_NORMAL, false);
for (i = 0; i < 3; i++) {
event_data[0].eventTimeStamps[i].tag = TIME_STAMP_SEQUENCE;
event_data[0].eventTimeStamps[i].value.sequenceNum = 0;
}
event_data[0].notifyType = NOTIFY_ALARM;
bitstring_init(&event_data[0].eventEnable);
bitstring_set_bit(
&event_data[0].eventEnable, TRANSITION_TO_OFFNORMAL, true);
bitstring_set_bit(&event_data[0].eventEnable, TRANSITION_TO_FAULT, true);
bitstring_set_bit(&event_data[0].eventEnable, TRANSITION_TO_NORMAL, true);
for (i = 0; i < 3; i++) {
event_data[0].eventPriorities[i] = 1;
}
len = getevent_ack_encode_apdu_init(&apdu[0], sizeof(apdu), invoke_id);
zassert_not_equal(len, 0, NULL);
zassert_not_equal(len, -1, NULL);
apdu_len = len;
len = getevent_ack_encode_apdu_data(
&apdu[apdu_len], sizeof(apdu) - apdu_len, &event_data);
&apdu[apdu_len], sizeof(apdu) - apdu_len, &event_data[0]);
zassert_not_equal(len, 0, NULL);
zassert_not_equal(len, -1, NULL);
apdu_len += len;
@@ -142,20 +142,28 @@ static void testGetEventInformationAck(void)
zassert_not_equal(len, 0, NULL);
zassert_not_equal(len, -1, NULL);
apdu_len += len;
null_len = getevent_ack_decode_apdu(&apdu[0], apdu_len, NULL, NULL, NULL);
len = getevent_ack_decode_apdu(
&apdu[0], apdu_len, /* total length of the apdu */
&test_invoke_id, &test_event_data, &test_moreEvents);
&test_invoke_id, &test_event_data[0], &test_moreEvents);
zassert_equal(null_len, len, "null_len=%d len=%d", null_len, len);
zassert_not_equal(len, -1, NULL);
zassert_equal(test_invoke_id, invoke_id, NULL);
zassert_equal(
event_data.objectIdentifier.type, test_event_data.objectIdentifier.type,
NULL);
event_data[0].objectIdentifier.type,
test_event_data[0].objectIdentifier.type, NULL);
zassert_equal(
event_data.objectIdentifier.instance,
test_event_data.objectIdentifier.instance, NULL);
event_data[0].objectIdentifier.instance,
test_event_data[0].objectIdentifier.instance, NULL);
zassert_equal(event_data.eventState, test_event_data.eventState, NULL);
zassert_equal(
event_data[0].eventState, test_event_data[0].eventState, NULL);
while (apdu_len) {
apdu_len--;
len = getevent_ack_decode_apdu(&apdu[0], apdu_len, NULL, NULL, NULL);
zassert_equal(len, BACNET_STATUS_ERROR, NULL);
}
}
#if defined(CONFIG_ZTEST_NEW_API)