Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re: Perl data notation

by davido (Cardinal)
on Jul 15, 2014 at 14:54 UTC ( [id://1093720]=note: print w/replies, xml ) Need Help??


in reply to Perl data notation

If by Perl's data notation you mean Data::Dumper type output, that's what Data::Dumper does; it serializes data structures in such a way that they would be perfectly legal as source code. That makes it possible to eval them back to existence.

But consider the implications of string eval: You would be executing your input. In the context of web work, you would be eval'ing (compiling and running) user input! That is the biggest of all possible security risks.

So to do it safely, you would need to come up with a module that parses the input similar to the way in which a JSON parser parses its input, and then returns a living data structure. And by the time you've done that, you may as well just use JSON; a format that everyone knows and understands, with robust parsing solutions available.

Even though JavaScript could "eval" most JSON input, in practice it's not done that way, for the same reason I've described above. Instead, it parses JSON into a data structure using a JSON parser, never actually compiling and executing it.


Dave

Replies are listed 'Best First'.
Re^2: Perl data notation
by kennethk (Abbot) on Jul 15, 2014 at 15:11 UTC
    <pedantic>
    That makes it possible to eval them back to existence.
    This holds for basic data structures, but fails for three cases (I know of):
    1. Repeated entries for the same reference
    2. Subroutine references
    3. Objects with hidden lexical content
    That first one is the most common; consider
    perl -MData::Dumper -e 'my $ref = []; print Dumper eval Dumper [$ref, + $ref];
    which outputs
    $VAR1 = [ [], undef ];
    and (thankfully) fails under strict.

    </pedantic>


    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      It may not solve all the problems you mentioned, but:

      $ perl -MData::Dump=pp -le '$ref = []; print pp eval pp [$ref, $ref];' do { my $a = [[], 'fix']; $a->[1] = $a->[0]; $a; }

      D::D can handle #1. You just gotta use Purity=1

      D::D can handle #2. You just gotta use Deparse=1

      I believe Storable will handle subrefs, but the eval problem doesn't go away. Storable does provide a way for the user to get between the input and the eval though. And of course Storable's frozen output is anything but legible.


      Dave

        For the truly motivated, B::Deparse can serialize into a legible format.

        use strict; use B::Deparse; my $deparse = B::Deparse->new(); my $func = sub { my %hash = @_; return $hash{a}; }; my $body = $deparse->coderef2text($func); print $body;
        You could condition the tree by crawling it and clobbering anything with reftype CODE with sprintf 'sub %s', $deparse->coderef2text($hash{key}). But this still kills closures, and plus is a terrible, terrible idea.

        #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      Again, it doesn't solve all the problems you mentioned, but:

      $ perl -MData::Dumper -le '$Data::Dumper::Deparse=1; \ print Dumper eval Dumper sub { $x++; print "Hello"; }' $VAR1 = sub { ++$x; print 'Hello'; };

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1093720]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (5)
As of 2024-04-23 21:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found