Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
perlpunk committed Nov 10, 2023
1 parent a21eb25 commit 90383a5
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 25 deletions.
50 changes: 27 additions & 23 deletions lib/YAML/PP/Constructor.pm
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ sub document_start_event {
}
my $ref = [];
push @$stack, { type => 'document', ref => $ref, data => $ref, event => $event };
$self->{alias_depth_count} = 0;
}

sub document_end_event {
Expand Down Expand Up @@ -138,6 +137,7 @@ sub mapping_start_event {
on_data => $on_data,
size => 1,
};
$self->{size_left}--;
my $stack = $self->stack;

my $preserve_order = $self->preserve_order;
Expand All @@ -161,7 +161,6 @@ sub mapping_start_event {
}
}
$self->anchors->{ $anchor } = { data => $ref->{data} };
$self->{open_anchors}->{ $anchor } = 1;
}
}

Expand Down Expand Up @@ -226,15 +225,12 @@ sub mapping_end_event {
push @{ $stack->[-1]->{ref} }, $$data;
my $size = $last->{size};
$stack->[-1]->{size} += $size;
if ($stack->[-1]->{size} > $self->{max_size}) {
die "Size limit reached: $self->{max_size}";
if ($self->{size_left} < 0) {
die "Size limit reached: $self->{max_size} (left: $self->{size_left})";
}
my $depth = ($last->{depth} || 0) + 1;
$stack->[-1]->{depth} = $depth;
if (defined(my $anchor = $last->{event}->{anchor})) {
$self->anchors->{ $anchor }->{finished} = 1;
$self->anchors->{ $anchor }->{size} = $size;
delete $self->{open_anchors}->{ $anchor };
}
return;
}
Expand All @@ -250,6 +246,7 @@ sub sequence_start_event {
on_data => $on_data,
size => 1,
};
$self->{size_left}--;
my $stack = $self->stack;

my $preserve_style = $self->preserve_flow_style;
Expand All @@ -270,7 +267,6 @@ sub sequence_start_event {
}
}
$self->anchors->{ $anchor } = { data => $ref->{data} };
$self->{open_anchors}->{ $anchor } = 1;
}
}

Expand All @@ -289,23 +285,26 @@ sub sequence_end_event {
push @{ $stack->[-1]->{ref} }, $$data;
my $size = $last->{size};
$stack->[-1]->{size} += $size;
if ($stack->[-1]->{size} > $self->{max_size}) {
die "Size limit reached: $self->{max_size}";
if ($self->{size_left} < 0) {
die "Size limit reached: $self->{max_size} (left: $self->{size_left})";
}
my $depth = ($last->{depth} || 0) + 1;
$stack->[-1]->{depth} = $depth;
if (defined(my $anchor = $last->{event}->{anchor})) {
my $test = $self->anchors->{ $anchor };
$self->anchors->{ $anchor }->{finished} = 1;
$self->anchors->{ $anchor }->{size} = $size;
delete $self->{open_anchors}->{ $anchor };
}
return;
}

sub stream_start_event {}
sub stream_start_event {
my ($self, $event) = @_;
$self->{size_left} = $self->{max_size};
}

sub stream_end_event {}
sub stream_end_event {
my ($self, $event) = @_;
$self->{size_left} = $self->{max_size};
}

sub scalar_event {
my ($self, $event) = @_;
Expand Down Expand Up @@ -333,7 +332,6 @@ sub scalar_event {
}
my $size = int( length( $event->{value} ) / 10 ) + 1;
if (defined (my $name = $event->{anchor})) {
my $d = int( length( $event->{value} ) / 1000 ) + 1;
$self->anchors->{ $name } = {
data => \$value,
finished => 1,
Expand All @@ -342,8 +340,11 @@ sub scalar_event {
}
push @{ $last->{ref} }, $value;
$last->{size} += $size;
if ($last->{size} > $self->{max_size}) {
die "Size limit reached: $self->{max_size}";
$self->{size_left} -= $size;
my $used = $self->{max_size} - $self->{size_left};
warn __PACKAGE__.':'.__LINE__.": !!!!!!!!! $self->{size_left} (used: $used) $size\n";
if ($self->{size_left} < 0) {
die "Size limit reached: $self->{max_size} (left: $self->{size_left})";
}
}

Expand All @@ -355,10 +356,9 @@ sub alias_event {
unless ($anchor = $self->anchors->{ $name }) {
croak "No anchor defined for alias '$name'";
}
my $size = $anchor->{size};
# We know this is a cyclic ref since the node hasn't
# been constructed completely yet
unless ($anchor->{finished} ) {
# We know this is a cyclic ref since the node hasn't
# been constructed completely yet
my $cyclic_refs = $self->cyclic_refs;
if ($cyclic_refs ne 'allow') {
if ($cyclic_refs eq 'fatal') {
Expand All @@ -373,12 +373,16 @@ sub alias_event {
}
}
}
my $size = $anchor->{size};
$value = $anchor->{data};
my $last = $self->stack->[-1];
push @{ $last->{ref} }, $$value;
$last->{size} += $size;
if ($last->{size} > $self->{max_size}) {
die "Size limit reached: $self->{max_size}";
$self->{size_left} -= $size;
my $used = $self->{max_size} - $self->{size_left};
warn __PACKAGE__.':'.__LINE__.": !!!!!!!!! $self->{size_left} (used: $used)\n";
if ($self->{size_left} < 0) {
die "Size limit reached: $self->{max_size} (left: $self->{size_left})";
}
}

Expand Down
5 changes: 3 additions & 2 deletions t/54.alias-bomb.t
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ subtest "nested aliases limit reached" => sub {
};
my $error = $@;
note $error;
like($error, qr{Limit of nested aliases reached});
like($error, qr{Size limit reached});
};

diag "========================================";
subtest "nested aliases ok" => sub {
my $yp = YAML::PP->new(
schema => ['Failsafe'],
limit => {
alias_depth => 1000_000_000,
alias_depth => 1_240_000_000,
},
);

Expand Down

0 comments on commit 90383a5

Please sign in to comment.