diff --git a/meddfnprs.rpgle b/meddfnprs.rpgle index 9afba68..5d6aa81 100644 --- a/meddfnprs.rpgle +++ b/meddfnprs.rpgle @@ -31,6 +31,9 @@ dcl-pr MD_ParseRetrieveBuffer; MediaDefinition likeds(MD_MediaDefinition_T); + Error + likeds(MD_Error_T); + end-pr; @@ -47,9 +50,11 @@ end-pr; // - Media File Definitions // - Volume Identifier Arrays // +// Parser errors are returned in Error. +// //===================================================================== -dcl-proc MD_ParseRetrieveBuffer export; +dcl-proc MD_ParseRetrieveBuffer export; dcl-pi *n; @@ -60,6 +65,9 @@ dcl-proc MD_ParseRetrieveBuffer export; MediaDefinition likeds(MD_MediaDefinition_T); + Error + likeds(MD_Error_T); + end-pi; @@ -81,6 +89,9 @@ dcl-proc MD_ParseRetrieveBuffer export; // Working variables //================================================================== + dcl-s ReceiverLength + int(10); + dcl-s DeviceOffset int(10); @@ -99,12 +110,32 @@ dcl-proc MD_ParseRetrieveBuffer export; dcl-s VolumeIndex int(10); + dcl-s RequiredLength + int(10); + //================================================================== - // Initialize result + // Initialize //================================================================== clear MediaDefinition; + clear Error; + + ReceiverLength = %len(ReceiverBuffer); + + + //================================================================== + // Receiver buffer + //================================================================== + + if ReceiverLength < %size(Header); + + Error.HasError = *on; + Error.MessageID = 'MDF2005'; + Error.MessageData = *blanks; + return; + + endif; //================================================================== @@ -118,6 +149,80 @@ dcl-proc MD_ParseRetrieveBuffer export; %size(Header)); + //================================================================== + // Validate Header + //================================================================== + + if Header.LengthOfHeader <> %size(Header); + + Error.HasError = *on; + Error.MessageID = 'MDF2001'; + Error.MessageData = *blanks; + return; + + endif; + + + if Header.NumberOfDeviceDefinitions < 1 + or Header.NumberOfDeviceDefinitions > MD_MaxDeviceDefinitions; + + Error.HasError = *on; + Error.MessageID = 'MDF2001'; + Error.MessageData = *blanks; + return; + + endif; + + + if Header.OffsetToFirstDeviceDefinition < %size(Header) + or Header.OffsetToFirstDeviceDefinition > + ReceiverLength - %size(Device); + + Error.HasError = *on; + Error.MessageID = 'MDF2001'; + Error.MessageData = *blanks; + return; + + endif; + + + if Header.DeviceAllocation <> MD_DeviceAllocateAll + and Header.DeviceAllocation <> MD_DeviceAllocateOne + and Header.DeviceAllocation <> MD_DeviceAllocateMinimum; + + Error.HasError = *on; + Error.MessageID = 'MDF2001'; + Error.MessageData = *blanks; + return; + + endif; + + + if Header.SaveFormat <> MD_SaveFormatAuto + and Header.SaveFormat <> MD_SaveFormatSerial + and Header.SaveFormat <> MD_SaveFormatParallel; + + Error.HasError = *on; + Error.MessageID = 'MDF2001'; + Error.MessageData = *blanks; + return; + + endif; + + + if Header.MaximumParallelDeviceResources < 0 + or Header.MinimumParallelDeviceResources < 0 + or Header.MinimumParallelDeviceResources > + Header.MaximumParallelDeviceResources; + + Error.HasError = *on; + Error.MessageID = 'MDF2001'; + Error.MessageData = *blanks; + return; + + endif; + + //================================================================== // Header -> Media Definition //================================================================== @@ -150,9 +255,24 @@ dcl-proc MD_ParseRetrieveBuffer export; to Header.NumberOfDeviceDefinitions; - //--------------------------------------------------------------- + //=============================================================== + // Validate Device Offset + //=============================================================== + + if DeviceOffset < 0 + or DeviceOffset > ReceiverLength - %size(Device); + + Error.HasError = *on; + Error.MessageID = 'MDF2002'; + Error.MessageData = *blanks; + return; + + endif; + + + //=============================================================== // Read Device Definition - //--------------------------------------------------------------- + //=============================================================== Device = %subst( @@ -161,9 +281,54 @@ dcl-proc MD_ParseRetrieveBuffer export; %size(Device)); - //--------------------------------------------------------------- + //=============================================================== + // Validate Device Definition + //=============================================================== + + if Device.LengthOfDeviceDefinition <> %size(Device); + + Error.HasError = *on; + Error.MessageID = 'MDF2002'; + Error.MessageData = *blanks; + return; + + endif; + + + if Device.NumberOfMediaFileDefinitions < 1 + or Device.NumberOfMediaFileDefinitions > MD_MaxMediaDefinitions; + + Error.HasError = *on; + Error.MessageID = 'MDF2002'; + Error.MessageData = *blanks; + return; + + endif; + + + if %trim(Device.DeviceName) = ''; + + Error.HasError = *on; + Error.MessageID = 'MDF2002'; + Error.MessageData = *blanks; + return; + + endif; + + + if Device.OffsetToFirstMediaFileDefinition < %size(Device); + + Error.HasError = *on; + Error.MessageID = 'MDF2002'; + Error.MessageData = *blanks; + return; + + endif; + + + //=============================================================== // Device -> Media Definition - //--------------------------------------------------------------- + //=============================================================== MediaDefinition.Device(DeviceIndex).DeviceName = Device.DeviceName; @@ -172,120 +337,238 @@ dcl-proc MD_ParseRetrieveBuffer export; Device.NumberOfMediaFileDefinitions; - //--------------------------------------------------------------- + //=============================================================== // Media Files - //--------------------------------------------------------------- + //=============================================================== - if Device.NumberOfMediaFileDefinitions > 0; - - // OffsetToFirstMediaFileDefinition is relative - // to the Device Definition. - - MediaOffset = - DeviceOffset - + Device.OffsetToFirstMediaFileDefinition; + MediaOffset = + DeviceOffset + + Device.OffsetToFirstMediaFileDefinition; - for MediaIndex = 1 - to Device.NumberOfMediaFileDefinitions; + for MediaIndex = 1 + to Device.NumberOfMediaFileDefinitions; - //---------------------------------------------------------- - // Read Media File Definition - //---------------------------------------------------------- + //============================================================ + // Validate Media Offset + //============================================================ - MediaFile = - %subst( - ReceiverBuffer : - MediaOffset + 1 : - %size(MediaFile)); + if MediaOffset < 0 + or MediaOffset > ReceiverLength - %size(MediaFile); + + Error.HasError = *on; + Error.MessageID = 'MDF2003'; + Error.MessageData = *blanks; + return; + + endif; - //---------------------------------------------------------- - // Media File -> Media Definition - //---------------------------------------------------------- + //============================================================ + // Read Media File Definition + //============================================================ - MediaDefinition.Device(DeviceIndex) - .MediaFile(MediaIndex) - .SequenceNumber = - MediaFile.SequenceNumber; + MediaFile = + %subst( + ReceiverBuffer : + MediaOffset + 1 : + %size(MediaFile)); - MediaDefinition.Device(DeviceIndex) - .MediaFile(MediaIndex) - .StartingPositionInFile = - MediaFile.StartingPositionInFile; + //============================================================ + // Validate Media File Definition + //============================================================ + + if MediaFile.LengthOfMediaFileDefinition <> %size(MediaFile); + + Error.HasError = *on; + Error.MessageID = 'MDF2003'; + Error.MessageData = *blanks; + return; + + endif; - MediaDefinition.Device(DeviceIndex) - .MediaFile(MediaIndex) - .NumberOfVolumeIdentifiers = - MediaFile.NumberOfVolumeIdentifiers; + if MediaFile.NumberOfVolumeIdentifiers < 0 + or MediaFile.NumberOfVolumeIdentifiers > MD_MaxVolumeIdentifiers; + + Error.HasError = *on; + Error.MessageID = 'MDF2003'; + Error.MessageData = *blanks; + return; + + endif; - //---------------------------------------------------------- - // Volume Identifier Array - //---------------------------------------------------------- + if MediaFile.NumberOfVolumeIdentifiers = 0; - if MediaFile.NumberOfVolumeIdentifiers > 0; + if MediaFile.OffsetToVolumeIdentifierArray <> 0 + or MediaFile.LengthOfVolumeIdentifier <> 0 + or MediaFile.StartingVolumeArrayElement <> 0; - VolumeOffset = - MediaFile.OffsetToVolumeIdentifierArray; - - - for VolumeIndex = 1 - to MediaFile.NumberOfVolumeIdentifiers; - - - MediaDefinition.Device(DeviceIndex) - .MediaFile(MediaIndex) - .VolumeIdentifier(VolumeIndex) - .VolumeIdentifier = - %subst( - ReceiverBuffer : - VolumeOffset - + ((VolumeIndex - 1) - * MediaFile.LengthOfVolumeIdentifier) - + 1 : - MediaFile.LengthOfVolumeIdentifier); - - - endfor; + Error.HasError = *on; + Error.MessageID = 'MDF2004'; + Error.MessageData = *blanks; + return; endif; + else; - //---------------------------------------------------------- - // Next Media File - //---------------------------------------------------------- + if MediaFile.OffsetToVolumeIdentifierArray <= 0 + or MediaFile.LengthOfVolumeIdentifier <> MD_VOLUME_ID_LENGTH + or MediaFile.StartingVolumeArrayElement < 1; - if MediaIndex - < Device.NumberOfMediaFileDefinitions; - - if MediaFile.OffsetToNextMediaFileDefinition > 0; - - MediaOffset = - MediaFile.OffsetToNextMediaFileDefinition; - - endif; + Error.HasError = *on; + Error.MessageID = 'MDF2004'; + Error.MessageData = *blanks; + return; endif; + RequiredLength = + MediaFile.NumberOfVolumeIdentifiers + * MediaFile.LengthOfVolumeIdentifier; - endfor; + if MediaFile.OffsetToVolumeIdentifierArray > + ReceiverLength - RequiredLength + or MediaFile.OffsetToVolumeIdentifierArray < + MediaOffset + %size(MediaFile); - endif; + Error.HasError = *on; + Error.MessageID = 'MDF2004'; + Error.MessageData = *blanks; + return; + + endif; + + endif; + + + //============================================================ + // Media File -> Media Definition + //============================================================ + + MediaDefinition.Device(DeviceIndex) + .MediaFile(MediaIndex) + .SequenceNumber = + MediaFile.SequenceNumber; + + + MediaDefinition.Device(DeviceIndex) + .MediaFile(MediaIndex) + .StartingPositionInFile = + MediaFile.StartingPositionInFile; + + + MediaDefinition.Device(DeviceIndex) + .MediaFile(MediaIndex) + .NumberOfVolumeIdentifiers = + MediaFile.NumberOfVolumeIdentifiers; + + + //============================================================ + // Volume Identifier Array + //============================================================ + + if MediaFile.NumberOfVolumeIdentifiers > 0; + + VolumeOffset = + MediaFile.OffsetToVolumeIdentifierArray; + + + for VolumeIndex = 1 + to MediaFile.NumberOfVolumeIdentifiers; + + MediaDefinition.Device(DeviceIndex) + .MediaFile(MediaIndex) + .VolumeIdentifier(VolumeIndex) + .VolumeIdentifier = + %subst( + ReceiverBuffer : + VolumeOffset + + ((VolumeIndex - 1) + * MediaFile.LengthOfVolumeIdentifier) + + 1 : + MediaFile.LengthOfVolumeIdentifier); + + endfor; + + endif; + + + //============================================================ + // Next Media File + //============================================================ + + if MediaIndex + < Device.NumberOfMediaFileDefinitions; + + if MediaFile.OffsetToNextMediaFileDefinition <= + MediaOffset + or MediaFile.OffsetToNextMediaFileDefinition > + ReceiverLength - %size(MediaFile); + + Error.HasError = *on; + Error.MessageID = 'MDF2003'; + Error.MessageData = *blanks; + return; + + endif; + + MediaOffset = + MediaFile.OffsetToNextMediaFileDefinition; + + else; + + if MediaFile.OffsetToNextMediaFileDefinition <> 0; + + Error.HasError = *on; + Error.MessageID = 'MDF2003'; + Error.MessageData = *blanks; + return; + + endif; + + endif; + + + endfor; //================================================================ // Next Device //================================================================ - if Device.OffsetToNextDeviceDefinition > 0; + if DeviceIndex < Header.NumberOfDeviceDefinitions; + + if Device.OffsetToNextDeviceDefinition <= + DeviceOffset + or Device.OffsetToNextDeviceDefinition > + ReceiverLength - %size(Device); + + Error.HasError = *on; + Error.MessageID = 'MDF2002'; + Error.MessageData = *blanks; + return; + + endif; DeviceOffset = Device.OffsetToNextDeviceDefinition; + else; + + if Device.OffsetToNextDeviceDefinition <> 0; + + Error.HasError = *on; + Error.MessageID = 'MDF2002'; + Error.MessageData = *blanks; + return; + + endif; + endif; @@ -293,4 +576,3 @@ dcl-proc MD_ParseRetrieveBuffer export; end-proc; - diff --git a/meddfnsrv.rpgle b/meddfnsrv.rpgle index 705cf7f..730450a 100644 --- a/meddfnsrv.rpgle +++ b/meddfnsrv.rpgle @@ -68,6 +68,9 @@ dcl-pr MD_ParseRetrieveBuffer; MediaDefinition likeds(MD_MediaDefinition_T); + Error + likeds(MD_Error_T); + end-pr; @@ -555,7 +558,18 @@ dcl-proc MD_RetrieveMediaDefinition export; MD_ParseRetrieveBuffer( Receiver.Data : - MediaDefinition); + MediaDefinition : + Error); + + if Error.HasError; + + MD_SendEscape( + Error.MessageID : + Error.MessageData); + + return; + + endif; end-proc; diff --git a/meddfntste.rpgle b/meddfntste.rpgle index d0a6172..14881d4 100644 --- a/meddfntste.rpgle +++ b/meddfntste.rpgle @@ -76,6 +76,20 @@ dsply '----------------------------------------'; dsply 'MEDDFN Error Test completed'; dsply '----------------------------------------'; +//===================================================================== +// End +//===================================================================== + +*inlr = *on; +return; + + +//===================================================================== +// +// TestCreateValidation +// +//===================================================================== + //===================================================================== //