diff --git a/bacnet-stack/demo/handler/h_rp.c b/bacnet-stack/demo/handler/h_rp.c index 97ead2e8..bd578731 100644 --- a/bacnet-stack/demo/handler/h_rp.c +++ b/bacnet-stack/demo/handler/h_rp.c @@ -36,6 +36,7 @@ #include "apdu.h" #include "npdu.h" #include "abort.h" +#include "reject.h" #include "rp.h" /* device object has custom handler for all objects */ #include "device.h" @@ -103,9 +104,8 @@ void handler_read_property( #endif if (len < 0) { /* bad decoding - send an abort */ - apdu_len = - abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len], - service_data->invoke_id, ABORT_REASON_OTHER, true); + apdu_len = reject_encode_apdu(&Handler_Transmit_Buffer[npdu_len], + service_data->invoke_id, rpdata.error_code); #if PRINT_ENABLED fprintf(stderr, "RP: Bad Encoding. Sending Abort!\n"); #endif diff --git a/bacnet-stack/src/rp.c b/bacnet-stack/src/rp.c index 9878a9ec..189426bf 100644 --- a/bacnet-stack/src/rp.c +++ b/bacnet-stack/src/rp.c @@ -88,18 +88,29 @@ int rp_decode_service_request( uint32_t array_value = 0; /* for decoding */ /* check for value pointers */ - if (apdu_len && rpdata) { - /* Tag 0: Object ID */ - if (!decode_is_context_tag(&apdu[len++], 0)) + if (rpdata != NULL) { + /* Must have at least 2 tags, an object id and a property identifier + * of at least 1 byte in length to have any chance of parsing */ + if(apdu_len < 7) { + rpdata->error_code = REJECT_REASON_MISSING_REQUIRED_PARAMETER; return -1; + } + + /* Tag 0: Object ID */ + if (!decode_is_context_tag(&apdu[len++], 0)) { + rpdata->error_code = REJECT_REASON_INVALID_TAG; + return -1; + } len += decode_object_id(&apdu[len], &type, &rpdata->object_instance); rpdata->object_type = (BACNET_OBJECT_TYPE) type; /* Tag 1: Property ID */ len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value_type); - if (tag_number != 1) + if (tag_number != 1) { + rpdata->error_code = REJECT_REASON_INVALID_TAG; return -1; + } len += decode_enumerated(&apdu[len], len_value_type, &property); rpdata->object_property = (BACNET_PROPERTY_ID) property; /* Tag 2: Optional Array Index */ @@ -107,15 +118,23 @@ int rp_decode_service_request( len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value_type); - if (tag_number == 2) { + if ((tag_number == 2) && (len < apdu_len)) { len += decode_unsigned(&apdu[len], len_value_type, &array_value); rpdata->array_index = array_value; - } else - rpdata->array_index = BACNET_ARRAY_ALL; + } else { + rpdata->error_code = REJECT_REASON_INVALID_TAG; + return -1; + } } else rpdata->array_index = BACNET_ARRAY_ALL; } + + if(len < apdu_len) { + /* If something left over now, we have an invalid request */ + rpdata->error_code = REJECT_REASON_TOO_MANY_ARGUMENTS; + return -1; + } return (int) len; }