NAME
YAML::PP::Schema::Perl - Schema for serializing perl objects and special types
SYNOPSIS
use YAML::PP;
# This can be dangerous when loading untrusted YAML!
my $yp = YAML::PP->new( schema => [qw/ JSON Perl /] );
# or
my $yp = YAML::PP->new( schema => [qw/ Core Perl /] );
my $yaml = $yp->dump_string(sub { return 23 });
# loading code references
# This is very dangerous when loading untrusted YAML!!
my $yp = YAML::PP->new( schema => [qw/ JSON Perl +loadcode /] );
my $code = $yp->load_string(<<'EOM');
--- !perl/code |
{
use 5.010;
my ($name) = @_;
say "Hello $name!";
}
EOM
$code->("Ingy");
DESCRIPTION
This schema allows you to load and dump perl objects and special types.
Please note that loading objects of arbitrary classes can be dangerous in Perl. You have to load the modules yourself, but if an exploitable module is loaded and an object is created, its DESTROY
method will be called when the object falls out of scope. File::Temp is an example that can be exploitable and might remove arbitrary files.
Typeglobs are not implemented yet. Dumping code references is on by default, but not loading (because that is easily exploitable since it's using string eval
).
Tag Styles
You can define the style of tags you want to support:
my $yp_perl_two_one = YAML::PP->new(
schema => [qw/ JSON Perl tags=!!perl+!perl /],
);
!perl
(default)-
Only
!perl/type
tags are supported. !!perl
-
Only
!!perl/type
tags are supported. !perl+!!perl
-
Both
!perl/type
and!!perl/tag
are supported when loading. When dumping,!perl/type
is used. !!perl+!perl
-
Both
!perl/type
and!!perl/tag
are supported when loading. When dumping,!!perl/type
is used.
YAML.pm, YAML::Syck and YAML::XS are using !!perl/type
when dumping.
YAML.pm and YAML::Syck are supporting both !perl/type
and !!perl/type
when loading. YAML::XS currently only supports the latter.
Allow only certain classes
Since v0.017
Blessing arbitrary objects can be dangerous. Maybe you want to allow blessing only specific classes and ignore others. For this you have to instantiate a Perl Schema object first and use the classes
option.
Currently it only allows a list of strings:
my $perl = YAML::PP::Schema::Perl->new(
classes => ['Foo', 'Bar'],
);
my $yp = YAML::PP::Perl->new(
schema => [qw/ JSON /, $perl],
);
Allowed classes will be loaded and dumped as usual. The others will be ignored.
If you want to allow no objects at all, pass an empty array ref.
EXAMPLES
This is a list of the currently supported types and how they are dumped into YAML:
- array
-
# Code [ qw/ one two three four / ] # YAML --- - one - two - three - four
- array_blessed
-
# Code bless [ qw/ one two three four / ], "Just::An::Arrayref" # YAML --- !perl/array:Just::An::Arrayref - one - two - three - four
- circular
-
# Code my $circle = bless [ 1, 2 ], 'Circle'; push @$circle, $circle; $circle; # YAML --- &1 !perl/array:Circle - 1 - 2 - *1
- coderef
-
# Code sub { my (%args) = @_; return $args{x} + $args{y}; } # YAML --- !perl/code |- { use warnings; use strict; (my(%args) = @_); (return ($args{'x'} + $args{'y'})); }
- coderef_blessed
-
# Code bless sub { my (%args) = @_; return $args{x} - $args{y}; }, "I::Am::Code" # YAML --- !perl/code:I::Am::Code |- { use warnings; use strict; (my(%args) = @_); (return ($args{'x'} - $args{'y'})); }
- hash
-
# Code { U => 2, B => 52, } # YAML --- B: 52 U: 2
- hash_blessed
-
# Code bless { U => 2, B => 52, }, 'A::Very::Exclusive::Class' # YAML --- !perl/hash:A::Very::Exclusive::Class B: 52 U: 2
- refref
-
# Code my $ref = { a => 'hash' }; my $refref = \$ref; $refref; # YAML --- !perl/ref =: a: hash
- refref_blessed
-
# Code my $ref = { a => 'hash' }; my $refref = bless \$ref, 'Foo'; $refref; # YAML --- !perl/ref:Foo =: a: hash
- regexp
-
# Code my $string = 'unblessed'; qr{$string} # YAML --- !perl/regexp unblessed
- regexp_blessed
-
# Code my $string = 'blessed'; bless qr{$string}, "Foo" # YAML --- !perl/regexp:Foo blessed
- scalarref
-
# Code my $scalar = "some string"; my $scalarref = \$scalar; $scalarref; # YAML --- !perl/scalar =: some string
- scalarref_blessed
-
# Code my $scalar = "some other string"; my $scalarref = bless \$scalar, 'Foo'; $scalarref; # YAML --- !perl/scalar:Foo =: some other string
METHODS
- new
-
my $perl = YAML::PP::Schema::Perl->new( tags => "!perl", classes => ['MyClass'], loadcode => 1, );
The constructor recognizes the following options:
-
Default: '
!perl
'See "Tag Styles"
- classes
-
Default:
undef
Since: v0.017
Accepts an array ref of class names
- loadcode
-
Default: 0
-
- register
-
A class method called by YAML::PP::Schema
- construct_ref, represent_ref
-
Perl variables of the type
REF
are represented in yaml like this:--- !perl/ref =: a: 1
construct_ref
returns the perl data:my $data = YAML::PP::Schema::Perl->construct_ref([ '=', { some => 'data' } ); my $data = \{ a => 1 };
represent_ref
turns aREF
variable into a YAML mapping:my $data = YAML::PP::Schema::Perl->represent_ref(\{ a => 1 }); my $data = { '=' => { a => 1 } };
- construct_scalar, represent_scalar
-
Perl variables of the type
SCALAR
are represented in yaml like this:--- !perl/scalar =: string
construct_scalar
returns the perl data:my $data = YAML::PP::Schema::Perl->construct_ref([ '=', 'string' ); my $data = \'string';
represent_scalar
turns aSCALAR
variable into a YAML mapping:my $data = YAML::PP::Schema::Perl->represent_scalar(\'string'); my $data = { '=' => 'string' };
- construct_regex, represent_regex
-
construct_regex
returns aqr{}
object from the YAML string:my $qr = YAML::PP::Schema::Perl->construct_regex('foo.*');
represent_regex
returns a string representing the regex object:my $string = YAML::PP::Schema::Perl->represent_regex(qr{...});
- evaluate_code, represent_code
-
evaluate_code
returns a code reference from a string. The string must start with a{
and end with a}
.my $code = YAML::PP::Schema::Perl->evaluate_code('{ return 23 }');
represent_code
returns a string representation of the code reference with the help of B::Deparse:my $string = YAML::PP::Schema::Perl->represent_code(sub { return 23 });
- object
-
Does the same as
bless
:my $object = YAML::PP::Schema::Perl->object($data, $class);