Tricky Perl Quine

Original author: Tony Finch
  • Transfer
Note Lane: Met today on Twitter very funny, at first glance, a thread. And then he took a closer look and realized that he was not only funny, but also entertaining. And since it so happened that today is Friday, I decided that it was worth sharing it with my friends :)

image

Save the following program in /tmp/quine.pl

Illegal division by zero at /tmp/quine.pl line 1.

Run it with the command

perl /tmp/quine.pl

and she will output her own code.

Quake-tricks are quite easy to compose in many programming languages, where a syntax error in the source provokes a parser to output an error that would coincide with the source code of the program. I posted several of these tricks on Twitter , including the following:

  File "quine.py", line 1
    File "quine.py", line 1
   ^
IndentationError: unexpected indent

But the pearl barley at the beginning of this article is a trick of a completely different kind - the program understands correctly . And it does not work long, until it stumbles on the error of division by zero. This quine is very sensitive to file naming - for example, running through ./quine.pl will not work.

So this error message is actually the whole program ?!

This program uses a lot of the pearl-bar do-what-I-mean-parser.

The symbol / is very dependent on the application context and can be regarded as a division symbol, or as the beginning of a regular expression. And even small changes in the code of this program lead to an error in parsing the regularity, and not to code execution. In this case, both / characters appear in the context of the operator.

Other non-dictionary parts of this program is 1.that which is interpreted simply as a number and . which is the concatenation operator.

Then what do the words mean?

Words in Perl can be names of routines, methods, packages, or classes. Or (in lazy mode) lines without a separator or maybe even something else that I forgot about!

Perl also uses an unusual method call syntax called the " indirect object syntax ", which looks like this:

метод объект аргументы
most often you can see how

print $filehandle "message";
my $instance = new Class(args);

although for Perl, the following syntax is preferable:

$filehandle->print("message");
my $instance = Class->new(args);

The perlobj documentation says:

Perl uses heuristics to parse this code, based on what package names it knows, what subroutines exist in the current package, what words it has encountered before and analyzing other input data. Needless to say, heuristics can produce very unexpected results!
How does he parse this code?
Starting on the right side

pl line 1.

parsed as a method call

line->pl(1.)

where line is the name of the package (class), and pl is the method.

In the middle, “at”, “tmp” and “quine” are parsed as simple words, i.e. strings. The expression is parsed as follows:

(("at" / "tmp") / "quine") . line->pl(1.)

On the left are two folded indirect method calls,

division->Illegal(zero->by( ... ))

The internal expression executed first is:

"at" / "tmp"

And this instantly causes the division by zero exception.

Also popular now: