mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-09 01:28:19 +02:00
TFileSearcher: first try at detecting circular links (outside the current tree).
This commit is contained in:
parent
de6b521614
commit
65e0930568
@ -795,6 +795,7 @@ begin
|
|||||||
FMaskSeparator := ';';
|
FMaskSeparator := ';';
|
||||||
FPathSeparator := ';';
|
FPathSeparator := ';';
|
||||||
FFollowSymLink := True;
|
FFollowSymLink := True;
|
||||||
|
FCircularLinkDetection := False;
|
||||||
FFileAttribute := faAnyFile;
|
FFileAttribute := faAnyFile;
|
||||||
FDirectoryAttribute := faDirectory;
|
FDirectoryAttribute := faDirectory;
|
||||||
FSearching := False;
|
FSearching := False;
|
||||||
@ -819,7 +820,7 @@ var
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
P: String;
|
P, FQDir, LinkTarget: String;
|
||||||
PathInfo: TSearchRec;
|
PathInfo: TSearchRec;
|
||||||
begin
|
begin
|
||||||
P := APath + AllDirectoryEntriesMask;
|
P := APath + AllDirectoryEntriesMask;
|
||||||
@ -862,22 +863,49 @@ var
|
|||||||
repeat
|
repeat
|
||||||
if (PathInfo.Name = '.') or (PathInfo.Name = '..') or
|
if (PathInfo.Name = '.') or (PathInfo.Name = '..') or
|
||||||
(PathInfo.Name = '') or ((PathInfo.Attr and faDirectory) = 0) or
|
(PathInfo.Name = '') or ((PathInfo.Attr and faDirectory) = 0) or
|
||||||
(not FFollowSymLink and FileIsSymlink(APath + PathInfo.Name)) or
|
|
||||||
(FileIsSymlink(APath + PathInfo.Name) and
|
|
||||||
( //try to detect the simples case of a circular link
|
|
||||||
//is the link "up or down the current tree": infinite loop if we follow
|
|
||||||
FileIsInPath(ExpandFilenameUTF8(ReadAllLinks(APath+PathInfo.Name,False)),ExpandFilenameUTF8(APath)) or
|
|
||||||
FileIsInPath(ExpandFilenameUTF8(APath),ExpandFilenameUTF8(ReadAllLinks(APath+PathInfo.Name,False))))
|
|
||||||
) or
|
|
||||||
(not AcceptDir(AppendPathDelim(ExpandFilenameUtf8(APath + PathInfo.Name))))
|
(not AcceptDir(AppendPathDelim(ExpandFilenameUtf8(APath + PathInfo.Name))))
|
||||||
then Continue;
|
then
|
||||||
|
Continue;
|
||||||
|
if Assigned(VisitedDirs) then
|
||||||
|
begin
|
||||||
|
FQDir := ExpandFilenameUTF8(APath + PathInfo.Name);
|
||||||
|
{$ifdef CaseInsensitiveFilenames}
|
||||||
|
FQDir := Utf8LowerCase(FQDir);
|
||||||
|
{$endif}
|
||||||
|
end;
|
||||||
|
|
||||||
|
// deal with symlinks separately, avoid excessive calls to ExpandFilenameUTF8 and
|
||||||
|
// have a less convoluted boolean expression above here
|
||||||
|
if (FileIsSymlink(APath + PathInfo.Name)) then
|
||||||
|
begin
|
||||||
|
if not FFollowSymlink then
|
||||||
|
Continue;
|
||||||
|
LinkTarget := ReadAllLinks(APath+PathInfo.Name,False);
|
||||||
|
if (LinkTarget = '') then //broken link
|
||||||
|
Continue;
|
||||||
|
LinkTarget := ExpandFilenameUTF8(LinkTarget);
|
||||||
|
{$ifdef CaseInsensitiveFilenames}
|
||||||
|
LinkTarget := Utf8LowerCase(LinkTarget);
|
||||||
|
{$endif}
|
||||||
|
if
|
||||||
|
//is the link "up or down the current tree": infinite loop if we follow
|
||||||
|
FileIsInPath(LinkTarget,ExpandFilenameUTF8(APath)) or
|
||||||
|
FileIsInPath(ExpandFilenameUTF8(APath),LinkTarget) or
|
||||||
|
//did we already visit that directory, assuming we actually do check for that
|
||||||
|
(Assigned(VisitedDirs) and Assigned(VisitedDirs.Find(LinkTarget)))
|
||||||
|
then
|
||||||
|
Continue;
|
||||||
|
if Assigned(VisitedDirs) then
|
||||||
|
FQDir := LinkTarget;
|
||||||
|
end;
|
||||||
|
|
||||||
FPath := APath;
|
FPath := APath;
|
||||||
FLevel := ALevel;
|
FLevel := ALevel;
|
||||||
FFileInfo := PathInfo;
|
FFileInfo := PathInfo;
|
||||||
DoDirectoryEnter;
|
DoDirectoryEnter;
|
||||||
if not FSearching then Break;
|
if not FSearching then Break;
|
||||||
|
if Assigned(VisitedDirs) then
|
||||||
|
VisitedDirs.Add(FQDir,'');
|
||||||
DoSearch(AppendPathDelim(APath + PathInfo.Name), Succ(ALevel));
|
DoSearch(AppendPathDelim(APath + PathInfo.Name), Succ(ALevel));
|
||||||
|
|
||||||
until (FindNextUTF8(PathInfo) <> 0);
|
until (FindNextUTF8(PathInfo) <> 0);
|
||||||
@ -893,6 +921,10 @@ var
|
|||||||
OtherDir: String;
|
OtherDir: String;
|
||||||
begin
|
begin
|
||||||
if FSearching then RaiseSearchingError;
|
if FSearching then RaiseSearchingError;
|
||||||
|
if FCircularLinkDetection and FFollowSymLink then
|
||||||
|
VisitedDirs := TFPStringHashTable.Create
|
||||||
|
else
|
||||||
|
VisitedDirs := nil;
|
||||||
{$ifdef windows}
|
{$ifdef windows}
|
||||||
MaskList := TWindowsMaskList.Create(ASearchMask, FMaskSeparator, CaseSensitive);
|
MaskList := TWindowsMaskList.Create(ASearchMask, FMaskSeparator, CaseSensitive);
|
||||||
{$else}
|
{$else}
|
||||||
@ -944,6 +976,8 @@ begin
|
|||||||
SearchDirectories.Free;
|
SearchDirectories.Free;
|
||||||
FSearching := False;
|
FSearching := False;
|
||||||
MaskList.Free;
|
MaskList.Free;
|
||||||
|
if Assigned(VisitedDirs) then
|
||||||
|
VisitedDirs.Free;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -29,7 +29,8 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes, SysUtils, StrUtils,
|
Classes, SysUtils, StrUtils,
|
||||||
// LazUtils
|
// LazUtils
|
||||||
Masks, LazUTF8, LazFileUtils;
|
Masks, LazUTF8, LazFileUtils,
|
||||||
|
Contnrs;
|
||||||
|
|
||||||
{$IF defined(Windows) or defined(darwin) or defined(HASAMIGA)}
|
{$IF defined(Windows) or defined(darwin) or defined(HASAMIGA)}
|
||||||
{$define CaseInsensitiveFilenames}
|
{$define CaseInsensitiveFilenames}
|
||||||
@ -138,6 +139,8 @@ type
|
|||||||
FDirectoryAttribute: Word;
|
FDirectoryAttribute: Word;
|
||||||
FOnQueryFileFound: TQueryFileFoundEvent;
|
FOnQueryFileFound: TQueryFileFoundEvent;
|
||||||
FOnQueryDirectoryFound: TQueryDirectoryFoundEvent;
|
FOnQueryDirectoryFound: TQueryDirectoryFoundEvent;
|
||||||
|
FCircularLinkDetection: Boolean;
|
||||||
|
VisitedDirs: TFPStringHashTable;
|
||||||
procedure RaiseSearchingError;
|
procedure RaiseSearchingError;
|
||||||
protected
|
protected
|
||||||
procedure DoDirectoryEnter; virtual;
|
procedure DoDirectoryEnter; virtual;
|
||||||
@ -155,6 +158,7 @@ type
|
|||||||
property FollowSymLink: Boolean read FFollowSymLink write FFollowSymLink;
|
property FollowSymLink: Boolean read FFollowSymLink write FFollowSymLink;
|
||||||
property FileAttribute: Word read FFileAttribute write FFileAttribute default faAnyfile;
|
property FileAttribute: Word read FFileAttribute write FFileAttribute default faAnyfile;
|
||||||
property DirectoryAttribute: Word read FDirectoryAttribute write FDirectoryAttribute default faDirectory;
|
property DirectoryAttribute: Word read FDirectoryAttribute write FDirectoryAttribute default faDirectory;
|
||||||
|
property CircularLinkdetection: Boolean read FCircularLinkdetection write FCircularLinkdetection default False;
|
||||||
property OnDirectoryFound: TDirectoryFoundEvent read FOnDirectoryFound write FOnDirectoryFound;
|
property OnDirectoryFound: TDirectoryFoundEvent read FOnDirectoryFound write FOnDirectoryFound;
|
||||||
property OnFileFound: TFileFoundEvent read FOnFileFound write FOnFileFound;
|
property OnFileFound: TFileFoundEvent read FOnFileFound write FOnFileFound;
|
||||||
property OnDirectoryEnter: TDirectoryEnterEvent read FOnDirectoryEnter write FOnDirectoryEnter;
|
property OnDirectoryEnter: TDirectoryEnterEvent read FOnDirectoryEnter write FOnDirectoryEnter;
|
||||||
|
Loading…
Reference in New Issue
Block a user