我尝试建立正则表达式验证(的preg_match)一些路径字符串为以下两个规则:检查目录路径范围和“..”向上目录签署
- 路径必须由来自给定的范围
[a-zA-z0-9-_\///\.]
只有符号 - 道路不会由一个备份目录序列 “..”
这是一个正确的路径例如:/user/temp
和坏的一个:/../user
UPD: /user/temp.../foo
也将是正确的(感谢劳伦斯·贡萨尔维斯)
我尝试建立正则表达式验证(的preg_match)一些路径字符串为以下两个规则:检查目录路径范围和“..”向上目录签署
[a-zA-z0-9-_\///\.]
只有符号这是一个正确的路径例如:/user/temp
和坏的一个:/../user
UPD: /user/temp.../foo
也将是正确的(感谢劳伦斯·贡萨尔维斯)
考虑一下:
$right_path = '/user/temp';
$wrong_path = '/../user';
$almost_wrong_path = 'foo/abc../bar';
$almost_right_path = 'foo/../bar';
$pattern = '#^(?!.*[\\/]\.{2}[\\/])(?!\.{2}[\\/])[-\w.\\/]+$#';
var_dump(preg_match($pattern, $right_path)); // 1
var_dump(preg_match($pattern, $wrong_path)); // 0
var_dump(preg_match($pattern, $almost_wrong_path)); // 1
var_dump(preg_match($pattern, $almost_right_path)); // 0
其实我已经建立了这个格局三个步骤:
1)给出的第一条规则是只允许字符串中的符号为0-9
,a-zA-Z
,_
(下划线),-
(连字符),.
(点)和两个斜线(/
和\
)。
[-\w.\\/]
这里注意两件事情:1)连字符应该是第一或在字符类中的最后一个符号(否则就前三的位置可以用一个快捷方式(\w
),则需要一个字符类来表示视为用于定义范围的元字符); 2)点和正斜杠都没有被转义(反斜线被转义;尽管如此,它太强大了,不能单独使用,即使在[...]
子表达式中也是如此)。
2)现在我们必须确保模式确实覆盖整个字符串。我们用所谓的锚点 - ^
开始字符串,$
结束。而且,不要忘记我们的字符串可能包含一个或多个允许的符号(用+
量词表示)。所以图案变成这样:
^[-\w.\\/]+$
3)最后一件事 - 我们必须避免使用../
和..\
(由/
或\
之前 - 与否,如果..[/\\]
序列开始的字符串)也是如此。
表达这一规则的最简单的方法是使用所谓的“negative lookahead”测试。它的内(?!...)子表达式编写的,(在这种情况下)记载了下述理念:“确保零个或多个符号该序列后面没有‘砍伐两个点斜杠’序”:
^(?!.*[\\/]\.{2}[\\/])(?!\.{2}[\\/])[-\w.\\/]+$
最后一件事实际上是将图案为preg_match
功能:当我们使用正则表达式中/
符号,我们可以只选择另一组分隔符。在我的示例中,我选择了“#”:
$pattern = '#^(?!.*[\\/]\.{2}[\\/])(?!\.{2}[\\/])[-\w.\\/]+$#';
请参阅?这很容易。 )你必须从小事做起,逐步发展。
谢谢,对于优秀的解释) – sharp
'/ user/foo..bar/baz'认为有效吗? –
是的,..foo/bar,/foo..bar/baz是正确的路径示例,谢谢你的提示! – sharp
更新了我的答案。 – raina77ow