CGI-Info
view release on metacpan or search on metacpan
t/function.t view on Meta::CPAN
reset_env();
$ENV{GATEWAY_INTERFACE} = 'CGI/1.1';
$ENV{REQUEST_METHOD} = 'OPTIONS';
my $info = CGI::Info->new();
$info->params();
is($info->status(), 405, 'OPTIONS yields 405');
};
subtest 'status() - DELETE sets 405 implicitly' => sub {
reset_env();
$ENV{GATEWAY_INTERFACE} = 'CGI/1.1';
$ENV{REQUEST_METHOD} = 'DELETE';
my $info = CGI::Info->new();
$info->params();
is($info->status(), 405, 'DELETE yields 405');
};
# ============================================================
# 4. params()
# ============================================================
subtest 'params() - GET simple query' => sub {
reset_env();
$ENV{GATEWAY_INTERFACE} = 'CGI/1.1';
$ENV{REQUEST_METHOD} = 'GET';
$ENV{QUERY_STRING} = 'foo=bar&baz=42';
my $info = CGI::Info->new();
my $p = $info->params();
ok(defined $p, 'params() returns defined value');
is($p->{foo}, 'bar', 'foo=bar parsed');
is($p->{baz}, '42', 'baz=42 parsed');
};
subtest 'params() - GET no query string returns undef' => sub {
reset_env();
$ENV{GATEWAY_INTERFACE} = 'CGI/1.1';
$ENV{REQUEST_METHOD} = 'GET';
$ENV{QUERY_STRING} = '';
my $info = CGI::Info->new();
my $p = $info->params();
ok(!defined $p, 'empty QUERY_STRING returns undef');
};
subtest 'params() - allow filters unknown keys' => sub {
reset_env();
$ENV{GATEWAY_INTERFACE} = 'CGI/1.1';
$ENV{REQUEST_METHOD} = 'GET';
$ENV{QUERY_STRING} = 'good=1&evil=2';
my $info = CGI::Info->new();
my $p = $info->params(allow => { good => qr/^\d+$/ });
ok(defined $p->{good}, 'allowed key present');
ok(!defined $p->{evil}, 'disallowed key absent');
};
subtest 'params() - allow regex mismatch blocks value' => sub {
reset_env();
$ENV{GATEWAY_INTERFACE} = 'CGI/1.1';
$ENV{REQUEST_METHOD} = 'GET';
$ENV{QUERY_STRING} = 'id=abc';
my $info = CGI::Info->new();
my $p = $info->params(allow => { id => qr/^\d+$/ });
ok(!defined($p), 'regex-blocked key excluded from result');
is($info->status(), 422, 'status 422 set on validation failure');
};
subtest 'params() - allow exact-string match' => sub {
reset_env();
$ENV{GATEWAY_INTERFACE} = 'CGI/1.1';
$ENV{REQUEST_METHOD} = 'GET';
$ENV{QUERY_STRING} = 'color=blue&color=red';
my $info = CGI::Info->new();
my $p = $info->params(allow => { color => 'blue' });
# 'blue' matches, but 'red' appears as comma-separated; blue matches first
ok(defined $p, 'exact-string allow passes matching value');
};
subtest 'params() - allow coderef validator' => sub {
reset_env();
$ENV{GATEWAY_INTERFACE} = 'CGI/1.1';
$ENV{REQUEST_METHOD} = 'GET';
$ENV{QUERY_STRING} = 'num=4&num2=3';
my $info = CGI::Info->new();
my $p = $info->params(allow => {
num => sub { ($_[1] % 2) == 0 }, # even => pass
num2 => sub { ($_[1] % 2) == 0 }, # odd => fail
});
ok(defined $p->{num}, 'even number passes coderef validator');
ok(!defined $p->{num2}, 'odd number blocked by coderef validator');
};
subtest 'params() - SQL injection blocked (GET)' => sub {
reset_env();
$ENV{GATEWAY_INTERFACE} = 'CGI/1.1';
$ENV{REQUEST_METHOD} = 'GET';
$ENV{QUERY_STRING} = "id=1'%20OR%201=1";
my $info = CGI::Info->new();
my $p = $info->params();
ok(!defined $p, 'SQL injection blocked');
is($info->status(), 403, 'status 403 on SQL injection');
};
subtest 'params() - XSS injection blocked (GET)' => sub {
reset_env();
$ENV{GATEWAY_INTERFACE} = 'CGI/1.1';
$ENV{REQUEST_METHOD} = 'GET';
$ENV{QUERY_STRING} = 'q=%3Cscript%3Ealert(1)%3C%2Fscript%3E';
my $info = CGI::Info->new();
my $p = $info->params();
ok(!defined $p, 'XSS injection blocked');
is($info->status(), 403, 'status 403 on XSS');
};
subtest 'params() - directory traversal blocked (GET)' => sub {
reset_env();
$ENV{GATEWAY_INTERFACE} = 'CGI/1.1';
$ENV{REQUEST_METHOD} = 'GET';
$ENV{QUERY_STRING} = 'file=../../etc/passwd';
my $info = CGI::Info->new();
my $p = $info->params();
ok(!defined $p, 'directory traversal blocked');
is($info->status(), 403, 'status 403 on directory traversal');
};
subtest 'params() - mustleak attack blocked (GET)' => sub {
reset_env();
$ENV{GATEWAY_INTERFACE} = 'CGI/1.1';
$ENV{REQUEST_METHOD} = 'GET';
$ENV{QUERY_STRING} = 'x=mustleak.com/probe';
my $info = CGI::Info->new();
my $p = $info->params();
ok(!defined $p, 'mustleak attack blocked');
is($info->status(), 403, 'status 403 on mustleak');
};
subtest 'params() - duplicate values comma-joined' => sub {
reset_env();
$ENV{GATEWAY_INTERFACE} = 'CGI/1.1';
$ENV{REQUEST_METHOD} = 'GET';
$ENV{QUERY_STRING} = 'color=red&color=blue';
my $info = CGI::Info->new();
my $p = $info->params();
like($p->{color}, qr/red.*blue|blue.*red/, 'duplicate values comma-joined');
};
subtest 'params() - POST missing CONTENT_LENGTH => 411' => sub {
reset_env();
$ENV{GATEWAY_INTERFACE} = 'CGI/1.1';
$ENV{REQUEST_METHOD} = 'POST';
# no CONTENT_LENGTH
my $info = CGI::Info->new();
my $p = $info->params();
ok(!defined $p, 'POST without CONTENT_LENGTH returns undef');
is($info->status(), 411, 'status 411');
};
subtest 'params() - POST oversized => 413' => sub {
reset_env();
$ENV{GATEWAY_INTERFACE} = 'CGI/1.1';
$ENV{REQUEST_METHOD} = 'POST';
$ENV{CONTENT_LENGTH} = 999_999_999;
my $info = CGI::Info->new(max_upload_size => 100);
my $p = $info->params();
ok(!defined $p, 'oversized POST returns undef');
is($info->status(), 413, 'status 413 on large upload');
};
subtest 'params() - command-line key=value pairs (non-CGI)' => sub {
reset_env();
local @ARGV = ('name=Alice', 'age=30');
my $info = CGI::Info->new();
my $p = $info->params();
is($p->{name}, 'Alice', 'name from ARGV');
is($p->{age}, '30', 'age from ARGV');
};
subtest 'params() - --mobile flag from ARGV' => sub {
reset_env();
local @ARGV = ('--mobile', 'x=1');
my $info = CGI::Info->new();
$info->params();
ok($info->is_mobile(), '--mobile flag sets is_mobile');
};
subtest 'params() - --robot flag from ARGV' => sub {
reset_env();
local @ARGV = ('--robot');
my $info = CGI::Info->new();
$info->params();
ok($info->is_robot(), '--robot flag sets is_robot');
};
t/function.t view on Meta::CPAN
$ENV{REQUEST_METHOD} = 'POST';
$ENV{CONTENT_TYPE} = 'application/json';
$ENV{CONTENT_LENGTH} = length($json_body);
# Inject STDIN via the class variable
$CGI::Info::stdin_data = $json_body;
my $info = CGI::Info->new();
my $p = $info->params();
if(defined $p) {
is($p->{alpha}, 'one', 'JSON POST: alpha=one');
is($p->{beta}, 'two', 'JSON POST: beta=two');
} else {
# JSON::MaybeXS may not be installed in all environments
pass('JSON POST: no result (JSON module unavailable, acceptable)');
}
};
# ============================================================
# 29. POST with text/xml content type
# ============================================================
subtest 'params() - POST XML stored under XML key' => sub {
reset_env();
my $xml_body = '<root><item>test</item></root>';
$ENV{GATEWAY_INTERFACE} = 'CGI/1.1';
$ENV{REQUEST_METHOD} = 'POST';
$ENV{CONTENT_TYPE} = 'text/xml';
$ENV{CONTENT_LENGTH} = length($xml_body);
$CGI::Info::stdin_data = $xml_body;
my $info = CGI::Info->new();
my $p = $info->params();
ok(defined $p, 'XML POST returns hashref');
is($p->{XML}, $xml_body, 'XML body stored under XML key');
};
# ============================================================
# 30. Params::Validate::Strict integration via allow hash-schema
# ============================================================
subtest 'params() - Params::Validate::Strict schema passes valid value' => sub {
reset_env();
$ENV{GATEWAY_INTERFACE} = 'CGI/1.1';
$ENV{REQUEST_METHOD} = 'GET';
$ENV{QUERY_STRING} = 'age=25';
my $info = CGI::Info->new();
my $p = $info->params(allow => {
age => { type => 'integer', min => 0, max => 150 }
});
ok(defined $p && defined $p->{age}, 'valid age passes Params::Validate::Strict');
};
subtest 'params() - Params::Validate::Strict schema blocks invalid value' => sub {
reset_env();
$ENV{GATEWAY_INTERFACE} = 'CGI/1.1';
$ENV{REQUEST_METHOD} = 'GET';
$ENV{QUERY_STRING} = 'age=999';
my $info = CGI::Info->new();
my $p = $info->params(allow => {
age => { type => 'integer', min => 0, max => 150 }
});
# Either blocked entirely or age is absent
my $blocked = (!defined $p) || (!defined $p->{age});
ok($blocked, 'out-of-range age blocked by Params::Validate::Strict');
};
done_testing();
( run in 0.768 second using v1.01-cache-2.11-cpan-39bf76dae61 )