TPath.HasValidPathChars
被完全破壞。這是它的實現:
class function TPath.HasValidPathChars(const Path: string;
const UseWildcards: Boolean): Boolean;
var
PPath: PChar;
PathLen: Integer;
Ch: Char;
I: Integer;
begin
// Result will become True if an invalid path char is found
{$IFDEF MSWINDOWS}
I := GetPosAfterExtendedPrefix(Path) - 1;
{$ENDIF MSWINDOWS}
{$IFDEF POSIX}
I := 0;
{$ENDIF POSIX}
PPath := PChar(Path);
PathLen := Length(Path);
Result := False;
while (not Result) and (i < PathLen) do
begin
Ch := PPath[i];
if not IsValidPathChar(Ch) then
if UseWildcards then
if not IsPathWildcardChar(Ch) then
Result := True
else
Inc(i)
else
Result := True
else
Inc(i);
end;
Result := not Result;
end;
關鍵是要撥打IsValidPathChar
。我們來看看它的功能。現在
class function TPath.IsValidPathChar(const AChar: Char): Boolean;
begin
Result := not IsCharInOrderedArray(AChar, FInvalidPathChars);
end;
,FInvalidPathChars
被定義爲:
FInvalidPathChars := TCharArray.Create(
#0, #1, #2, #3, #4, #5, #6, #7, #8, #9, #10, #11, #12,
#13, #14, #15, #16, #17, #18, #19, #20, #21, #22, #23, #24,
#25, #26, #27, #28, #29, #30, #31,
'"', '<', '>', '|'); // DO NOT LOCALIZE;
即,小於32所有序,並且"
,<
,>
和|
。
我們還需要了解IsPathWildcardChar
的功能。
class function TPath.IsPathWildcardChar(const AChar: Char): Boolean;
begin
Result := IsCharInOrderedArray(AChar, FPathWildcardChars);
end;
其中FPathWildcardChars
是:
FPathWildcardChars := TCharArray.Create('*', '/', ':', '?', '\'); // DO NOT LOCALIZE;
現在,回到TPath.HasValidPathChars
。讓我們考慮這個if
聲明:
if not IsValidPathChar(Ch) then
條件not IsValidPathChar(Ch)
評估爲True
時IsValidPathChar(Ch)
是False
。如果Ch
在FInvalidPathChars
中,會發生哪種情況。也就是說,如果Ch
具有小於32的序數,或者是"
,<
,>
和|
中的一個。
您的測試字符串是'C:\test\test?\'
而實際上這些字符都不在FInvalidPathChars
之內。這意味着if not IsValidPathChar(Ch) then
聲明中的條件總是評估False
。因此,即使你的字符串包含通配符,它永遠不能達到的後續測試:
if UseWildcards then
人們很容易得出結論:HasValidPathChars
不論輸入參數UseWildcards
的值返回相同的值。如果您對分析的任何疑問,這個程序應該驅散它:
{$APPTYPE CONSOLE}
uses
System.SysUtils,
System.IOUtils;
procedure Main;
var
Ch: Char;
begin
for Ch := low(Ch) to high(Ch) do
if TPath.HasValidPathChars(Ch, False)<>TPath.HasValidPathChars(Ch, True) then
Writeln('different at #' + IntToStr(ord(Ch)));
Writeln('finished');
end;
begin
Main;
Readln;
end.
這看起來像在這又一功能害怕IOUtils
單元已被不正當地實施,而不是測試。
我提交了一個報告錯誤:RSP-18696。
基於已經偶然發現了IOUtils
許多這樣的問題,我的經驗是,該單位不被信任。我不會使用它。找到解決問題的另一種方法。
不應拒絕'?',因爲路徑可以在Windows上包含問號。示例:https://superuser.com/q/1069055 –
該超級用戶的帖子還指出:「您不能使用這些類型的路徑來訪問用戶空間中的文件或目錄,只有某些底層系統組件可用於對象管理器路徑「。所以從這個觀點來看,'?'是一個無效的路徑字符。 – gabr
@GünthertheBeautiful - 文章說,\ ??是一個有效的路徑,所以HasValidPathChars應該檢查'??'如果找到了正確的模式(\ ??),並返回true,並且在有單個'?'時返回false。 – Ampere