TPath.HasValidPathChars
hoàn toàn bị hỏng. Đây là triển khai của nó:
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;
Điểm quan trọng là gọi tới IsValidPathChar
. Hãy nhìn vào những gì có.
class function TPath.IsValidPathChar(const AChar: Char): Boolean;
begin
Result := not IsCharInOrderedArray(AChar, FInvalidPathChars);
end;
Bây giờ, FInvalidPathChars
được định nghĩa là:
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;
Đó là, tất cả ordinals ít hơn 32 tuổi, và "
, <
, >
và |
.
Chúng tôi cũng cần hiểu những gì IsPathWildcardChar
thực hiện.
class function TPath.IsPathWildcardChar(const AChar: Char): Boolean;
begin
Result := IsCharInOrderedArray(AChar, FPathWildcardChars);
end;
đâu FPathWildcardChars
là:
FPathWildcardChars := TCharArray.Create('*', '/', ':', '?', '\'); // DO NOT LOCALIZE;
Bây giờ, trở lại TPath.HasValidPathChars
. Hãy xem xét if
tuyên bố này:
if not IsValidPathChar(Ch) then
Điều kiện not IsValidPathChar(Ch)
đánh giá để True
khi IsValidPathChar(Ch)
là False
. Điều này xảy ra nếu Ch
nằm trong số FInvalidPathChars
. Đó là nếu Ch
có thứ tự dưới 32 hoặc là một trong số "
, <
, >
và |
.
Chuỗi kiểm tra của bạn là 'C:\test\test?\'
và trên thực tế không có ký tự nào trong số này là FInvalidPathChars
. Điều này có nghĩa là điều kiện trong câu lệnh if not IsValidPathChar(Ch) then
luôn đánh giá False
. Vì vậy, mặc dù chuỗi của bạn có chứa một ký tự đại diện, nó không bao giờ có thể đạt được thử nghiệm tiếp theo:
if UseWildcards then
Nó rất dễ dàng để kết luận rằng HasValidPathChars
trả về giá trị như nhau không phụ thuộc vào giá trị của tham số đầu vào UseWildcards
. Và nếu bạn có bất kỳ nghi ngờ gì về việc phân tích, chương trình này nên xua tan nó:
{$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.
này trông giống như thêm một chức năng trong này sợ hãi IOUtils
đơn vị đó đã được thực hiện không đúng cách và không được kiểm tra.
Tôi đã gửi báo cáo lỗi: RSP-18696.
Dựa trên việc vấp phải nhiều vấn đề như vậy với IOUtils
, kinh nghiệm của tôi là đơn vị không được tin cậy. Tôi sẽ không sử dụng nó. Tìm một cách khác để giải quyết vấn đề của bạn.
Không nên từ chối '?' Vì đường dẫn CÓ THỂ chứa dấu hỏi trên Windows. Ví dụ: https://superuser.com/q/1069055 –
Bài đăng siêu người dùng đó cũng nêu rõ: "Bạn không thể sử dụng các loại đường dẫn này để truy cập tệp hoặc thư mục trong vùng người dùng. Chỉ một số thành phần hệ thống cấp thấp nhất định được thiết kế để hoạt động với Đường dẫn Trình quản lý đối tượng. " Vì vậy, từ quan điểm này '?' Là một ký tự đường dẫn không hợp lệ. – gabr
@ GünthertheBeautiful - Bài viết nói rằng \ ?? là một đường dẫn hợp lệ, vì vậy HasValidPathChars nên kiểm tra '??' và trả về true NẾU mẫu đúng (\ ??) được tìm thấy và sai khi có một '?' – Ampere