#1 2024-08-09 07:24:08

oz
Member
Registered: 2015-09-02
Posts: 98

Regression in TRttiCustomProp.SetValueVariant()

Hi Arnaud,

there seems to be a regression in mormot.core.rtti.pas, procedure TRttiCustomProp.SetValueVariant().

procedure TRttiCustomProp.SetValueVariant(Data: pointer; var Source: TVarData);
var
  u: pointer;
begin
  if Prop <> nil then
    Prop.SetValue(TObject(Data), variant(Source)) // for class properties
  else
  begin
    u := nil; // use a temp UTF-8 conversion with records
    if Source.VType > varNull then
    begin
      VariantToUtf8(variant(Source), RawUtf8(u));
      if not SetValueText(Data, RawUtf8(u)) then
        ClearValue(Data, {freenestedobjects=}true);
    end;
    FastAssignNew(u);
  end;
  VarClearProc(Source);
end;

The last line VarClearProc(Source); is raising EVariantInvalidOpError when copying tkEnumeration type properties. If I remove VarClearProc(Source) call completely, everything works as expected, no mem leaks. Why do you have to call VarClearProc(Source) at all?

Offline

#2 2024-08-09 07:56:54

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,506
Website

Re: Regression in TRttiCustomProp.SetValueVariant()

This is documented as such:

    // - Source is eventually cleared via VarClearProc()

But what is the stack trace at that place?
Do you use a getter/setter function?

Do you call TRttiCustomProp.GetRttiVarData before calling SetValueVariant?
This is plain wrong.

Note that in our regression tests, we validate the copy of an enumerate.
I included the validation with getter/setter too: https://github.com/synopse/mORMot2/commit/806605e0

Anyway, Source should be a true variant, not a varAny as from TRttiVarData.
For instance, TRttiCustomProp.GetValueVariant() should detect varAny for tkEnumeration, then use an intermediate Int64 for the copy.

Offline

#3 2024-08-09 08:23:01

oz
Member
Registered: 2015-09-02
Posts: 98

Re: Regression in TRttiCustomProp.SetValueVariant()

I just found the problem at my side. The enum value has been read using Prop.GetValue(); instead of Prop.GetValueVariant(); Using Prop.GetValueVariant() works as expected.
Thanks.

Offline

#4 2024-08-09 08:27:07

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,506
Website

Re: Regression in TRttiCustomProp.SetValueVariant()

Prop.GetValue() does not exist any more: it is now called Prop.GetRttiVarData() to avoid such confusion.

Edit:
I have introduced TSynVarData to avoid any confusion, and use TRttiVarData only for internal usage.
https://github.com/synopse/mORMot2/commit/be22cbaf

Offline

Board footer

Powered by FluxBB