Implemented checks in ModbusWriteRegisters so that the upper bound of process image is not exceeded.

This commit is contained in:
Jonny007-MKD 2014-07-14 10:27:04 +00:00
parent 608ec48e47
commit 2d26d89db0

View file

@ -441,7 +441,7 @@ void ModbusWriteBits(word address, long count, byte values[])
long offset; long offset;
word devStartAddr, devEndAddr; word devStartAddr, devEndAddr;
devStartAddr = funcCode == thisDev.Addr.Write.OutputBits; // The start address of the bits devStartAddr = thisDev.Addr.Write.OutputBits; // The start address of the bits
devEndAddr = devStartAddr + thisDev.MaxBitCount; // The address behind the last bit devEndAddr = devStartAddr + thisDev.MaxBitCount; // The address behind the last bit
if (address < devStartAddr) // Oh, reading at the wrong address? if (address < devStartAddr) // Oh, reading at the wrong address?
{ {
@ -567,23 +567,42 @@ void ModbusWriteRegisters(word address, long count, word values[])
enum ModbusFuncCode funcCode = WriteRegisters; enum ModbusFuncCode funcCode = WriteRegisters;
byte buffer[maxLength]; byte buffer[maxLength];
struct ModbusReqWriteRegisters mbreq; struct ModbusReqWriteRegisters mbreq;
word curCount; word overallLength, curCount, addressO;
byte dataLength; byte dataLength;
word overallLength;
word i; word i;
long offset; long offset;
word devStartAddr, devEndAddr;
devStartAddr = thisDev.Addr.Write.OutputRegisters; // The start address of the bits
devEndAddr = devStartAddr + thisDev.MaxRegisterCount; // The address behind the last bit
if (address >= devEndAddr)
devEndAddr = 0xFFFF;
if (address < devStartAddr) // Oh, reading at the wrong address?
{
writeDbg(MbError, "ModbusWriteRegisters: The given start address 0x%04X is smaller than the obligatory start address 0x%04X", address, devStartAddr);
OnModbusClientPanics(AddressFailure);
return;
}
// FC16: Write Multiple Registers (AOs) // FC16: Write Multiple Registers (AOs)
offset = 0; offset = 0;
while (count > 0) while (count > 0 && (address + offset) < devEndAddr)
{ {
addressO = address + offset;
curCount = count > gMaxRegsPerWrite ? gMaxRegsPerWrite : count; curCount = count > gMaxRegsPerWrite ? gMaxRegsPerWrite : count;
if (addressO + curCount > devEndAddr) // upper bound in process image
{
writeDbg(MbWarning, "ModbusWriteRegisters: Impossible to write %d bits at 0x%04X. Changed count to %d.", curCount, addressO, devEndAddr - addressO);
curCount = devEndAddr - addressO;
}
dataLength = 2 * curCount; dataLength = 2 * curCount;
overallLength = maxLength - 2*gMaxRegsPerWrite + dataLength; overallLength = maxLength - 2*gMaxRegsPerWrite + dataLength;
_ModbusMakeHeader(mbreq.Header, overallLength, funcCode); _ModbusMakeHeader(mbreq.Header, overallLength, funcCode);
mbreq.Address = address+offset; // [2] Output address mbreq.Address = addressO; // [2] Output address
mbreq.Count = curCount; // [2] Number of items; 1:max 123=0x7B mbreq.Count = curCount; // [2] Number of items; 1:max 123=0x7B
mbreq.ByteCount = dataLength; // [1] Number of bytes; = 2 * count mbreq.ByteCount = dataLength; // [1] Number of bytes; = 2 * count