我嘗試建立正則表達式驗證(的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