Data-TOON
view release on metacpan or search on metacpan
t/05_security.t view on Meta::CPAN
my $toon_text = "data: \"$long_string\"";
my $data = eval { Data::TOON->decode($toon_text) };
ok(defined $data, 'decode handles large strings');
}
# Test 4: Array count mismatch
{
my $toon_text = <<'TOON';
items[3]:
- id: 1
- id: 2
TOON
my $data = Data::TOON->decode($toon_text);
ok($data, 'decode handles array count mismatch gracefully');
}
# Test 5: Malformed header - missing colon
{
my $toon_text = "items[2]";
my $data = Data::TOON->decode($toon_text);
ok(defined $data, 'decode handles missing colon gracefully');
}
# Test 6: Invalid array size (negative)
{
my $toon_text = 'items[-1]: value';
my $data = eval { Data::TOON->decode($toon_text) };
ok($data || $@, 'decode handles negative array size');
}
# Test 7: Unterminated quoted string
{
my $toon_text = 'name: "unclosed string';
my $data = Data::TOON->decode($toon_text);
ok(defined $data, 'decode handles unterminated quotes gracefully');
}
# Test 8: Reserved characters in unquoted key
{
my $toon_text = 'my-key: value'; # Hyphen not allowed in unquoted key at start
my $data = Data::TOON->decode($toon_text);
ok(defined $data, 'decode handles key with special chars');
}
# Test 9: Circular reference in encoding (DoS risk)
{
my $data = { a => 1 };
$data->{self} = $data; # Circular reference
my $encoder = Data::TOON::Encoder->new(max_depth => 10); # Low limit to catch circular ref
my $encoded = eval { $encoder->encode($data) };
like($@ // '', qr/circular|reference|depth/i, 'encode detects circular references or depth limit');
}
# Test 10: NaN and Infinity are strings, not numbers
{
my $toon_text = <<'TOON';
value1: NaN
value2: Infinity
TOON
my $data = Data::TOON->decode($toon_text);
is($data->{value1}, 'NaN', 'NaN decoded as string');
is($data->{value2}, 'Infinity', 'Infinity decoded as string');
}
# Test 11: Shell injection-like patterns (data escaping)
{
my $toon_text = 'cmd: "rm -rf /; echo pwned"';
my $data = Data::TOON->decode($toon_text);
is($data->{cmd}, "rm -rf /; echo pwned", 'dangerous string preserved literally');
}
# Test 12: SQL injection-like patterns
{
my $toon_text = "query: \"SELECT * WHERE id='1' OR '1'='1'\"";
my $data = Data::TOON->decode($toon_text);
is($data->{query}, "SELECT * WHERE id='1' OR '1'='1'", 'SQL pattern preserved as string');
}
# Test 13: Multiple colons (HTTP URLs)
{
my $toon_text = 'url: "http://example.com:8080/path"';
my $data = Data::TOON->decode($toon_text);
is($data->{url}, 'http://example.com:8080/path', 'URL with port parsed correctly');
}
# Test 14: Embedded quotes and escapes
{
my $toon_text = 'message: "He said \"Hello\""';
my $data = Data::TOON->decode($toon_text);
is($data->{message}, 'He said "Hello"', 'escaped quotes handled correctly');
}
# Test 15: Max depth can be customized
{
my $deep_data = { level1 => { level2 => { level3 => "value" } } };
my $encoder_limited = Data::TOON::Encoder->new(max_depth => 2);
my $encoded = eval { $encoder_limited->encode($deep_data) };
like($@ // '', qr/depth|exceed|limit/i, 'encoder respects max_depth setting');
}
# Test 16: Delimiter confusion (CSV injection risk)
{
my $toon_text = <<'TOON';
items[2]{a,b}:
1|2
3|4
TOON
my $data = Data::TOON->decode($toon_text);
ok($data, 'decode handles delimiter specification in header');
# First row should try to split by comma, not pipe
}
# Test 17: Empty nested objects
{
my $toon_text = <<'TOON';
( run in 0.473 second using v1.01-cache-2.11-cpan-39bf76dae61 )