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,9 +441,9 @@ void ModbusWriteBits(word address, long count, byte values[])
long offset;
word devStartAddr, devEndAddr;
devStartAddr = funcCode == thisDev.Addr.Write.OutputBits; // The start address of the bits
devEndAddr = devStartAddr + thisDev.MaxBitCount; // The address behind the last bit
if (address < devStartAddr) // Oh, reading at the wrong address?
devStartAddr = thisDev.Addr.Write.OutputBits; // The start address of the bits
devEndAddr = devStartAddr + thisDev.MaxBitCount; // The address behind the last bit
if (address < devStartAddr) // Oh, reading at the wrong address?
{
writeDbg(MbError, "ModbusWriteBits: The given start address 0x%04X is smaller than the obligatory start address 0x%04X", address, devStartAddr);
OnModbusClientPanics(AddressFailure);
@ -567,23 +567,42 @@ void ModbusWriteRegisters(word address, long count, word values[])
enum ModbusFuncCode funcCode = WriteRegisters;
byte buffer[maxLength];
struct ModbusReqWriteRegisters mbreq;
word curCount;
word overallLength, curCount, addressO;
byte dataLength;
word overallLength;
word i;
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)
offset = 0;
while (count > 0)
while (count > 0 && (address + offset) < devEndAddr)
{
addressO = address + offset;
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;
overallLength = maxLength - 2*gMaxRegsPerWrite + dataLength;
_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.ByteCount = dataLength; // [1] Number of bytes; = 2 * count