Crash in TWriter with read only class property = nil
Original Reporter info from Mantis: Martin @martin_frb
-
Reporter name: Martin Friebe
Original Reporter info from Mantis: Martin @martin_frb
- Reporter name: Martin Friebe
Description:
Trying to write a component with a readonly class property that is nil will crash in WriteProperty
#0 CLASSES$_$TWRITER_$__$$_WRITEPROPERTY$TPERSISTENT$POINTER+275 at :0
#1 CLASSES$_$TWRITER_$__$$_WRITEPROPERTIES$TPERSISTENT+116 at :0
#2 CLASSES$_$TWRITER_$__$$_WRITECOMPONENTDATA$TCOMPONENT+151 at :0
#3 CLASSES$_$TWRITER_$__$$_WRITEDESCENDENT$TCOMPONENT$TCOMPONENT+51 at :0
#4 SYSTEM_$$_MAIN_WRAPPER$POINTER$POINTER$$INT64+6 at :0
procedure TWriter.WriteProperty(Instance: TPersistent; PropInfo: Pointer);
....
PropType := PPropInfo(PropInfo)^.PropType;
if not Assigned(PPropInfo(PropInfo)^.SetProc) then begin
if PropType^.Kind<>tkClass then
exit;
ObjValue := TObject(GetObjectProp(Instance, PropInfo));
if not ObjValue.InheritsFrom(TComponent) or
not (csSubComponent in TComponent(ObjValue).ComponentStyle) then
exit;
end;
ObjValue will be nil.
The code should have "not assigned(ObjValue) or" added:
if not assigned(ObjValue) or
not ObjValue.InheritsFrom(TComponent) or
not (csSubComponent in TComponent(ObjValue).ComponentStyle) then
exit;
Steps to reproduce:
program Project1;
{$mode objfpc}{$H+}
uses
Classes;
type
TMyComponent = class(TComponent)
private
FFoo: TComponent;
published
property ReadOnly: TComponent read FFoo; // will be nil
end;
var
strm: TMemoryStream;
Driver: TAbstractObjectWriter;
Writer: TWriter;
Reader: TReader;
o: TMyComponent;
begin
o := TMyComponent.Create(nil);
strm := TMemoryStream.Create;
Driver := TBinaryObjectWriter.Create(strm,4096);
Writer := TWriter.Create(Driver);
Writer.WriteRootComponent(o);
Driver.Free;
Writer.Free;
strm.Free;
end.
Mantis conversion info:
- Mantis ID: 38920
- OS: win 10
- OS Build: 10
- Platform: 64bit Intel
- Version: 3.3.1
- Fixed in version: 3.3.1
- Fixed in revision: 49389 (#61cd38e6)
- Target version: 4.0.0