http://qs321.pair.com?node_id=294899


in reply to Worst thing you ever made with Perl

My First Worst would be Wappy. It's not my first Perl code, but it was the first Perl code I used on a website that got a reasonable amount of visitors.

At http://wappy.to/, people can make their own WAP sites. For those who don't know: WAP stands for Wireless Application Protocol and many find writing valid XML hard. Anyway, Wappy was made to be the first free WAP redirection service and the second free easy WAP site builder. The second, because the first was also made by me. That one did not even have user accounts. Pages would be saved once and then be read-only.

So Wappy needed to have a database. I thought SQL was hard back then and didn't know of abstraction. This resulted in a GDBM_File that holds all user data, serialized by hand, not dealing with bad user input. This file is 38M now.

sub setuser($){ my $user = $_[0]; for (0..8){ $TITLES[$_] = '--' if $TITLES[$_] eq ''; $CARDS[$_] = '--' if $CARDS[$_] eq ''; } for (0..4){ $LURLS[$_] = '--' if $LURLS[$_] eq ''; $LALTS[$_] = '--' if $LALTS[$_] eq ''; } my $titles = join "<==>", @TITLES; my $cards = join "<==>", @CARDS; my $lurls = join "<==>", @LURLS; my $lalts = join "<==>", @LALTS; my $value = join "<~~>", ( $USER{pass}, $USER{name}, $USER{mail}, $USER{url}, $USER{mode}, $USER{rurl}, $titles, $cards, $USER{keywords}, $USER{desc}, $lurls, $lalts, $USER{wbmp}, $USER{maillink}, $USER{goto} ); $DB{$user} = $value; logline("wapfunc: setuser $user"); }
I think you can guess how to break that :)

But things are worse than just this. The sub above is in a .pm file, but it has no package of its own. Actually, we had some issues with global variables and didn't know about local and my. So there are variables like $foo_12523, just to make sure we got a fresh variable :)

Of course (?), we didn't use CGI.pm. We benchmarked it and it made everything even slower than it already was. So I came up with something we have all seen before:

sub leesinfo() { for (split /&/, ($ENV{REQUEST_METHOD} eq 'GET' ? $ENV{QUERY_STRING +} : <>)) { split /=/; for (@_) { tr{+} { }; s{%([0-9A-Fa-f]{2})} {pack('c',hex($1))}ge; } $fields{$_[0]} = $_[1]; } $gelezen = 1; }
The worst thing about this is not that we hand-parsed things, I'm still reasonably comfortable with that. Not even that we used split in void context. No, the worst thing is that it uses the magic ARGV. Which with a query string of /dev/urandom means there is a problem. Did I mention that I set $/ to undef before we did anything else?

The mail sending thing could be used as a spam gateway. And it was used for that. I don't want to talk about this ;)

On non-Perl side, this site still has some things that the users don't like. There is no way to have your user account deleted. Or to retrieve your lost password. The site still uses another website to do image conversion. It could just have used Imager or Image::Magick, of course.

Wappy gets no attention. It should be re-written from scratch. We changed the design recently to test a new worker's design capabilities, but apart from that not much has happened in the past few years. User mail is usually moved to /dev/null, since 99% of all mail we get on that address is spam.

Wappy has 54464 registered users, of which 1500 signed up in the last 30 days. The number of visitors is still growing. The site now has 2100 visits per day, according to webalizer. Wappy has been featured in printed magazines several times, last time was three months ago. The site got its last technical change in March 2000. (Okay, I'm not counting the security fixes I did before writing this)

All those people don't realize how awful the code behind Wappy really is. People should stop using it (and stop writing about it in magazines) so we can let it die peacefully.

If I had to re-code this today, I'd use PLP, Class::DBI, MIME::Lite and of course strict.

Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }