test(opdf): guard recProperty layout integrity for method-backed properties
The recProperty corruption (garbled Name/ReadMethod/WriteMethod string
fields) was fixed in c6d22aac, but the only property test asserted just
the '# recProperty' comment — it would not have caught the RecSize/layout
mismatch that caused the reader to overshoot into the next record.
Add TestOPDF_Property_MethodBacked_LayoutIntact: for a method-backed
property it asserts the exact RecSize (32-byte fixed payload + the three
string lengths), the getter/setter symbol strings, and the three length
words. This pins the writer's declared size to the actual emitted bytes,
which is the invariant the reader (SizeOf(TDefProperty)=32 then three
length-prefixed strings) depends on.
This commit is contained in:
parent
25cd8e3ee7
commit
fdf99b26c0
|
|
@ -61,6 +61,7 @@ type
|
|||
procedure TestOPDF_Set_RecType;
|
||||
procedure TestOPDF_Set_SizeInBytes;
|
||||
procedure TestOPDF_Property_RecType;
|
||||
procedure TestOPDF_Property_MethodBacked_LayoutIntact;
|
||||
procedure TestOPDF_Interface_RecType;
|
||||
procedure TestOPDF_Constant_OrdRecord;
|
||||
procedure TestOPDF_Constant_OrdValue;
|
||||
|
|
@ -611,6 +612,47 @@ begin
|
|||
AssertTrue('recProperty comment', Contains(IR, '# recProperty: Val'));
|
||||
end;
|
||||
|
||||
procedure TOPDFTests.TestOPDF_Property_MethodBacked_LayoutIntact;
|
||||
{ Regression for the recProperty corruption (bugs.txt, opdebugger #10/#13 era):
|
||||
a method-backed property must emit a COMPLETE, correctly-sized recProperty so
|
||||
the reader (which reads SizeOf(TDefProperty)=32 fixed bytes then the three
|
||||
length-prefixed strings) does not overshoot into the next record. The fixed
|
||||
payload is 32 bytes (4 ClassTypeID + 4 PropTypeID + 1 ReadType + 1 WriteType +
|
||||
8 ReadAddr + 8 WriteAddr + 2+2+2 length words); RecSize = 32 + len(getterSym) +
|
||||
len(setterSym) + len(name). For TGadget.Val read GetVal write SetVal:
|
||||
getterSym = "TGadget_GetVal" (14), setterSym = "TGadget_SetVal" (14),
|
||||
name = "Val" (3) -> RecSize = 32 + 14 + 14 + 3 = 63. }
|
||||
var
|
||||
IR: string;
|
||||
begin
|
||||
IR := GenOPDF(
|
||||
'''
|
||||
program P;
|
||||
type TGadget = class
|
||||
FVal: Integer;
|
||||
function GetVal: Integer;
|
||||
procedure SetVal(AValue: Integer);
|
||||
property Val: Integer read GetVal write SetVal;
|
||||
end;
|
||||
function TGadget.GetVal: Integer;
|
||||
begin Result := FVal; end;
|
||||
procedure TGadget.SetVal(AValue: Integer);
|
||||
begin FVal := AValue; end;
|
||||
begin end.
|
||||
''');
|
||||
AssertTrue('recProperty comment', Contains(IR, '# recProperty: Val'));
|
||||
{ RecSize must match the fixed payload (32) + the three string lengths. }
|
||||
AssertTrue('recProperty RecSize is 63', Contains(IR, '.int 63 # RecSize'));
|
||||
{ The getter/setter symbol names and the property name must be present as the
|
||||
three trailing strings (the fields the corruption garbled). }
|
||||
AssertTrue('getter method symbol string', Contains(IR, '.ascii "TGadget_GetVal"'));
|
||||
AssertTrue('setter method symbol string', Contains(IR, '.ascii "TGadget_SetVal"'));
|
||||
{ The length words must match the actual symbol lengths. }
|
||||
AssertTrue('ReadMethodNameLen = 14', Contains(IR, '.word 14 # ReadMethodNameLen'));
|
||||
AssertTrue('WriteMethodNameLen = 14', Contains(IR, '.word 14 # WriteMethodNameLen'));
|
||||
AssertTrue('NameLen = 3', Contains(IR, '.word 3 # NameLen'));
|
||||
end;
|
||||
|
||||
procedure TOPDFTests.TestOPDF_Interface_RecType;
|
||||
var
|
||||
IR: string;
|
||||
|
|
|
|||
Loading…
Reference in a new issue