IDE, FindInFiles: Prevent corrupt data in case UTF8 characters have size mismatch in upper/lower case. Issue #40893, patch by n7800.

This commit is contained in:
Juha 2024-04-13 13:35:55 +03:00
parent 12af15e8ef
commit 8374cbc333
2 changed files with 34 additions and 0 deletions

View File

@ -4191,6 +4191,10 @@ resourcestring
lisDirectories = 'Directories';
lisFindFileFileMask = 'Fi&le mask';
lisFindFileIncludeSubDirectories = 'Include &sub directories';
lisFindFileReplacementIsNotPossible = 'This file contains characters that have '
+ 'different lengths in upper and lower case. The current implementation does '
+ 'not allow for correct replacement in this case (but you can use '
+ 'case-sensitive replacement). This file will have to be skipped:';
// package manager
lisPkgMangPackage = 'Package: %s';

View File

@ -529,6 +529,7 @@ var
Src: String;
NewMatchStartPos: PtrInt;
NewMatchEndPos: PtrInt;
i, l, n1, n2: Integer;
begin
//debugln(['SearchInText TheFileName=',TheFileName,' SearchFor=',SearchFor,'" ReplaceText=',ReplaceText,'"']);
@ -584,6 +585,35 @@ begin
CaseFile:=TSourceLog.Create(UTF8UpperCase(OriginalFile.Source));
TempSearch:=UTF8UpperCase(TempSearch);
Src:=CaseFile.Source;
// Comparing character lengths after UTF8UpperCase:
// their difference can lead to damage to the text when replacing
// issue #40893
if sesoReplace in Flags then
begin
// length of strings in bytes (not use UTF8Length)
n1 := length(OriginalFile.Source);
n2 := length(CaseFile.Source);
l := n1; // assumed n1=n2
i := 1;
while (n1 = n2) and (i <= l) do
begin
// length of characters in bytes
n1 := UTF8CodepointSize(@OriginalFile.Source[i]);
n2 := UTF8CodepointSize(@CaseFile.Source[i]);
inc(i, n1); // assumed n1=n2
end;
if n1 <> n2 then
begin
if IDEMessageDialog(lisCCOWarningCaption,
lisFindFileReplacementIsNotPossible + LineEnding + LineEnding + TheFileName,
mtWarning, [mbOK, mbCancel]) = mrCancel
then
DoAbort;
exit(mrAbort);
end;
end;
end else
Src:=OriginalFile.Source;
end;