Implemented checks in ModbusWriteRegisters so that the upper bound of process image is not exceeded.
This commit is contained in:
		
							parent
							
								
									608ec48e47
								
							
						
					
					
						commit
						2d26d89db0
					
				
					 1 changed files with 26 additions and 7 deletions
				
			
		| 
						 | 
					@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue