From 6fe3a481783ceb096747108855f9ee3d69b1e5fb Mon Sep 17 00:00:00 2001 From: Arnaud Bouchez Date: Tue, 9 Jan 2024 22:21:06 +0100 Subject: [PATCH] fixed NameChange() with '' destination property name --- src/core/mormot.core.json.pas | 8 ++++---- src/core/mormot.core.rtti.pas | 28 +++++++++++++++++++--------- src/mormot.commit.inc | 2 +- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/core/mormot.core.json.pas b/src/core/mormot.core.json.pas index ec160d020..2e92b05ca 100644 --- a/src/core/mormot.core.json.pas +++ b/src/core/mormot.core.json.pas @@ -8081,7 +8081,7 @@ function _JL_DynArray_FromResults(Data: PPointer; var Ctxt: TJsonParserContext): arrinfo := Ctxt.Info; iteminfo := arrinfo.ArrayRtti; if (iteminfo = nil) or - (iteminfo.Props.Count = 0) then + (iteminfo.Props.CountNonVoid = 0) then exit; // expect an array of objects (classes or records) SetLength(props, fieldcount); for f := 0 to fieldcount - 1 do @@ -8092,8 +8092,8 @@ function _JL_DynArray_FromResults(Data: PPointer; var Ctxt: TJsonParserContext): prop := nil; if Ctxt.ValueLen <> 0 then begin - prop := FindCustomProp(pointer(iteminfo.props.List), - Ctxt.Value, Ctxt.ValueLen, iteminfo.props.Count); + prop := FindCustomProp(pointer(iteminfo.Props.List), + Ctxt.Value, Ctxt.ValueLen, iteminfo.Props.Count); if (prop = nil) and (itemInfo.ValueRtlClass = vcObjectWithID) and (PInteger(Ctxt.Value)^ and $dfdfdfdf = @@ -10600,7 +10600,7 @@ function TRttiJson.ValueByPath(var Data: pointer; Path: PUtf8Char; if StrEquAW(@n[1], PPWord(Data)^) then exit; else - if result.Props.Count <> 0 then + if result.Props.CountNonVoid <> 0 then begin // search name in rkRecord/rkObject or rkClass properties p := FindCustomProp( diff --git a/src/core/mormot.core.rtti.pas b/src/core/mormot.core.rtti.pas index eb90a7b38..d25988fa2 100644 --- a/src/core/mormot.core.rtti.pas +++ b/src/core/mormot.core.rtti.pas @@ -2163,6 +2163,7 @@ TRttiCustomProp = record TRttiCustomProp = object {$endif USERECORDWITHMETHODS} private + fOrigName: RawUtf8; // as set by InternalAdd() function InitFrom(RttiProp: PRttiProp): PtrInt; function ValueIsVoidGetter(Data: pointer): boolean; procedure GetValueDirect(Data: PByte; out RVD: TRttiVarData); @@ -6799,6 +6800,7 @@ function TRttiCustomProp.InitFrom(RttiProp: PRttiProp): PtrInt; else OffsetSet := -1; Name := ToUtf8(RttiProp^.Name^); + fOrigName := Name; Prop := RttiProp; if rcfHasRttiOrd in Value.Cache.Flags then OrdinalDefault := RttiProp.Default @@ -6814,7 +6816,7 @@ function TRttiCustomProp.NameMatch(P: PUtf8Char; Len: PtrInt): boolean; begin // inlined IdemPropNameUSameLenNotNull() result := false; n := pointer(Name); - if (n = nil) or + if (n = nil) or // Name='' after NameChange() (PStrLen(n - _STRLEN)^ <> Len) then exit; pointer(Len) := @PUtf8Char(n)[Len - SizeOf(cardinal)]; @@ -7201,8 +7203,9 @@ function FindCustomProp(p: PRttiCustomProp; name: pointer; namelen: TStrLen; p2 := name; repeat // inlined IdemPropNameUSameLenNotNull(p, name, namelen) - p1 := pointer(result^.Name); // Name<>'' so p1<>nil - if PStrLen(p1 - _STRLEN)^ = namelen then + p1 := pointer(result^.Name); + if (p1 <> nil) and // Name='' after NameChange() + (PStrLen(p1 - _STRLEN)^ = namelen) then begin l := @p1[namelen - SizeOf(cardinal)]; dec(p2, PtrUInt(p1)); @@ -7292,12 +7295,11 @@ procedure TRttiCustomProps.NameChanges(const Old, New: array of RawUtf8); if high(Old) <> high(New) then raise ERttiException.CreateUtf8( 'NameChanges(%,%) fields count', [high(Old), high(New)]); - // first reset the names from RTTI (if available) + // first reset the names p := pointer(List); for i := 1 to Count do begin - if p^.Prop <> nil then - p^.Name := ToUtf8(p^.Prop^.Name^); + p^.Name := p^.fOrigName; // back to original inc(p); end; // customize field names @@ -7328,6 +7330,7 @@ procedure TRttiCustomProps.InternalAdd(Info: PRttiInfo; Offset: PtrInt; begin MoveFast(List[0], List[1], SizeOf(List[0]) * Count); pointer(List[0].Name) := nil; // avoid GPF below + pointer(List[0].fOrigName) := nil; end; NamesAsJsonArray := '"' + PropName + '",' + NamesAsJsonArray; n := 0; @@ -7345,6 +7348,7 @@ procedure TRttiCustomProps.InternalAdd(Info: PRttiInfo; Offset: PtrInt; OffsetGet := Offset; OffsetSet := Offset; Name := PropName; + fOrigName := PropName; Prop := nil; OrdinalDefault := NO_DEFAULT; Stored := rpsTrue; @@ -7361,7 +7365,11 @@ function TRttiCustomProps.FromTextPrepare(const PropName: RawUtf8): integer; result := Count; inc(Count); SetLength(List, Count); - List[result].Name := PropName; + with List[result] do + begin + Name := PropName; + fOrigName := PropName; + end; end; function TRttiCustomProps.AdjustAfterAdded: TRttiCustomFlags; @@ -7508,6 +7516,7 @@ procedure TRttiCustomProps.SetFromRecordExtendedRtti(RecordInfo: PRttiInfo); OffsetGet := f^.Offset; OffsetSet := f^.Offset; Name := ToUtf8(f^.Name^); + fOrigName := Name; OrdinalDefault := NO_DEFAULT; Stored := rpsTrue; inc(f); @@ -8093,7 +8102,7 @@ function TRttiCustom.PropFindByPath(var Data: pointer; FullName: PUtf8Char; result := nil; if (rc = nil) or (Data = nil) or - (rc.Props.Count = 0) then + (rc.Props.CountNonVoid = 0) then exit; GetNextItemShortString(FullName, @n, PathDelim); if n[0] in [#0, #254] then @@ -9309,7 +9318,8 @@ function SetObjectFromExecutableCommandLine(Value: TObject; p := pointer(rc.Props.List); for i := 1 to rc.Props.Count do begin - if not (p^.Value.Kind in rkComplexTypes) then + if (p^.Name <> '') and + not (p^.Value.Kind in rkComplexTypes) then begin desc := ''; dolower := false; diff --git a/src/mormot.commit.inc b/src/mormot.commit.inc index 837df4e6d..5c890c6e8 100644 --- a/src/mormot.commit.inc +++ b/src/mormot.commit.inc @@ -1 +1 @@ -'2.2.6652' +'2.2.6653'