From 69d65e704dc937f1edac42cae318190b840c37e1 Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 1 Mar 2025 11:26:17 +0100 Subject: [PATCH] SynEdit: Initialize "Result" var of managed type (avoid mem re-alloc in case caller passes non-nil). Issue #41461 (see notes). --- components/synedit/lazsynedittext.pas | 3 ++- components/synedit/syneditexport.pas | 4 +++- components/synedit/syneditfoldedview.pp | 12 ++++++++---- components/synedit/syneditmarkuphighall.pp | 3 ++- components/synedit/syneditpointclasses.pas | 6 ++++-- components/synedit/syneditsearch.pp | 6 +++--- components/synedit/synedittextdyntabexpander.pas | 1 + components/synedit/synedittexttabexpander.pas | 1 + components/synedit/synhighlighterpas.pp | 7 +------ components/synedit/synhighlighterposition.pas | 6 +----- components/synedit/synpluginsyncroedit.pp | 3 +-- components/synedit/test/testbase.pas | 1 + components/synedit/test/testbasicsynedit.pas | 8 ++++---- .../synedit/test/testmarkupfoldcoloring.pas | 16 ++++++++-------- components/synedit/test/testwordwrap.pas | 4 ++-- 15 files changed, 42 insertions(+), 39 deletions(-) diff --git a/components/synedit/lazsynedittext.pas b/components/synedit/lazsynedittext.pas index e4fe27f801..fe6cc80267 100644 --- a/components/synedit/lazsynedittext.pas +++ b/components/synedit/lazsynedittext.pas @@ -1156,9 +1156,10 @@ end; function TSynEditStrings.GetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer): TPhysicalCharWidths; begin - SetLength(Result{%H-}, LineLen); + Result := nil; if LineLen = 0 then exit; + SetLength(Result{%H-}, LineLen); DoGetPhysicalCharWidths(Line, LineLen, Index, @Result[0]); end; diff --git a/components/synedit/syneditexport.pas b/components/synedit/syneditexport.pas index efb6979199..59aa836250 100644 --- a/components/synedit/syneditexport.pas +++ b/components/synedit/syneditexport.pas @@ -459,6 +459,7 @@ end; {$IFDEF SYN_MBCSSUPPORT} function TSynCustomExporter.ReplaceMBCS(Char1, Char2: char): string; begin + Result := ''; SetLength(Result, 2); Result[1] := Char1; Result[2] := Char2; @@ -474,11 +475,12 @@ var begin IsSpace := TRUE; if AToken <> '' then begin + Result := ''; SrcLen := Length(AToken); ISrc := 1; DestLen := SrcLen; IDest := 1; - SetLength(Result{%H-}, DestLen); + SetLength(Result, DestLen); while ISrc <= SrcLen do begin c := AToken[ISrc]; IsSpace := IsSpace and (c = ' '); diff --git a/components/synedit/syneditfoldedview.pp b/components/synedit/syneditfoldedview.pp index 56e7579a82..a38676bfc9 100644 --- a/components/synedit/syneditfoldedview.pp +++ b/components/synedit/syneditfoldedview.pp @@ -1266,8 +1266,9 @@ end; function TSynEditFoldExportStream.PeakString(ALen: Integer): String; begin + Result := ''; If not(FPos+ ALen <= FLen) then - exit(''); + exit; SetLength(Result, ALen); if ALen > 0 then System.Move((FMem + FPos)^, Result[1], ALen); @@ -1284,8 +1285,9 @@ end; function TSynEditFoldExportStream.ReadString(ALen: Integer): String; begin + Result := ''; If not(FPos+ ALen <= FLen) then - exit(''); + exit; SetLength(Result, ALen); if ALen > 0 then System.Move((FMem + FPos)^, Result[1], ALen); @@ -3126,7 +3128,8 @@ var i: Integer; begin i := FoldOpenCount(ALine); - SetLength(Result{%H-}, i); + Result := nil; + SetLength(Result, i); while i > 0 do begin dec(i); Result[i] := InfoForFoldAtTextIndex(ALine, i, False, NeedLen); @@ -4609,9 +4612,10 @@ var end; begin + Result := Default(TFoldViewNodeInfo); hl := TSynCustomFoldHighlighter(HighLighter); if not assigned(hl) then - exit; // ToDo: Initialize Result + exit; nd.LogXStart := 0; nd.LogXEnd := 0; diff --git a/components/synedit/syneditmarkuphighall.pp b/components/synedit/syneditmarkuphighall.pp index 41bc297cb6..dce2c614d6 100644 --- a/components/synedit/syneditmarkuphighall.pp +++ b/components/synedit/syneditmarkuphighall.pp @@ -914,7 +914,8 @@ procedure TSynSearchDictionary.BuildDictionary; memory consumption, since they have 4 continuation bytes (array size 64) to bring down the average. *) - SetLength(Result{%H-}, Length(ATerm)); + Result := ''; + SetLength(Result, Length(ATerm)); for i := 1 to Length(ATerm) do begin c := ATerm[i]; if c < #128 diff --git a/components/synedit/syneditpointclasses.pas b/components/synedit/syneditpointclasses.pas index 7dc47755d2..b953f3787d 100644 --- a/components/synedit/syneditpointclasses.pas +++ b/components/synedit/syneditpointclasses.pas @@ -1835,9 +1835,11 @@ function TSynEditSelection.GetSelText : string; begin SrcLen := Length(S); DstLen := Index + Count; - if SrcLen >= DstLen then - Result := Copy(S, Index, Count) + if SrcLen >= DstLen then begin + Result := Copy(S, Index, Count); + end else begin + Result := ''; SetLength(Result, DstLen); P := PChar(Result); StrPCopy(P, Copy(S, Index, Count)); diff --git a/components/synedit/syneditsearch.pp b/components/synedit/syneditsearch.pp index 12b0369bf7..0239f7d258 100644 --- a/components/synedit/syneditsearch.pp +++ b/components/synedit/syneditsearch.pp @@ -652,10 +652,10 @@ var //DebugLn(['GetTextRange StartPos=',dbgs(StartPos),' EndPos=',dbgs(EndPos)]); //DebugLn(Lines.Text); - if EndPos.Y0 then - System.Move(fLine[fTokenPos],Result[1],Len); + SetString(Result, @fLine[fTokenPos], Run - fTokenPos); end; procedure TSynPasSyn.GetTokenEx(out TokenStart: PChar; out TokenLength: integer); diff --git a/components/synedit/synhighlighterposition.pas b/components/synedit/synhighlighterposition.pas index 7a19e28d85..bcfc2c649d 100644 --- a/components/synedit/synhighlighterposition.pas +++ b/components/synedit/synhighlighterposition.pas @@ -188,12 +188,8 @@ begin end; function TSynPositionHighlighter.GetToken: string; -var - Len: LongInt; begin - Len := fTokenEnd - fTokenPos; - SetLength(Result{%H-},Len); - System.Move(fLine[fTokenPos],Result[1],Len); + SetString(Result, @fLine[fTokenPos], fTokenEnd - fTokenPos); end; procedure TSynPositionHighlighter.GetTokenEx(out TokenStart: PChar; diff --git a/components/synedit/synpluginsyncroedit.pp b/components/synedit/synpluginsyncroedit.pp index 45295bb66f..5efe5f3daf 100644 --- a/components/synedit/synpluginsyncroedit.pp +++ b/components/synedit/synpluginsyncroedit.pp @@ -958,8 +958,7 @@ var begin TCustomSynEdit(FriendEdit).GetHighlighterAttriAtRowColEx(APos, Ctx, FLastContextLine = APos.Y); FLastContextLine := APos.Y; - SetLength(Result{%H-}, SizeOf(Integer)); - PInteger(@Result[1])^ := Ctx; + SetString(Result, PChar(@Ctx), SizeOf(Ctx)); end; procedure TSynPluginSyncroEdit.SetGutterGlyph(const AValue: TBitmap); diff --git a/components/synedit/test/testbase.pas b/components/synedit/test/testbase.pas index a00a6f761b..8c1de312ee 100644 --- a/components/synedit/test/testbase.pas +++ b/components/synedit/test/testbase.pas @@ -577,6 +577,7 @@ var i, j, k: Integer; s: String; begin + Result := nil; SetLength(Result, length(Lines)); for i := low(Lines) to high(Lines) do Result[i-low(Lines)] := Lines[i]; diff --git a/components/synedit/test/testbasicsynedit.pas b/components/synedit/test/testbasicsynedit.pas index b8b8c96e49..49fadfceb2 100644 --- a/components/synedit/test/testbasicsynedit.pas +++ b/components/synedit/test/testbasicsynedit.pas @@ -81,7 +81,7 @@ end; function TTestBasicSynEdit.TestLines1: TStringArray; begin - SetLength(Result, 16); + SetLength(Result{%H-}, 16); // 1 6 11 14 Result[0] := 'Some text to test'; //1 // 1 5 9 @@ -111,7 +111,7 @@ end; function TTestBasicSynEdit.TestLines2: TStringArray; begin - SetLength(Result, 7); + SetLength(Result{%H-}, 7); // 1 6 11 14 Result[0] := 'abc def ghi'; // 1 Result[1] := 'ABC DEF GHI'; // 2 @@ -307,7 +307,7 @@ var function TestText1: TStringArray; begin - SetLength(Result, 4); + SetLength(Result{%H-}, 4); Result[0] := 'abc'; Result[1] := 'öbc'; Result[2] := #9'abc'; @@ -2378,7 +2378,7 @@ end; procedure TTestBasicSynEdit.TestSearchReplace; function TestText1: TStringArray; begin - SetLength(Result, 9); + SetLength(Result{%H-}, 9); Result[0] := 'aaaa'; Result[1] := 'xx11'; Result[2] := 'cccc'; diff --git a/components/synedit/test/testmarkupfoldcoloring.pas b/components/synedit/test/testmarkupfoldcoloring.pas index ac5d594851..63f55ad9ff 100644 --- a/components/synedit/test/testmarkupfoldcoloring.pas +++ b/components/synedit/test/testmarkupfoldcoloring.pas @@ -78,7 +78,7 @@ implementation function CopyArray(a: array of Integer): TIntArray; begin - SetLength(Result, Length(a)); + SetLength(Result{%H-}, Length(a)); if Length(a) > 0 then move(a[0], Result[0], Length(a) * SizeOf(a[0])); end; @@ -279,7 +279,7 @@ end; function TTestMarkupFoldColoring.TestText1: TStringArray; begin - SetLength(Result, 26); + SetLength(Result{%H-}, 26); Result[ 0] := 'program Foo;'; Result[ 1] := ''; Result[ 2] := 'procedure a;'; @@ -310,7 +310,7 @@ end; function TTestMarkupFoldColoring.TestText2: TStringArray; begin - SetLength(Result, 20); + SetLength(Result{%H-}, 20); Result[0] := 'program a;'; Result[1] := 'procedure TEditorFrame.NotifChanged(Sender: TObject);'; Result[2] := 'begin'; @@ -337,7 +337,7 @@ function TTestMarkupFoldColoring.TestTextEditIfThen(out ExpLines, var i: Integer; begin - SetLength(Result, 29); + SetLength(Result{%H-}, 29); SetLength(ExpLines, 29); SetLength(ExpLinesEdited, 18); // stop at bad line // HL may change.... Result[ 0] := 'program a;'; @@ -405,7 +405,7 @@ end; function TTestMarkupFoldColoring.TestTextMultiLineIfIndent: TStringArray; begin - SetLength(Result, 29); + SetLength(Result{%H-}, 29); Result[ 0] := 'program a;'; Result[ 1] := 'procedure foo;'; Result[ 2] := 'begin'; @@ -439,7 +439,7 @@ end; function TTestMarkupFoldColoring.TestTextInval1: TStringArray; begin - SetLength(Result, 20); + SetLength(Result{%H-}, 20); Result[0] := 'procedure'; Result[1] := 'begin'; Result[2] := ''; @@ -466,7 +466,7 @@ function TTestMarkupFoldColoring.TestTextScroll1: TStringArray; var i: Integer; begin - SetLength(Result, 112); + SetLength(Result{%H-}, 112); Result[0] := 'unit TestUnit;'; Result[1] := ''; Result[2] := '{$mode objfpc}{$H+}'; @@ -517,7 +517,7 @@ end; function TTestMarkupFoldColoring.TestTextCaseScroll1(out ExpLines: TTestLineMarkupResults): TStringArray; begin - SetLength(Result, 44+30); + SetLength(Result{%H-}, 44+30); SetLength(ExpLines, 44); Result[ 0] := 'program a;'; Result[ 1] := 'begin'; diff --git a/components/synedit/test/testwordwrap.pas b/components/synedit/test/testwordwrap.pas index 639f74d44e..e4ed63c0f7 100644 --- a/components/synedit/test/testwordwrap.pas +++ b/components/synedit/test/testwordwrap.pas @@ -190,7 +190,7 @@ function FillArray(AFrom, ATo: integer; AIncrease: Integer = 1): TIntArray; var i: Integer; begin - SetLength(Result, ATo - AFrom + 1); + SetLength(Result{%H-}, ATo - AFrom + 1); for i := 0 to high(Result) do Result[i] := AFrom + i * AIncrease; end; @@ -210,7 +210,7 @@ function ViewedExp(AFirstViewedIdx: TLineIdx; var i, j: Integer; begin - SetLength(Result, Length(ALines)); + SetLength(Result{%H-}, Length(ALines)); j := 0; for i := 0 to Length(ALines) - 1 do begin if (i > 0) and (ALines[i].SubIdx = 0) then begin