Add registers count checking for file_read and file_write operations

MODBUS Application Protocol Specification does not require it explicitly
but without this checking PDU of a request or response may exceed 253 bytes.
This commit is contained in:
Vyacheslav Verkhovin 2023-07-14 00:54:49 +07:00
parent bd302660b6
commit 8dafc721fa
2 changed files with 28 additions and 10 deletions

View File

@ -1190,6 +1190,9 @@ static nmbs_error handle_read_file_record(nmbs_t* nmbs) {
if (subreq[i].record_number > 0x270F)
return send_exception_msg(nmbs, NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS);
if (subreq[i].record_length > 124)
return send_exception_msg(nmbs, NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS);
NMBS_DEBUG_PRINT("a %d\tr %d\tl %d\t fread ", subreq[i].file_number, subreq[i].record_number,
subreq[i].record_length);
}
@ -1259,7 +1262,7 @@ static nmbs_error handle_write_file_record(nmbs_t* nmbs) {
uint16_t size = request_size;
nmbs->msg.buf_idx = msg_buf_idx; // restore context
if (request_size < 0x07 || request_size > 0xF5)
if (request_size < 0x07 || request_size > 0xFB)
return send_exception_msg(nmbs, NMBS_EXCEPTION_ILLEGAL_DATA_VALUE);
do {
@ -1278,6 +1281,9 @@ static nmbs_error handle_write_file_record(nmbs_t* nmbs) {
if (subreq_record_number_c > 0x270F)
return send_exception_msg(nmbs, NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS);
if (subreq_record_length_c > 122)
return send_exception_msg(nmbs, NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS);
NMBS_DEBUG_PRINT("a %d\tr %d\tl %d\t fwrite ", subreq_file_number_c, subreq_record_number_c,
subreq_record_length_c);
size -= (subreq_header_size + subreq_record_length_c * 2);
@ -1652,6 +1658,9 @@ nmbs_error nmbs_read_file_record(nmbs_t* nmbs, uint16_t file_number, uint16_t re
if (record_number > 0x270F)
return NMBS_ERROR_INVALID_ARGUMENT;
if (count > 124)
return NMBS_ERROR_INVALID_ARGUMENT;
msg_state_req(nmbs, 20);
put_req_header(nmbs, 8);
@ -1681,6 +1690,9 @@ nmbs_error nmbs_write_file_record(nmbs_t* nmbs, uint16_t file_number, uint16_t r
if (record_number > 0x270F)
return NMBS_ERROR_INVALID_ARGUMENT;
if (count > 122)
return NMBS_ERROR_INVALID_ARGUMENT;
uint16_t data_size = count * 2;
msg_state_req(nmbs, 21);

View File

@ -842,8 +842,8 @@ nmbs_error read_file(uint16_t file_number, uint16_t record_number, uint16_t* reg
registers[3] = 0xFFFF;
}
if (file_number == 255 && record_number == 9999 && count == 119)
registers[118] = 42;
if (file_number == 255 && record_number == 9999 && count == 124)
registers[123] = 42;
return NMBS_ERROR_NONE;
}
@ -868,6 +868,9 @@ void test_fc20(nmbs_transport transport) {
should("immediately return NMBS_ERROR_INVALID_ARGUMENT when calling with record_number > 9999");
expect(nmbs_read_file_record(&CLIENT, 1, 10000, registers, 1) == NMBS_ERROR_INVALID_ARGUMENT);
should("return NMBS_ERROR_INVALID_ARGUMENT when calling with count > 124");
expect(nmbs_read_file_record(&CLIENT, 1, 0, registers, 125) == NMBS_ERROR_INVALID_ARGUMENT);
should("return NMBS_EXCEPTION_SERVER_DEVICE_FAILURE when server handler returns any non-exception error");
expect(nmbs_read_file_record(&CLIENT, 1, 1, registers, 3) == NMBS_EXCEPTION_SERVER_DEVICE_FAILURE);
@ -884,8 +887,8 @@ void test_fc20(nmbs_transport transport) {
expect(registers[2] == 0xAA55);
expect(registers[3] == 0xFFFF);
check(nmbs_read_file_record(&CLIENT, 255, 9999, registers, 119));
expect(registers[118] == 42);
check(nmbs_read_file_record(&CLIENT, 255, 9999, registers, 124));
expect(registers[123] == 42);
stop_client_and_server();
}
@ -914,8 +917,8 @@ nmbs_error write_file(uint16_t file_number, uint16_t record_number, const uint16
return NMBS_ERROR_NONE;
}
if (file_number == 255 && record_number == 9999 && count == 119)
expect(registers[118] == 42);
if (file_number == 255 && record_number == 9999 && count == 122)
expect(registers[121] == 42);
return NMBS_ERROR_NONE;
}
@ -937,9 +940,12 @@ void test_fc21(nmbs_transport transport) {
should("immediately return NMBS_ERROR_INVALID_ARGUMENT when calling with file_number 0");
expect(nmbs_write_file_record(&CLIENT, 0, 0, registers, 1) == NMBS_ERROR_INVALID_ARGUMENT);
should("immediately return NMBS_ERROR_INVALID_ARGUMENT when calling with record_number > 0x007B");
should("immediately return NMBS_ERROR_INVALID_ARGUMENT when calling with record_number > 9999");
expect(nmbs_write_file_record(&CLIENT, 1, 10000, registers, 1) == NMBS_ERROR_INVALID_ARGUMENT);
should("return NMBS_ERROR_INVALID_ARGUMENT hen calling with count > 123");
expect(nmbs_write_file_record(&CLIENT, 1, 0, registers, 123) == NMBS_ERROR_INVALID_ARGUMENT);
should("return NMBS_EXCEPTION_SERVER_DEVICE_FAILURE when server handler returns any non-exception error");
expect(nmbs_write_file_record(&CLIENT, 1, 1, registers, 1) == NMBS_EXCEPTION_SERVER_DEVICE_FAILURE);
@ -956,8 +962,8 @@ void test_fc21(nmbs_transport transport) {
registers[3] = 0xFFFF;
check(nmbs_write_file_record(&CLIENT, 4, 4, registers, 4));
registers[118] = 42;
check(nmbs_write_file_record(&CLIENT, 255, 9999, registers, 119));
registers[121] = 42;
check(nmbs_write_file_record(&CLIENT, 255, 9999, registers, 122));
stop_client_and_server();
}