[libbacnet]: bacapp_data_len() + bacnet_tag_number_and_value_decode() (#453)
* Bugfix: bacapp_data_len() + bacnet_tag_number_and_value_decode() * Fix bacnet_tag_number_and_value_decode function. Add read buffer safe functions for opening, closing, context specific tags. Fix bacapp_data_len function changes as indicated by unit testing. * refactor bacapp_data_len --------- Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
committed by
GitHub
parent
28de333b6e
commit
acb3b0f57d
+54
-37
@@ -1520,54 +1520,71 @@ int bacapp_data_len(
|
||||
uint8_t opening_tag_number = 0;
|
||||
uint8_t opening_tag_number_counter = 0;
|
||||
uint32_t value = 0;
|
||||
bool total_len_enable = false;
|
||||
|
||||
if (IS_OPENING_TAG(apdu[0])) {
|
||||
len = bacnet_tag_number_and_value_decode(
|
||||
&apdu[apdu_len], apdu_len_max - apdu_len, &tag_number, &value);
|
||||
apdu_len += len;
|
||||
opening_tag_number = tag_number;
|
||||
opening_tag_number_counter = 1;
|
||||
while (opening_tag_number_counter) {
|
||||
if (IS_OPENING_TAG(apdu[apdu_len])) {
|
||||
len = bacnet_tag_number_and_value_decode(&apdu[apdu_len],
|
||||
apdu_len_max - apdu_len, &tag_number, &value);
|
||||
if (tag_number == opening_tag_number) {
|
||||
opening_tag_number_counter++;
|
||||
}
|
||||
} else if (IS_CLOSING_TAG(apdu[apdu_len])) {
|
||||
len = bacnet_tag_number_and_value_decode(&apdu[apdu_len],
|
||||
apdu_len_max - apdu_len, &tag_number, &value);
|
||||
if (tag_number == opening_tag_number) {
|
||||
if (!apdu) {
|
||||
return BACNET_STATUS_ERROR;
|
||||
}
|
||||
if (apdu_len_max <= apdu_len) {
|
||||
/* error: exceeding our buffer limit */
|
||||
return BACNET_STATUS_ERROR;
|
||||
}
|
||||
if (!bacnet_is_opening_tag(apdu, apdu_len_max)) {
|
||||
/* error: opening tag is missing */
|
||||
return BACNET_STATUS_ERROR;
|
||||
}
|
||||
do {
|
||||
if (bacnet_is_opening_tag(apdu, apdu_len_max)) {
|
||||
len = bacnet_tag_number_and_value_decode(apdu,
|
||||
apdu_len_max - apdu_len, &tag_number, &value);
|
||||
if (opening_tag_number_counter == 0) {
|
||||
opening_tag_number = tag_number;
|
||||
opening_tag_number_counter = 1;
|
||||
total_len_enable = false;
|
||||
} else if (tag_number == opening_tag_number) {
|
||||
total_len_enable = true;
|
||||
opening_tag_number_counter++;
|
||||
}
|
||||
} else if (bacnet_is_closing_tag(apdu, apdu_len_max)) {
|
||||
len = bacnet_tag_number_and_value_decode(apdu,
|
||||
apdu_len_max - apdu_len, &tag_number, &value);
|
||||
if (tag_number == opening_tag_number) {
|
||||
if (opening_tag_number_counter > 0) {
|
||||
opening_tag_number_counter--;
|
||||
}
|
||||
} else if (IS_CONTEXT_SPECIFIC(apdu[apdu_len])) {
|
||||
}
|
||||
total_len_enable = true;
|
||||
} else if (bacnet_is_context_specific(apdu, apdu_len_max)) {
|
||||
#if defined(BACAPP_TYPES_EXTRA)
|
||||
/* context-specific tagged data */
|
||||
len = bacapp_decode_context_data_len(
|
||||
&apdu[apdu_len], apdu_len_max - apdu_len, property);
|
||||
/* context-specific tagged data */
|
||||
len = bacapp_decode_context_data_len(
|
||||
apdu, apdu_len_max - apdu_len, property);
|
||||
total_len_enable = true;
|
||||
#endif
|
||||
} else {
|
||||
/* application tagged data */
|
||||
len = bacapp_decode_application_data_len(
|
||||
apdu, apdu_len_max - apdu_len);
|
||||
total_len_enable = true;
|
||||
}
|
||||
if (opening_tag_number_counter > 0) {
|
||||
if (len > 0) {
|
||||
if (total_len_enable) {
|
||||
total_len += len;
|
||||
}
|
||||
} else {
|
||||
/* application tagged data */
|
||||
len = bacapp_decode_application_data_len(
|
||||
&apdu[apdu_len], apdu_len_max - apdu_len);
|
||||
/* error: len is not incrementing */
|
||||
return BACNET_STATUS_ERROR;
|
||||
}
|
||||
apdu_len += len;
|
||||
if (opening_tag_number_counter) {
|
||||
if (len > 0) {
|
||||
total_len += len;
|
||||
} else {
|
||||
/* error: len is not incrementing */
|
||||
total_len = BACNET_STATUS_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((unsigned)apdu_len > apdu_len_max) {
|
||||
if (apdu_len_max <= apdu_len) {
|
||||
/* error: exceeding our buffer limit */
|
||||
total_len = BACNET_STATUS_ERROR;
|
||||
break;
|
||||
return BACNET_STATUS_ERROR;
|
||||
}
|
||||
apdu += len;
|
||||
}
|
||||
}
|
||||
} while (opening_tag_number_counter > 0);
|
||||
|
||||
|
||||
return total_len;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user