You are not logged in.
Pages: 1
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
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
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
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
Pages: 1