CVE-2011-3441
CVE-2011-3246
A series of regex-writing challenges.
A series of XSS challenges: here's some unsafe code; exploit it! Shortest code wins.

My CSS-fu is weak; please use a recent browser.

Some rights reserved.

Random, semi-related image by AmUnivers.

PHP Must Die

A comparison of how different scripting languages treat their users.

/tmp$ perl -le 'print 07'
7
/tmp$ perl -le 'print 08'
Illegal octal digit '8' at -e line 1, at end of line
Execution of -e aborted due to compilation errors.
/tmp$ python -c 'print 07' 
7
/tmp$ python -c 'print 08'
  File "", line 1
    print 08
           ^
SyntaxError: invalid token
/tmp$ php -r 'print 07' 

Parse error: parse error in Command line code on line 1
/tmp$ php -r 'print 07;'    
7/tmp$ 
/tmp$ php -r 'print 08;'
0

Indeed.

A less idiotic thing to do would be to give the user a warning, or fail. Just using the wrong number is dangerous; the user might think this works after checking a few values:

$magic_dates = array(stamp(01,01,1980),
   stamp(12,31,1980),
   stamp(08,11,1950)); # fails silently!
PHP doesn't report that anything is wrong even at the most pedantic warning level:
error_reporting(E_ALL); eval("print 028;");  # prints 2 without warning
Why? Laziness, ignorance or both. PHP only supports octal numbers by accident, as evidenced by the following snippet from zend_language_scanner.l:
<ST_IN_SCRIPTING>{LNUM} {
        errno = 0;
        zendlval->value.lval = strtol(yytext, NULL, 0);
        if (errno == ERANGE) { /* overflow */
                zendlval->value.dval = zend_strtod(yytext, NULL);
                zendlval->type = IS_DOUBLE;
                return T_DNUMBER;
        } else {
                zendlval->type = IS_LONG;
                return T_LNUMBER;
        }
}
strtol() sees the first 0, decides to use octal, and eats as much of the number as it can. Because PHP completely ignores the endptr argument, it throws away the rest of the number.

Another lexer bug

Guess what this program prints?

error_reporting(E_ALL);  # doesn't help :)
foreach(array(0xffffff,
              0xfffffff,
              0xffffffff,
              0xfffffffff,
              0xffffffffff) as $x) {
  printf("%s (%s)\n", $x, gettype($x));
}
Output:

16777215 (integer)
268435455 (integer)
4294967295 (double)
2147483647 (integer)
2147483647 (integer)

A fun parser bug

This is almost as impressive. The ternary operator should be right associative, so you can do this:

 function getcolor($errors = 0, $warnings = 0) {
   return $errors ? "red" : $warnings ? "yellow" : "green";
}

PHP is the only language in which ?: is left associative. In PHP, the expression above never returns red.

/tmp$ perl -le 'print 1 ? 2 : 3 ? 4 : 5'
2
/tmp$ ruby -e 'print 1 ? 2 : 3 ? 4 : 5'
2
/tmp$ php -r 'print 1 ? 2 : 3 ? 4 : 5' 

Parse error: syntax error, unexpected $end in Command line code on line 1
/tmp$ php -r 'print 1 ? 2 : 3 ? 4 : 5;'
4

This was most likely an accident as well; the correct behavior could have been restored with a single-line change to language-parser.y, but of course it's too late now (for backwards compatibility).

Comments

python ftw. i'll come back here again. i also appreciate the cordiality of your comment form.
— Zack 2009-06-20
Use error_reporting(-1); instead of error_reporting(E_ALL); Which will enable all E_STRICT, E_NOTICE etc up.
— Lenin 2010-01-09
[I love how PHP is using its own definition of 'all'.]
ruby ftw. I'll also come back here again. This post is beautiful.
— Merrck Christensen 2010-01-09
As evidenced by decades of programming history, it's at least naive to rely on parser/compiler to make up for the the shortcomings of a programmer's brain power. The breadth of any average programmer's stupidity is so wide that compilers/parsers can not possibly cover all of it. That's why there's that little-known thing called "unit tests". Cheers.
— Irakli 2010-01-09
[You want me to write unit tests for the compiler?]
Love the anti-PHP post on a PHP site.
— Luyt, Bill S. Preston, and several others; enough now 2010-01-09
[If I didn't use it, why would I care? Besides, for a trivial site like this, the zero startup cost makes PHP a reasonable option.]

I will admit that PHP has its issues but saying that it should die is a bit overboard in my opinion as overall I like APHP compared to other languages for web development.

The issues with using wrong numbers is pretty bad but that is something I have learned to live with by always checking my variables for empty values. Of course that does not remove the fact that if you don't check your values, the is a chance you could screw up something big time.

I have also run into that ternary issue you mention and while it is backwards, all I had to do was rearrange the ternary to get it to work that way I needed it to. Sure, it is a pain in the ass but it is something you can work around.

I would pick PHP over perl any day of the week if we are talking about a language to use for running a website. As far as other languages like python, ruby, and ASP.NET(C#), if I had to pick another language to use for building websites, I would probably give C# a try first.

Now PHP is not going to die any time soon but what I think does need to happen is that PHP needs to be reborn. There are a lot of inconsistencies in the language's API itself and are some big and small language quirks like the ones you mentioned that should be fixed. The issue with this happening is that fixing all that will completely break backwards compatibility to the point it would be quicker to rewrite existing code than fix it. Will this even happen, I don't know I really hope it does.

— Ryan 2010-01-09
[The title was chosen in 2004 after a particularly bad debugging session :) I guess in therms of backwards compatibility you could make nested ?: a warning in PHP 7, an error in PHP 8, and introduce the sane semantics in PHP 10 or so.]
Your comment form is indeed awesome! Great coverage. I totally agree that this should be enough reasons to finally kill PHP.
— Pascal 2010-01-09
I'm not saying your article is flawed, or even incorrect, but I will say that each language has its own set of problems and errors.
— Shadow14l 2010-01-09
[And I will agree with you wholeheartedly.]
Do you mean die as in when you write stupid code like this PHP should die() with a message?
— r 2010-01-10
[Yes, that would be the most reasonable way of handling lexer errors.]