Merge pull request #1427 from xexyl/dlowe2k-bugs
This commit is contained in:
2 files changed
+262
-15
No files matched your search
+34
-15
@@ -4,12 +4,26 @@
|
||||
make
|
||||
```
|
||||
|
||||
The following bit of perl may help determining the values you need:
|
||||
The following bit of perl may help determine the values you need:
|
||||
|
||||
```sh
|
||||
perl -MConfig -e 'print "$Config{archlibexp}/CORE\n"'
|
||||
```
|
||||
|
||||
... just in case the Makefile does not figure this out for you.
|
||||
|
||||
|
||||
### Bugs and (Mis)features:
|
||||
|
||||
The current status of this entry is:
|
||||
|
||||
```
|
||||
STATUS: doesn't work with some platforms - please help us fix
|
||||
STATUS: known bug - please help us fix
|
||||
```
|
||||
|
||||
For more detailed information see [2000 dlowe in bugs.md](/bugs.md#2000-dlowe).
|
||||
|
||||
|
||||
## To use:
|
||||
|
||||
@@ -34,7 +48,7 @@ hand it qualifies as the Worst Abuse of the Rules. As a previous winner\*
|
||||
David Lowe continues to inflict the highest quality "poot" on the
|
||||
Judges.
|
||||
|
||||
The program also contains an undocumented command for Chad and Chongo.
|
||||
The program also contains an undocumented command for Chad and Chongo (Landon).
|
||||
The judges' remarks contain a clue to the hidden command :-).
|
||||
|
||||
* The IOCCC uses an anonymous judging process which keeps the identity
|
||||
@@ -51,8 +65,9 @@ of the submitters hidden until all the prize winners have been selected.
|
||||
|
||||
### Synopsis
|
||||
|
||||
This is a reverse polish calculator, loosely based on the `dc(1)` unix
|
||||
calculator.
|
||||
This is a [Reverse Polish
|
||||
calculator](https://en.wikipedia.org/wiki/Reverse_Polish_notation), loosely
|
||||
based on the `dc(1)` unix calculator.
|
||||
|
||||
# Syntax
|
||||
|
||||
@@ -89,11 +104,12 @@ modulus operator actually returns `(p1 - (p2 * (p1 / p2)))`, but with
|
||||
the innermost division calculated at integer precision. This is
|
||||
usually what you expect (e.g. `echo "12 8 % p" | ./dlowe == 4`)
|
||||
|
||||
Commands are read from stdin or from a list of files named on
|
||||
Commands are read from `stdin` or from a list of files named on
|
||||
the command line. Unlike `dc(1)`, multiple commands on the same line
|
||||
must be space separated. Commands are only executed when a newline
|
||||
or EOF is encountered.
|
||||
|
||||
|
||||
### Diagnostics:
|
||||
|
||||
```
|
||||
@@ -107,6 +123,7 @@ Floating point exception (core dumped) (or something to that effect)
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Examples:
|
||||
|
||||
```sh
|
||||
@@ -130,7 +147,7 @@ poot
|
||||
|
||||
We all know that Perl and other VHLLs (very high level languages)
|
||||
are particularly well-suited for (among other things) string
|
||||
handling, I/O, and powerful built-in datatypes, and (relatively)
|
||||
handling, I/O, and powerful built-in data types, and (relatively)
|
||||
poorly suited for number crunching and other processor-intensive
|
||||
tasks - areas where C is strongest. This program takes this
|
||||
knowledge to its extreme conclusion, using each language for its
|
||||
@@ -151,7 +168,7 @@ Unfortunately, Perl is an evolving beast - that includes the
|
||||
embedding API and the XS API. The code was developed under
|
||||
`Perl 5.005_03`, successfully tested against `Perl 5.6.0`, `Perl 5.005_02`
|
||||
and `Perl 5.004_04`, and according to the version delta documentation,
|
||||
should work as-is with Perl 5.002` and later (which has been around
|
||||
should work as-is with `Perl 5.002` and later (which has been around
|
||||
since February 1996). To clarify - it's not the Perl code itself
|
||||
that may be non-portable, it's the C code for embedding Perl and for
|
||||
calling C from Perl.
|
||||
@@ -161,13 +178,13 @@ You may have problems linking if, for example, you have multiple
|
||||
overlapping versions of Perl installed (which might not be a problem
|
||||
for scripts, but causes problems with embedding the interpreter).
|
||||
More commonly, you may get non-fatal warnings from the linker, caused
|
||||
by slight misconfigurations of Perl on your system.
|
||||
by slight mis-configurations of Perl on your system.
|
||||
|
||||
Some compilers also complain that "third argument of `main' is
|
||||
Some compilers also complain that "third argument of `main()` is
|
||||
deprecated" or something to that effect. But in Perl prior to
|
||||
`5.6.0`, the header file "proto.h" actually had a prototype for main,
|
||||
so applications which embed Perl must use the three argument form
|
||||
of main.
|
||||
`5.6.0`, the header file "proto.h" actually had a prototype for `main()`, so
|
||||
applications which embed Perl must use the three argument form of `main()`.
|
||||
|
||||
|
||||
### Aside: history...
|
||||
|
||||
@@ -176,9 +193,10 @@ years he won the IOCCC. I hope this program helps you to realize that
|
||||
this was no fluke - that Perl and Obfuscation are as inseparable as,
|
||||
say, camels and humps.
|
||||
|
||||
|
||||
### Obfuscated?
|
||||
|
||||
- Reverse polish notation is pretty strange, in and of itself.
|
||||
- Reverse Polish notation is pretty strange, in and of itself.
|
||||
|
||||
- The layout of the program is three roughly symmetrical "stacks"
|
||||
of code. This layout is quite sensitive in places - my C indenter
|
||||
@@ -224,7 +242,7 @@ input.
|
||||
- Because of the "interesting" way that commands are interpreted,
|
||||
all of the commands have synonyms. For example, if you find it
|
||||
easier to remember, `=` is synonymous with `d`. This also makes it
|
||||
possible to write (even more) obfuscated reverse polish commands
|
||||
possible to write (even more) obfuscated reverse Polish commands
|
||||
(I figure this explanation moves the synonyms from 'bug' to
|
||||
'feature'!)
|
||||
|
||||
@@ -247,7 +265,8 @@ beautifier won't help too much, either ;)
|
||||
|
||||
If you don't change the rules, it'll be embedded Ada next year!
|
||||
|
||||
### AutoDefend
|
||||
|
||||
### Auto defend
|
||||
|
||||
A. Isn't this the obfuscated C contest? What's this Perl `$#_&&$_`?
|
||||
|
||||
|
||||
@@ -1507,6 +1507,234 @@ There was no IOCCC in 1999.
|
||||
# 2000
|
||||
|
||||
|
||||
## 2000 dlowe
|
||||
|
||||
### STATUS: doesn't work with some platforms - please help us fix
|
||||
### Source code: [2000/dlowe/dlowe.c](2000/dlowe/dlowe.c)
|
||||
### Information: [2000/dlowe/README.md](2000/dlowe/README.md)
|
||||
|
||||
This **MIGHT** be better described as doesn't work with some versions of perl:
|
||||
the author states that in perl < 5.6.0 there is a bug with a core dump in what
|
||||
they said is in `Perl_sv_upgrade`. This does not exist in the code, seemingly,
|
||||
but it might be that this is impossible to fix without getting a perl upgrade.
|
||||
In any event the below details a problem. Another bug that happens in linux also
|
||||
is below.
|
||||
|
||||
In macOS this program crashes. A tip from Cody is that the code that crashes is:
|
||||
|
||||
```c
|
||||
perl_eval_sv
|
||||
(newSVpv("_:$_= <> ; defined or exit; @ARGV"
|
||||
"=split; __:$_= shift;defined or goto _; chomp "
|
||||
";(m*^\\x70oO" "\\x74$*i)?(pri" "nt \"$_ w\\x"
|
||||
"61s h\\145r\\x" "65!\\n\"):((m*" "^\\s\\*(-?\\d+"
|
||||
"(\\.\\d+)?)\\s" "\\*$*)?(push@SS ,$1):(&{chr(((o"
|
||||
"rd)%39)+3**4)x2 } )); goto __; sub ff { @SS= ("
|
||||
")} sub __{print \"stack empty\\" "n\"} sub ss{$#"
|
||||
"SS<0 and goto & __; print $SS[$" "#SS].\"\\n\"} "
|
||||
"sub SS{ $#SS<0 and goto &__ ; print pop @SS}"
|
||||
"sub _ { print \"divide by zer" "o\\n\"}sub ii{"
|
||||
"map{ print\"$_" "\\n\" } reverse @SS} sub AUTOLO"
|
||||
"AD { print\"un" "implemented\\n" "\"} sub gg{ $#"
|
||||
"SS<0 and goto &__;push@SS,$SS[ $#SS]} sub uu{ "
|
||||
"$#SS<1 and goto &__;$SS[ $#SS]+= $SS[$#SS-1];$SS"
|
||||
"[$#SS-1]=$SS[$" "#SS]-$SS[$#SS-" "1]; $SS[$#SS]-"
|
||||
"=$SS[$#SS-1]} ",0),0 );
|
||||
```
|
||||
|
||||
and in particular it appears that it is the perl itself. In other words if one
|
||||
changes it to be:
|
||||
|
||||
```c
|
||||
perl_eval_sv(newSVpv("",0),0);
|
||||
```
|
||||
|
||||
it will not crash. But of course it won't do anything either. So it's more
|
||||
specifically that the call to `newSVpv()` crashes the code but _INSIDE_
|
||||
(key point!) the call to `perl_eval_sv()` that does it. Given what the author
|
||||
stated and that the version of perl is < than 5.6.0 that might be exactly what
|
||||
is going on.
|
||||
|
||||
The example command above _should_ print:
|
||||
|
||||
```sh
|
||||
$ echo "13 14 15 16 17 + - * / p" | ./dlowe
|
||||
-0.0515873015873016
|
||||
```
|
||||
|
||||
and that's what it shows in linux.
|
||||
|
||||
Note that with different perl libraries in macOS (for instance from
|
||||
[Homebrew](https://brew.sh) and [MacPorts](https://www.macports.org) it will
|
||||
likely print different warnings when compiling. It was observed that with
|
||||
Homebrew it does not report any warnings but with MacPorts it results in a total
|
||||
of 92 warnings! Nonetheless neither works okay and both crash.
|
||||
|
||||
|
||||
### STATUS: known bug - please help us fix
|
||||
|
||||
The author gives an example command:
|
||||
|
||||
```sh
|
||||
echo "7 P 6 d P P 8 p" | ./dlowe | tr 876 tpo
|
||||
```
|
||||
|
||||
which should print out `poot` but it doesn't, not in linux and not in macOS.
|
||||
This might in part be because `./dlowe` will show not a number with `876` but
|
||||
rather
|
||||
|
||||
```sh
|
||||
$ echo "7 P 6 d P P 8 p" | ./dlowe
|
||||
7668
|
||||
```
|
||||
|
||||
In linux it doesn't crash but it doesn't print anything out either.
|
||||
|
||||
In macOS it crashes; it might appear to not crash in macOS but this is because
|
||||
of the pipeline. If you remove the `| tr 876 tpo` part of the command you will
|
||||
see that it does indeed crash!
|
||||
|
||||
Other commands do work, however, and give the appropriate output, such as:
|
||||
|
||||
```sh
|
||||
$ echo 1 2 + p | ./dlowe
|
||||
3
|
||||
```
|
||||
|
||||
so something is wrong with some commands/operators.
|
||||
|
||||
Another feature that does work in linux is:
|
||||
|
||||
```sh
|
||||
$ echo poot | ./dlowe
|
||||
poot was here!
|
||||
```
|
||||
|
||||
Can you help fix these problems?
|
||||
|
||||
Cody provided the C code that creates an unformatted perl script that will just
|
||||
print 'unimplemented' for operators but it seems to work in some other ways (see
|
||||
below for how to go further than unimplemented) which is the exact perl from the
|
||||
C program except that it has the `#!/usr/bin/env perl` and `use warnings;` as
|
||||
well. A note below might suggest that doing this creates incomplete perl.
|
||||
Anyway:
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
int main(void)
|
||||
{
|
||||
printf("#!/usr/bin/env perl\nuse warnings;_:$_= <> ; defined or exit; @ARGV"
|
||||
"=split; __:$_= shift;defined or goto _; chomp "
|
||||
";(m*^\\x70oO" "\\x74$*i)?(pri" "nt \"$_ w\\x"
|
||||
"61s h\\145r\\x" "65!\\n\"):((m*" "^\\s\\*(-?\\d+"
|
||||
"(\\.\\d+)?)\\s" "\\*$*)?(push@SS ,$1):(&{chr(((o"
|
||||
"rd)%%39)+3**4)x2 } )); goto __; sub ff { @SS= ("
|
||||
")} sub __{print \"stack empty\\" "n\"} sub ss{$#"
|
||||
"SS<0 and goto & __; print $SS[$" "#SS].\"\\n\"} "
|
||||
"sub SS{ $#SS<0 and goto &__ ; print pop @SS}"
|
||||
"sub _ { print \"divide by zer" "o\\n\"}sub ii{"
|
||||
"map{ print\"$_" "\\n\" } reverse @SS} sub AUTOLO"
|
||||
"AD { print\"un" "implemented\\n" "\"} sub gg{ $#"
|
||||
"SS<0 and goto &__;push@SS,$SS[ $#SS]} sub uu{ "
|
||||
"$#SS<1 and goto &__;$SS[ $#SS]+= $SS[$#SS-1];$SS"
|
||||
"[$#SS-1]=$SS[$" "#SS]-$SS[$#SS-" "1]; $SS[$#SS]-"
|
||||
"=$SS[$#SS-1]}");
|
||||
}
|
||||
```
|
||||
|
||||
Compiling this you can generate:
|
||||
|
||||
|
||||
```perl
|
||||
#!/usr/bin/env perl
|
||||
use warnings;_:$_= <> ; defined or exit; @ARGV=split; __:$_= shift;defined or goto _; chomp ;(m*^\x70oO\x74$*i)?(print "$_ w\x61s h\145r\x65!\n"):((m*^\s\*(-?\d+(\.\d+)?)\s\*$*)?(push@SS ,$1):(&{chr(((ord)%39)+3**4)x2 } )); goto __; sub ff { @SS= ()} sub __{print "stack empty\n"} sub ss{$#SS<0 and goto & __; print $SS[$#SS]."\n"} sub SS{ $#SS<0 and goto &__ ; print pop @SS}sub _ { print "divide by zero\n"}sub ii{map{ print"$_\n" } reverse @SS} sub AUTOLOAD { print"unimplemented\n"} sub gg{ $#SS<0 and goto &__;push@SS,$SS[ $#SS]} sub uu{ $#SS<1 and goto &__;$SS[ $#SS]+= $SS[$#SS-1];$SS[$#SS-1]=$SS[$#SS]-$SS[$#SS-1]; $SS[$#SS]-=$SS[$#SS-1]}
|
||||
```
|
||||
|
||||
Here is example input/output:
|
||||
|
||||
```
|
||||
p
|
||||
stack empty
|
||||
5 p
|
||||
5
|
||||
5 + 5 p
|
||||
unimplemented
|
||||
5
|
||||
P
|
||||
5
|
||||
p
|
||||
5
|
||||
```
|
||||
|
||||
So you can see that if one uses operators it just shows 'unimplemented' (observe
|
||||
how this does not happen in the C program in linux!) but if one uses 'p' by
|
||||
itself it will print what's on the stack (for example).
|
||||
|
||||
To not get 'unimplemented' you can remove from the perl:
|
||||
|
||||
|
||||
```perl
|
||||
sub AUTOLOAD { print"unimplemented\n"}
|
||||
```
|
||||
|
||||
(Note that the author stated this was used for exception handling so another
|
||||
possibility is that the C code doesn't generate the correct perl and indeed even
|
||||
spaces is known to break the perl in at least one way, syntax errors, but maybe
|
||||
others too.)
|
||||
|
||||
Here is an example run of several operations in the perl script after removing
|
||||
that subroutine:
|
||||
|
||||
```sh
|
||||
$ echo 5 5 p | ./dlowe.pl
|
||||
5
|
||||
$ echo 5 5 + p | ./dlowe.pl
|
||||
5
|
||||
Undefined subroutine &main::UU called at ./pl.pl line 2, <> line 1.
|
||||
$ echo 5 5 * p | ./dlowe.pl
|
||||
5
|
||||
Undefined subroutine &main::ww called at ./pl.pl line 2, <> line 1.
|
||||
$ echo 5 5 - p | ./dlowe.pl
|
||||
5
|
||||
Undefined subroutine &main::WW called at ./pl.pl line 2, <> line 1.
|
||||
$ echo 5 5 / p | ./dlowe.pl
|
||||
5
|
||||
Undefined subroutine &main::YY called at ./pl.pl line 2, <> line 1.
|
||||
$ echo 5 P | ./dlowe.pl
|
||||
5$ echo p | ./dlowe.pl
|
||||
stack empty
|
||||
$ echo P | ./dlowe.pl
|
||||
stack empty
|
||||
```
|
||||
|
||||
Note the undefined subroutine error: that happens with commands that are not
|
||||
even in the program. Again the author used `AUTOLOAD` for exception handling so
|
||||
it seems likely that there is something missing (which the below shows as well).
|
||||
For instance inputting `D` followed by `XX`:
|
||||
|
||||
```
|
||||
Undefined subroutine &main::nn called at ./pl.pl line 2, <> line 6.
|
||||
Undefined subroutine &main::[[ called at ./pl.pl line 2, <> line 1.
|
||||
```
|
||||
|
||||
That means then that in linux despite the subroutines seemingly not existing it
|
||||
works in the code, at least in some cases.
|
||||
|
||||
As far as the unimplemented error goes: the author stated that it means there is
|
||||
invalid input. But as can be seen by the input I (Cody) gave the input is not
|
||||
actually incorrect. It is also curious to note that it ends up printing what's
|
||||
on the stack at that point:
|
||||
|
||||
```sh
|
||||
$ echo 5 5 + p | ./dlowe.pl
|
||||
unimplemented
|
||||
5
|
||||
```
|
||||
|
||||
which might (?) suggest that the `+` operator is unimplemented. Unfortunately it
|
||||
has been many years since I have used perl and I was never a guru either.
|
||||
|
||||
|
||||
## 2000 primenum
|
||||
|
||||
### STATUS: INABIAF - please **DO NOT** fix
|
||||
|
||||
Reference in new issue
Block a user