Merge pull request #1427 from xexyl/dlowe2k-bugs

This commit is contained in:
Landon Curt Noll authored and GitHub committed 2023-11-15 09:37:06 -07:00
commit 6403a4a5a8
2 files changed
+262 -15

No files matched your search

+34 -15
View File
@@ -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 `$#_&&$_`?
+228
View File
@@ -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