Problem/Motivation
Drupal\file\Plugin\Field\FieldType\FileItem::getUploadValidators() always sets the maximum file size for uploading based on post_max_size and upload_max_filesize PHP settings.
That prevents us from avoiding max file size validation for some use-cases. A typical use case where this would be helpful is when files are not stored on the same server as Drupal (e.g. they are stored in a remote file system, S3).
Proposed resolution
Let file size validator use max_filesize setting if it is explicitly configured (not empty) only.
Otherwise, we should either skip file_validate_size() completely or do the call and indicate that no file size limit should be enforced.
Remaining tasks
User interface changes
API changes
Data model changes
Comments
Comment #2
mbovan commentedThe first patch that implements the idea from the issue summary.
Comment #3
mbovan commentedComment #4
berdirthis is also used for the actual upload validation.
I think we should instead just alter it in the constraint only, so we don't do this validation for existing files.
Also, this is IMHO a bug/regression because 7.x didn't do anything like this.
Comment #5
berdirThat said, I don't really understand why we do need that in there, as you wouldn't actually ever get that far if it's over the system limit?
But that's for another issue to change/discuss.
Comment #7
mbovan commentedUpdates as suggested in #4.
Comment #8
mbovan commentedAnd conversions...
Comment #9
mbovan commentedAhh.. Removed duplicated comment.
Comment #10
mbovan commentedNot sure in which version this should go... Here is the #9 with unchanged old array syntax (applies to 8.2.7).
Comment #12
berdirLooks good to me, I don't really know how we could test this nor how we need to convince to RTBC this. Possibly crosspost in the S3 CORS upload issue, as I'm sure people there will run into this problem.
Maybe we can improve the comments a bit and clearly state that files that are already uploaded and/or might even be stored remotly to not need to respect the max upload size. Needs work for that.
Comment #13
berdircould reads strange, maybe we can change the test to specifically mention *Uploading files to the server will...* or so.
Comment #14
berdirIdea how we could have *some* test coverage:
Move the logic for getting the validators into a protected helper method, write a unit test that uses mocking and a subclass to call that helper directly and get the validators, with different settings.
Comment #19
berdirReroll.
Comment #24
gabesullice<- I think this got messed up in the reroll.
This makes it impossible to set
max_filesizeto 0.I think that's acceptable because one should disable the field or make it inaccessible. However, it'd make the code more pleasing if it precisely matched the comment. Something like:
Comment #25
gabesulliceMaybe I'm misunderstanding this because I'm not very familiar with file system stuff, but couldn't one argue that this is an upstream bug/missing feature in PHP? E.g. shouldn't there be stream wrapper specific versions of
upload_max_filesizeso that Drupal doesn't have to ignore its environment's configuration?Comment #26
berdirupload_max_filesize is a PHP ini setting that PHP automatically enforces, this is not related to stream wrappers. The file could absolutely live in the regular sites directory, maybe you've built a custom feature that imports files from a file share or whatever.
This is about validating a file that already exists on the server in regards to whether or not you would be able to upload it to that server. Why would you do that?
If you move to a new server that has a lower upload limit, does that make all your existing files suddenly invalid?
It makes sense to check the setting so that we can tell the user that this limit applies, but that's all it should be used for.
Comment #27
gabesulliceThanks for helping me understand @Berdir. I misinterpreted the issue to be about uploading to the filesystem or to alternative storage like S3 and made the assumption that the problem was that
upload_max_filesizeshouldn't/doesn't apply when forward-streaming the upload to an S3 bucket.Comment #28
kim.pepperCan we add a test for this?
Comment #29
berdirI tried, but no, not easily. upload_max_filesize can't be changed/set at runtime. It doesn't just not use the value, it actively ignores an attempt to set it.
And without the ability to change it, I doubt that we want to have a test that creates a file that is bigger than upload_max_filesize, whatever that value might be.
If that would work, then doing something like \Drupal\Tests\file\Kernel\FileItemValidationTest::testFileValidationConstraint() and setting that instead of the explicit setting would work.
I suppose we could write a unit test for FileValidationConstraintValidator and mock getUploadValidators() and everything else going on, including the function call to file_validate(), but that seems like a lot work with a lot of hardcoded assumptions about the exact implementation of the code.
If your patch to make them separate constraints would move that logic out of \Drupal\Tests\file\Kernel\FileItemValidationTest::testFileValidationConstraint() and into whatever logic creates dynamic constraints with configuration then maybe we could check that?
Comment #30
hchonovreroll.
Comment #32
jcnventuraBytes::toInt() is deprecated in drupal:9.1.0 and is removed from drupal:10.0.0Also, please take into account the comment in #24 where we should check if the setting exists instead of checking if it is not 0.
One personal nitpick: I really dislike the code readability of
if (a = b) {}instead ofa = b; if (a) {}. There's coding standards for writing secure code that specifically forbid this kind of thing because of how easy it is to overlook what is happening here.Comment #33
jcnventuraComment #35
jcnventuraNeeded another further fix.
Comment #36
jonathanshawFileFieldValidateTest already tests that the max filesize field setting is respected on both upload and other validation.
Per #29 there is no good way to test that the php environment setting is respected on upload but correctly ignored with other validation.
Comment #38
berdirRandom JS test fail, looks very unrelated?
Comment #42
berdirReroll for 9.5+.
Comment #44
ravi.shankar commentedIt's green so changing status to needs review.
Comment #45
jonathanshawrtbc per #38
Comment #47
catchThis looks fine and I also can't think of way to test it. Committed/pushed to 10.1.x, cherry-picked to 10.0.x and 9.5.x, thanks!
Comment #49
omd commentedCouldn't this be tested this with the plupload api module and the plupload widget module?