Hello Internals!

I originally posted this to Github as an issue -
https://github.com/php/php-src/issues/20456 - but someone there
recommended that I post it to this list instead. Including the same
content here.

If you run this script:

<html><title>test</title>
<body>
<form method="POST" action="">
    <?php
    for($i=0;$i<1200;$i++) {
        print "<input type='hidden' name='test[]' value='$i' />";
    }
    ?>
    <input type="submit">
</form>
<?php
if(isset($_REQUEST['test'])) {
    print "<div>Total test values: ".count($_REQUEST['test'])."</div>";
}
?>
</body>
</html>

You end up with this:

Warning: PHP Request Startup: Input variables exceeded 1000. To
increase the limit change max_input_vars in php.ini. in Unknown on
line 0
Total test values: 1001

Instead of the expected:

Total test values: 1200

That warning is nice and all, but in the world of modern PHP with a
framework like Laravel - too much has changed or is changing, such
that a default installation of at Laravel suppresses all warnings,
because they've grown too noisy. My boss and I lost two days
troubleshooting this, and we ended up actually mangling user data in
the process.

I'm wondering if there isn't a better way to handle this. I can think
of a few options -

1. Get rid of the option entirely (ignoring it in php.ini). Just let
people submit as much stuff as they want. I don't know enough about
the technical implementation to say whether or not that's a good idea.
1.a Get rid of the option for 64-bit machines. If the hash table
collision problem that is mentioned in the documentation for this
setting is only ameliorated on 64-bit machines, then this might do the
trick.
2. Return a 400-series code - perhaps "413 Payload Too Large". This
would've allowed us to at least find the problem much sooner.
3. Return a 500-series code - I like this less, but we still would've
at least found the issue if this had happened. And you could argue
that it's the server's fault that it can't handle all of those
variables.
4. If the problem is something to do with hash tables, maybe we can
relax the variable count to only include variables with different
names - permitting our very-large array to be submitted correctly?
5. Return an error instead of a warning - that would've at least shown up.
6. Something else?

What I think is *not* good is just (semi-)silently truncating the
input that's being submitted from the form. For our use-case, that
resulted in some users actually losing data - removing group
memberships for whichever of their users was at the 'end' and making
it hard to change the actual permissions of the group (which show up
'after' the user list, so they were getting chopped off the end).
We've worked around the problem by smashing all the values together
using Javascript and submitting them as one big giant comma-delimited
list, but I would much rather us not having to do that - nor do I want
other developers to run into this problem and have to do similar
workarounds.

My C is pretty rusty, but I'm happy to try and take a swing at
changing this if we can come up with a decision on which approach we
think is best, if any.

Thank you so much, always, for making PHP! It's been my daily-driver
programming language for probably around 25 years now :)

-B.

Reply via email to