Fix decoding empty array of complex type in RPM

This commit is contained in:
Ondřej Hruška
2023-10-20 15:27:44 +02:00
parent 0b5474d36e
commit 3870bb3826
+43 -34
View File
@@ -118,40 +118,49 @@ int rpm_ack_decode_service_request(
more than one element to decode */ more than one element to decode */
value = calloc(1, sizeof(BACNET_APPLICATION_DATA_VALUE)); value = calloc(1, sizeof(BACNET_APPLICATION_DATA_VALUE));
rpm_property->value = value; rpm_property->value = value;
while (value && (apdu_len > 0)) {
len = bacapp_decode_known_property(apdu, (unsigned)apdu_len, /* Special case for an empty array - we decode it as null */
value, rpm_object->object_type, if (apdu_len && decode_is_closing_tag_number(apdu, 4)) {
rpm_property->propertyIdentifier); /* NULL value has tag 0, that was already set by calloc */
/* If len == 0 then it's an empty structure, which is OK. */ decoded_len++;
if (len < 0) { apdu_len--;
/* problem decoding */ apdu++;
PERROR("RPM Ack: unable to decode! %s:%s\n", } else {
bactext_object_type_name(rpm_object->object_type), while (value && (apdu_len > 0)) {
bactext_property_name( len = bacapp_decode_known_property(apdu, (unsigned)apdu_len,
rpm_property->propertyIdentifier)); value, rpm_object->object_type,
/* note: caller will free the memory */ rpm_property->propertyIdentifier);
return BACNET_STATUS_ERROR; /* If len == 0 then it's an empty structure, which is OK. */
} if (len < 0) {
decoded_len += len; /* problem decoding */
apdu_len -= len; PERROR("RPM Ack: unable to decode! %s:%s\n",
apdu += len; bactext_object_type_name(rpm_object->object_type),
if (apdu_len && decode_is_closing_tag_number(apdu, 4)) { bactext_property_name(
decoded_len++; rpm_property->propertyIdentifier));
apdu_len--; /* note: caller will free the memory */
apdu++; return BACNET_STATUS_ERROR;
break; }
} else if (len > 0) { decoded_len += len;
old_value = value; apdu_len -= len;
value = apdu += len;
calloc(1, sizeof(BACNET_APPLICATION_DATA_VALUE)); if (apdu_len && decode_is_closing_tag_number(apdu, 4)) {
old_value->next = value; decoded_len++;
} else { apdu_len--;
PERROR("RPM Ack: decoded %s:%s len=%d\n", apdu++;
bactext_object_type_name(rpm_object->object_type), break;
bactext_property_name( } else if (len > 0) {
rpm_property->propertyIdentifier), old_value = value;
len); value =
break; calloc(1, sizeof(BACNET_APPLICATION_DATA_VALUE));
old_value->next = value;
} else {
PERROR("RPM Ack: decoded %s:%s len=%d\n",
bactext_object_type_name(rpm_object->object_type),
bactext_property_name(
rpm_property->propertyIdentifier),
len);
break;
}
} }
} }
} else if (apdu_len && decode_is_opening_tag_number(apdu, 5)) { } else if (apdu_len && decode_is_opening_tag_number(apdu, 5)) {