为什么TPath.HasValidPathChars接受“?"作为路径中的有效字符? [英] Why does TPath.HasValidPathChars accept '?' as a valid char in a path?

查看:91
本文介绍了为什么TPath.HasValidPathChars接受“?"作为路径中的有效字符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么System.IOUtils.TPath.HasValidPathChars接受?"作为路径中的有效字符? 我将第二个参数(UseWildcards)设置为false.因此,根据文档,?"应该被拒绝.仍然,该函数为'c:\ test \ test?\'返回True.

Why does System.IOUtils.TPath.HasValidPathChars accept'?' as a valid char in a path? I set the second parameter (UseWildcards) to false. So, according to the documentation the '?' should be rejected. Still, the function returns True for 'c:\test\test?\'.

UseWildcards =指定是否将掩码字符视为 有效的路径字符(例如星号或问号).

UseWildcards = Specifies whether the mask characters are treated as valid path characters (e.g. asterisk or question mark).

此功能的行为是否仅部分正确?函数可以返回更好的结果吗?

Is the behavior of this function only partially correct? Could the function have returned a better result?

推荐答案

TPath.HasValidPathChars已完全损坏.这是它的实现:

TPath.HasValidPathChars is completely broken. This is its implementation:

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的调用.让我们看看它能做什么.

The crucial point is the call to IsValidPathChar. Let's look at what that does.

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的序号以及"<>|.

That is, all ordinals less than 32, and ", <, > and |.

我们还需要了解IsPathWildcardChar的作用.

We also need to understand what IsPathWildcardChar does.

class function TPath.IsPathWildcardChar(const AChar: Char): Boolean;
begin
  Result := IsCharInOrderedArray(AChar, FPathWildcardChars);
end;

FPathWildcardChars所在的位置:

FPathWildcardChars := TCharArray.Create('*', '/', ':', '?', '\'); // DO NOT LOCALIZE;

现在,返回到TPath.HasValidPathChars.让我们考虑以下if语句:

Now, back to TPath.HasValidPathChars. Let's consider this if statement:

if not IsValidPathChar(Ch) then

IsValidPathChar(Ch)False时,条件not IsValidPathChar(Ch)的计算结果为True.如果Ch位于FInvalidPathChars中,则会发生这种情况.也就是说,如果Ch的序数小于32,或者是"<>|之一.

The condition not IsValidPathChar(Ch) evaluates to True when IsValidPathChar(Ch) is False. Which happens if Ch is in FInvalidPathChars. That is if Ch has ordinal less than 32, or is one of ", <, > and |.

您的测试字符串为'C:\test\test?\',实际上这些字符都不在FInvalidPathChars中.这意味着if not IsValidPathChar(Ch) then语句中的条件始终为False.因此,即使您的字符串包含通配符,也永远无法达到后续测试要求:

Your test string is 'C:\test\test?\' and in fact none of these characters are in FInvalidPathChars. Which means that the condition in the if not IsValidPathChar(Ch) then statement always evaluates False. So even though your string contains a wildcard, it can never reach the subsequent test:

if UseWildcards then

很容易得出结论,不管输入参数UseWildcards的值如何,HasValidPathChars返回相同的值.如果您对分析有任何疑问,此程序应消除它:

It is easy to conclude that HasValidPathChars returns the same value irrespective of the value of the input parameter UseWildcards. And if you have any doubt about the analysis, this program should dispel it:

{$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单元中的另一个功能,该功能未正确实施且未经测试.

This looks like yet another function in this dreaded IOUtils unit that has been improperly implemented and not tested.

我已经提交了一个错误报告: RSP-18696 .

I have submitted a bug report: RSP-18696.

基于偶然发现IOUtils的许多此类问题,我的经验是该单元不可信任.我不会用.寻找另一种解决问题的方法.

Based on having stumbled upon many such problems with IOUtils, my experience is that the unit is not to be trusted. I would not use it. Find an alternative way to solve your problem.

这篇关于为什么TPath.HasValidPathChars接受“?"作为路径中的有效字符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆