Merge 2.5.x (2.5.12) changes into trunk.

This commit is contained in:
b1v1r
2010-02-05 19:05:20 +00:00
parent ed11e27e0f
commit 08edc0c26f
54 changed files with 3170 additions and 330 deletions

View File

@@ -1,17 +1,21 @@
### Logging tests
# log/nolog
# log/nolog (pass)
{
type => "action",
comment => "log",
comment => "log (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,log"
),
match_log => {
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Warning\. Unconditional match in SecAction\./, 1 ],
},
match_response => {
status => qr/^200$/,
@@ -22,9 +26,12 @@
},
{
type => "action",
comment => "nolog",
comment => "nolog (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,nolog"
@@ -41,19 +48,70 @@
),
},
# auditlog/noauditlog
# log/nolog (deny)
{
type => "action",
comment => "auditlog",
comment => "log (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,log"
),
match_log => {
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "action",
comment => "nolog (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,nolog"
),
match_log => {
-error => [ qr/ModSecurity: /, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
# auditlog/noauditlog (pass)
{
type => "action",
comment => "auditlog (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,auditlog"
),
match_log => {
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Warning. Unconditional match in SecAction\./, 1 ],
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Warning\. Unconditional match in SecAction\./, 1 ],
},
match_response => {
status => qr/^200$/,
@@ -64,15 +122,18 @@
},
{
type => "action",
comment => "noauditlog",
comment => "noauditlog (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,noauditlog"
),
match_log => {
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
@@ -83,19 +144,70 @@
),
},
# All log/nolog auditlog/noauditlog combos
# auditlog/noauditlog (deny)
{
type => "action",
comment => "log,auditlog",
comment => "auditlog (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,auditlog"
),
match_log => {
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "action",
comment => "noauditlog (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,noauditlog"
),
match_log => {
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
# All log/nolog auditlog/noauditlog combos (pass)
{
type => "action",
comment => "log,auditlog (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,log,auditlog"
),
match_log => {
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Warning. Unconditional match in SecAction\./, 1 ],
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Warning\. Unconditional match in SecAction\./, 1 ],
},
match_response => {
status => qr/^200$/,
@@ -106,15 +218,18 @@
},
{
type => "action",
comment => "log,noauditlog",
comment => "log,noauditlog (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,log,noauditlog"
),
match_log => {
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
@@ -126,9 +241,12 @@
},
{
type => "action",
comment => "nolog,auditlog",
comment => "nolog,auditlog (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,nolog,auditlog"
@@ -145,9 +263,12 @@
},
{
type => "action",
comment => "nolog,noauditlog",
comment => "nolog,noauditlog (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,nolog,noauditlog"
@@ -165,16 +286,19 @@
},
{
type => "action",
comment => "auditlog,log",
comment => "auditlog,log (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,auditlog,log"
),
match_log => {
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Warning. Unconditional match in SecAction\./, 1 ],
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Warning\. Unconditional match in SecAction\./, 1 ],
},
match_response => {
status => qr/^200$/,
@@ -185,9 +309,12 @@
},
{
type => "action",
comment => "auditlog,nolog",
comment => "auditlog,nolog (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,auditlog,nolog"
@@ -205,15 +332,18 @@
},
{
type => "action",
comment => "noauditlog,log",
comment => "noauditlog,log (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,noauditlog,log"
),
match_log => {
error => [ qr/ModSecurity: Warning. Unconditional match in SecAction\./, 1 ],
error => [ qr/ModSecurity: Warning\. Unconditional match in SecAction\./, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
@@ -225,9 +355,12 @@
},
{
type => "action",
comment => "noauditlog,nolog",
comment => "noauditlog,nolog (pass)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,pass,noauditlog,nolog"
@@ -244,3 +377,188 @@
),
},
# All log/nolog auditlog/noauditlog combos (deny)
{
type => "action",
comment => "log,auditlog (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,log,auditlog"
),
match_log => {
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "action",
comment => "log,noauditlog (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,log,noauditlog"
),
match_log => {
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "action",
comment => "nolog,auditlog (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,nolog,auditlog"
),
match_log => {
audit => [ qr/-H--\s+Message: .*Stopwatch: /s, 1 ],
},
match_response => {
-error => [ qr/ModSecurity: /, 1 ],
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "action",
comment => "nolog,noauditlog (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,nolog,noauditlog"
),
match_log => {
-error => [ qr/ModSecurity: /, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "action",
comment => "auditlog,log (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,auditlog,log"
),
match_log => {
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
audit => [ qr/Message: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "action",
comment => "auditlog,nolog (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,auditlog,nolog"
),
match_log => {
-error => [ qr/ModSecurity: /, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "action",
comment => "noauditlog,log (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,noauditlog,log"
),
match_log => {
error => [ qr/ModSecurity: Access denied with code 403 \(phase 1\)\. Unconditional match in SecAction\./, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},
{
type => "action",
comment => "noauditlog,nolog (deny)",
conf => qq(
SecRuleEngine On
SecDebugLog "$ENV{DEBUG_LOG}"
SecDebugLogLevel 9
SecAuditLogRelevantStatus xxx
SecAuditEngine RelevantOnly
SecAuditLog "$ENV{AUDIT_LOG}"
SecAction "phase:1,deny,status:403,noauditlog,nolog"
),
match_log => {
-error => [ qr/ModSecurity: /, 1 ],
-audit => [ qr/./, 1 ],
},
match_response => {
status => qr/^403$/,
},
request => new HTTP::Request(
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
),
},

View File

@@ -96,7 +96,7 @@
return 1;
},
match_log => {
debug => [ qr/Created temporary file: $ENV{TEMP_DIR}/, 1 ],
debug => [ qr/Created temporary file.*$ENV{TEMP_DIR}/, 1 ],
-debug => [ qr/Failed to /, 1 ],
},
match_response => {

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -27,64 +27,190 @@
{
type => "tfn",
name => "normalisePath",
input => "/foo/bar//baz",
output => "/foo/bar/baz",
input => "x",
output => "x",
ret => 0,
},
{
type => "tfn",
name => "normalisePath",
input => ".",
output => "",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "/foo/bar baz/././././boo//eek/././../whoa",
output => "/foo/bar baz/boo/whoa",
input => "./",
output => "",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "./foo/bar baz/././././boo//eek/././../whoa",
output => "./foo/bar baz/boo/whoa",
input => "./..",
output => "..",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "/./foo/bar baz/././././boo//eek/././../whoa",
output => "/foo/bar baz/boo/whoa",
input => "./../",
output => "../",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "//foo/bar baz/././././boo//eek/././../whoa",
output => "/foo/bar baz/boo/whoa",
input => "..",
output => "..",
ret => 0,
},
{
type => "tfn",
name => "normalisePath",
input => "../",
output => "../",
ret => 0,
},
{
type => "tfn",
name => "normalisePath",
input => "../.",
output => "..",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "//foo/bar baz/././././boo//eek/././../whoa/./",
output => "/foo/bar baz/boo/whoa/",
input => ".././",
output => "../",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "/./foo/bar baz/././././boo//eek/././../whoa//",
output => "/foo/bar baz/boo/whoa/",
input => "../..",
output => "../..",
ret => 0,
},
{
type => "tfn",
name => "normalisePath",
input => "../../",
output => "../../",
ret => 0,
},
{
type => "tfn",
name => "normalisePath",
input => "/dir/foo//bar",
output => "/dir/foo/bar",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "/./../../../../../../../../etc/passwd",
output => "/etc/passwd",
input => "dir/foo//bar/",
output => "dir/foo/bar/",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "/./.././../../../../../../../etc/../etc/./passwd",
output => "/etc/passwd",
input => "dir/../foo",
output => "foo",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/../../foo",
output => "../foo",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/./.././../../foo/bar",
output => "../../foo/bar",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/./.././../../foo/bar/.",
output => "../../foo/bar",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/./.././../../foo/bar/./",
output => "../../foo/bar/",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/./.././../../foo/bar/..",
output => "../../foo",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/./.././../../foo/bar/../",
output => "../../foo/",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/./.././../../foo/bar/",
output => "../../foo/bar/",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir//.//..//.//..//..//foo//bar",
output => "../../foo/bar",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir//.//..//.//..//..//foo//bar//",
output => "../../foo/bar/",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/subdir/subsubdir/subsubsubdir/../../..",
output => "dir",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/./subdir/./subsubdir/./subsubsubdir/../../..",
output => "dir",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "dir/./subdir/../subsubdir/../subsubsubdir/..",
output => "dir",
ret => 1,
},
{
type => "tfn",
name => "normalisePath",
input => "/dir/./subdir/../subsubdir/../subsubsubdir/../",
output => "/dir/",
ret => 1,
},

View File

@@ -27,64 +27,190 @@
{
type => "tfn",
name => "normalisePathWin",
input => "\\foo\\bar\\\\baz",
output => "/foo/bar/baz",
input => "x",
output => "x",
ret => 0,
},
{
type => "tfn",
name => "normalisePathWin",
input => ".",
output => "",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "\\foo\\bar baz\\.\\.\\.\\.\\boo\\\\eek\\.\\.\\..\\whoa",
output => "/foo/bar baz/boo/whoa",
input => ".\\",
output => "",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => ".\\foo\\bar baz\\.\\.\\.\\.\\boo\\\\eek\\.\\.\\..\\whoa",
output => "./foo/bar baz/boo/whoa",
input => ".\\..",
output => "..",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "\\.\\foo\\bar baz\\.\\.\\.\\.\\boo\\\\eek\\.\\.\\..\\whoa",
output => "/foo/bar baz/boo/whoa",
input => ".\\..\\",
output => "../",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "\\\\foo\\bar baz\\.\\.\\.\\.\\boo\\\\eek\\.\\.\\..\\whoa",
output => "/foo/bar baz/boo/whoa",
input => "..",
output => "..",
ret => 0,
},
{
type => "tfn",
name => "normalisePathWin",
input => "..\\",
output => "../",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "\\\\foo\\bar baz\\.\\.\\.\\.\\boo\\\\eek\\.\\.\\..\\whoa\\.\\",
output => "/foo/bar baz/boo/whoa/",
input => "..\\.",
output => "..",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "\\.\\foo\\bar baz\\.\\.\\.\\.\\boo\\\\eek\\.\\.\\..\\whoa\\\\",
output => "/foo/bar baz/boo/whoa/",
input => "..\\.\\",
output => "../",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "\\.\\..\\..\\..\\..\\..\\..\\..\\..\\etc\\passwd",
output => "/etc/passwd",
input => "..\\..",
output => "../..",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "\\.\\..\\.\\..\\..\\..\\..\\..\\..\\..\\etc\\..\\etc\\.\\passwd",
output => "/etc/passwd",
input => "..\\..\\",
output => "../../",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "\\dir\\foo\\\\bar",
output => "/dir/foo/bar",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\foo\\\\bar\\",
output => "dir/foo/bar/",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\..\\foo",
output => "foo",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\..\\..\\foo",
output => "../foo",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\.\\..\\.\\..\\..\\foo\\bar",
output => "../../foo/bar",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\.\\..\\.\\..\\..\\foo\\bar\\.",
output => "../../foo/bar",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\.\\..\\.\\..\\..\\foo\\bar\\.\\",
output => "../../foo/bar/",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\.\\..\\.\\..\\..\\foo\\bar\\..",
output => "../../foo",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\.\\..\\.\\..\\..\\foo\\bar\\..\\",
output => "../../foo/",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\.\\..\\.\\..\\..\\foo\\bar\\",
output => "../../foo/bar/",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\\\.\\\\..\\\\.\\\\..\\\\..\\\\foo\\\\bar",
output => "../../foo/bar",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\\\.\\\\..\\\\.\\\\..\\\\..\\\\foo\\\\bar\\\\",
output => "../../foo/bar/",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\subdir\\subsubdir\\subsubsubdir\\..\\..\\..",
output => "dir",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\.\\subdir\\.\\subsubdir\\.\\subsubsubdir\\..\\..\\..",
output => "dir",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "dir\\.\\subdir\\..\\subsubdir\\..\\subsubsubdir\\..",
output => "dir",
ret => 1,
},
{
type => "tfn",
name => "normalisePathWin",
input => "\\dir\\.\\subdir\\..\\subsubdir\\..\\subsubsubdir\\..\\",
output => "/dir/",
ret => 1,
},