[fpc-devel] Can someone confirm if this is a bug? (ancestor in TWRiter.WriteProperty)

Michael Van Canneyt michael at freepascal.org
Tue Aug 18 09:02:51 CEST 2009



On Tue, 18 Aug 2009, Martin wrote:

> I may have mis-judged t, but the problem is still the same:
>
> when you get to write TPersistenChild  you enter the following code
>
>   tkClass:
>     begin
>       ObjValue := TObject(GetObjectProp(Instance, PropInfo));
>       if HasAncestor then
>       begin
>         AncestorObj := TObject(GetObjectProp(Ancestor, PropInfo));
>         if Assigned(AncestorObj) then
>           if Assigned(ObjValue) and
>             (TComponent(AncestorObj).Owner = FRootAncestor) and
>             (TComponent(ObjValue).Owner = Root) and
>             (UpperCase(TComponent(AncestorObj).Name) = 
> UpperCase(TComponent(ObjValue).Name)) then
>             AncestorObj := ObjValue
> //            else
> //              AncestorObj := nil;
>       end else
>         AncestorObj := nil;
> --------------
>
> TObject(GetObjectProp(Ancestor, PropInfo));  returns the TpersistentChil
> as well as ObjValue being TPersistent
>
>
> both get casted to TComponent with no check?

Ancestors can only be a TComponent.

Michael.

>
>
>
> Martin wrote:
>> I am not very familiar with the code, so before reporting, I'd like to ask:
>> 
>> trunc\rtl\objpas\classes\writer.inc
>> procedure TWriter.WriteProperty(Instance: TPersistent; PropInfo: Pointer);
>> 
>> Imagine you a writing an Component, that does have an ancestor.
>> The same component should have
>>   property Foo: TPersistentChild read FFoo write FFoo;
>> 
>> You should end up in the following code: (line 1091 in recent (a few weeks) 
>> trunc )
>> // this is the last else, it's not a component, and it is not a collection
>>          else
>>            begin
>>            SavedAncestor := Ancestor;
>>            SavedPropPath := FPropPath;
>>            try
>>              FPropPath := FPropPath + PPropInfo(PropInfo)^.Name + '.';
>>              if HasAncestor then
>>                Ancestor := TPersistent(GetObjectProp(Ancestor, PropInfo)); 
>> WriteProperties(TPersistent(ObjValue));
>>            finally
>>              Ancestor := SavedAncestor;
>>              FPropPath := SavedPropPath;
>>            end;
>>            end;
>> --------------------------------------
>>              if HasAncestor then
>>                Ancestor := TPersistent(GetObjectProp(Ancestor, PropInfo));
>> sets the ancestor to a persitent object
>> 
>> Now if TPersistentChild  itself has
>>  property Some: TComponent
>> 
>> then you end up again in TWriter.WriteProperty  writing a tclass property
>>
>>    tkClass:
>>      begin
>>        ObjValue := TObject(GetObjectProp(Instance, PropInfo));
>>        if HasAncestor then
>>        begin
>>          AncestorObj := TObject(GetObjectProp(Ancestor, PropInfo));
>>          if Assigned(AncestorObj) then
>>            if Assigned(ObjValue) and
>>              (TComponent(AncestorObj).Owner = FRootAncestor) and
>>              (TComponent(ObjValue).Owner = Root) and
>>              (UpperCase(TComponent(AncestorObj).Name) = 
>> UpperCase(TComponent(ObjValue).Name)) then
>>              AncestorObj := ObjValue
>> //            else
>> //              AncestorObj := nil;
>>        end else
>>          AncestorObj := nil;
>> 
>> 
>> and this code assumes that the ancestor is a TComponent, but as seen 
>> before, the ancestor is not.
>> 
>> 
>> Shall I report a bug, or do I miss understand something?
>> (is there a workaround?)
>> 
>> Martin
>> 
>> _______________________________________________
>> fpc-devel maillist  -  fpc-devel at lists.freepascal.org
>> http://lists.freepascal.org/mailman/listinfo/fpc-devel
>
> _______________________________________________
> fpc-devel maillist  -  fpc-devel at lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-devel
>



More information about the fpc-devel mailing list