-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WIP Add limit for nested data structures
YAML is not directly vulnerable to the Billion Laughs Attack: https://en.wikipedia.org/wiki/Billion_laughs_attack#Variations As long as the constructor uses perl references, everything is fine. But if you print such data (for example as JSON), then it will get huge, as JSON does not know references. This commit is adding an experimental option that limits nested data. Every anchor that is created gets assigned a number (its depth): &anchor [x] # 1 &anchor [[x]] # 2 Whenever an alias is used, it will increase the total sum by its depth. Whenever an alias is used inside of another anchor, the depth of this anchor will be increased by the alias depth. - &a [[x]] # *a = 2 - &b [*a,*a,*a] # *b = 2+2+2 + 1 = 7 total=6 - &c [*b] # *c = 7 + 1 total=6+7=13 The total sum of depths must not be higher then a maximum which is currently 256 by default.
- Loading branch information
Showing
8 changed files
with
366 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
--- | ||
a: &a ["lol","lol","lol","lol","lol","lol","lol","lol","lol"] | ||
b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a] | ||
c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b] | ||
d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c] | ||
e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d] | ||
f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e] | ||
g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f] | ||
h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g] | ||
i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h] |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#!/usr/bin/perl | ||
use strict; | ||
use warnings; | ||
use 5.010; | ||
use FindBin '$Bin'; | ||
use lib "$Bin/../../lib"; | ||
|
||
use YAML::PP; | ||
use JSON::PP; | ||
|
||
my ($file, $limit) = @ARGV; | ||
|
||
$limit ||= 1024; | ||
|
||
my $yp = YAML::PP->new( | ||
limit => { | ||
alias_depth => $limit, | ||
}, | ||
); | ||
my $j = JSON::PP->new; | ||
|
||
my $start = size(); | ||
say "Memory at start: $start"; | ||
|
||
my $data = $yp->load_file($file); | ||
my $mem_load = size(); | ||
my $growth = $mem_load - $start; | ||
say "After load: $mem_load (+$growth)"; | ||
|
||
my $json = $j->encode($data); | ||
my $mem_json = size(); | ||
$growth = $mem_json - $mem_load; | ||
say "After json encode: $mem_json (+$growth)"; | ||
say sprintf "length JSON: %s bytes", length $json; | ||
|
||
sub size { | ||
my $s = qx{ps --no-headers -o vsize:3 --pid $$}; | ||
chomp $s; | ||
return $s; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#!/usr/bin/env perl | ||
use strict; | ||
use warnings; | ||
use Test::More; | ||
use Test::Deep; | ||
use FindBin '$Bin'; | ||
use Data::Dumper; | ||
use YAML::PP; | ||
|
||
my $file = "$Bin/data/billion.yaml"; | ||
|
||
subtest "nested aliases limit reached" => sub { | ||
my $yp = YAML::PP->new( | ||
schema => ['Failsafe'], | ||
limit => { | ||
alias_depth => 100, | ||
}, | ||
); | ||
|
||
eval { | ||
my $data = $yp->load_file($file); | ||
}; | ||
my $error = $@; | ||
note $error; | ||
like($error, qr{Limit of nested aliases reached}); | ||
}; | ||
|
||
subtest "nested aliases ok" => sub { | ||
my $yp = YAML::PP->new( | ||
schema => ['Failsafe'], | ||
limit => { | ||
alias_depth => 1000_000_000, | ||
}, | ||
); | ||
|
||
my $data = $yp->load_file($file); | ||
is($data->{data}->{i}->[0]->[0]->[0]->[0]->[0]->[0]->[0]->[0]->[0], 'lol'); | ||
}; | ||
|
||
done_testing; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
data: | ||
a: &a [lol,lol,lol,lol,lol,lol,lol,lol,lol,lol] | ||
b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a,*a] | ||
c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b,*b] | ||
d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c,*c] | ||
e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d,*d] | ||
f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e,*e] | ||
g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f,*f] | ||
h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g,*g] | ||
i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h,*h] |