Closed (fixed)
Project:
Drupal core
Version:
8.9.x-dev
Component:
file system
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
28 Nov 2018 at 22:46 UTC
Updated:
20 Apr 2020 at 11:04 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
jhedstromSomething like this perhaps...
Comment #3
borisson_I guess this makes sense, but let's add a test for this as well.
Comment #4
jhedstromHere's a test.
Comment #5
borisson_Awesome, that test looks like it provides sufficient coverage.
Comment #6
catchThis looks sensible but would a 400 or 404 be more appropriate for the error?
Comment #7
jhedstromCurrently a 404 is thrown (after processing file hooks), so I guess the least impactful code to throw here would still be a 404? 400 might make more sense though...
Comment #8
jhedstromEr, wait, a 403 is currently thrown here. I mis-read the code:
Comment #9
catchhmm would be good to get a test-only patch to confirm exactly what happens now, but if so maintaining the same behaviour while doing the shortcut seems OK.
Comment #10
alexpottI've run the test without the fix.
So the behaviour is unchanged (as expected). I'm not sure we can test for this early return but it is good to have an explicit test of calling system/files with no query string. If we had the ability to use expressions in our routes we could do something like https://symfony.com/doc/current/routing/conditions.html but we don't have that.
Comment #11
alexpottThis condition feels a bit loose. Given PHP's fun with false equivalence. How about we make this super-explicit and do
prior to the getting.
Comment #12
jhedstromSince we already had a
file_test_file_downloadimplementation of the hook, I added to that so we can explicitly test for the hook not being invoked with an empty file. I've also addressed #11.Comment #14
alexpottIt's not an empty file :) - I think we need to be explicit that we mean no file query parameter. However this does pose the question below...
Hmmm... so now the words "empty file" are making me think about how we should handle URLs that end like
?file=.Also reading the whole \Drupal\system\FileDownloadController::download() is instructive.
This makes me wonder whether or not the current behaviour of AccessDeniedHttpException is correct. I guess there is no reason to change this. But for me pass no file is very similar to the
file_exists()check returning false. OTOH something does exist - a directory - but this should not give access to them so perhaps a 403 is the correct response.And thinking even more about this check I wonder if we should be doing this instead
if (file_stream_wrapper_valid_scheme($scheme) && is_file($uri)) {because I think that BinaryFileResponse cannot possibly work with directories. This would deal with a$urilikeprivate://too.Perhaps the best change would be
Should it be
is_dir()or!is_file()- i.e should we allow symbolic links here... I dunno - maybe a follow up to discuss. Ah looking at the Symfony code eventually \Symfony\Component\HttpFoundation\File\File::__construct() gets called and that doesSo I think maybe the best fix would be to do:
This will change to throw 404s but it will work for empty file query strings and when they point to directories or links neither of which are supported.
Comment #15
berdir> It's not an empty file :) - I think we need to be explicit that we mean no file query parameter.
Yeah, which is why I was confused initially when I saw this issue title :)
Comment #16
jhedstromThis makes the changes suggested in #14 and should remove the use of 'empty' to describe the issue :)
Comment #19
mr.baileysThe comment mentions access denied, but the assertion expects 404.
Patch also needs a reroll, no longer applies against 8.9.x-dev (FileManagedAccessTest was converted to a Kernel test in #3048434: Convert FileManagedAccessTest into a Kernel test, and there is a conflict in FileDownloadController.php). Both seem easy to resolve, so tagging as a novice issue)
Comment #20
mr.baileysForget to set to NW because of issues mentioned in #19.
Comment #21
peximo commentedWorking on it in DrupalCon Amsterdam 2019
Comment #22
petr illekYAY! First time mentoring at DrupalCon Amsterdam 2019.
Comment #23
cgoffin commentedHelping peximo on this issue at DrupalCon Amsterdam 2019.
Comment #24
fabio84I'm helping peximo too at DrupalCon Amsterdam 2019
Comment #25
francescoq commentedI'm here to help too!
Comment #26
pandaski commentedIs it necessary to check the filesize for downloading?
is_file($path) && (filesize($path) > 0)Comment #27
scuba_flyHelping on this issue as a mentor on DrupalCon Amsterdam 2019
Comment #28
peximo commentedComment #29
scuba_flyWe need a some advice about how to rewrite the test.
Comment #30
scuba_flyWe talked with Lendude and concluded we need a new test extending BrowserTestBase because there is an HTTP request.
Comment #31
peximo commentedSince
FileManagedAccessTestwas converted to a Kernel test but we need an HTTP request in this case, I've added a new Browser test. Also I've changed the comment and rerolled the patch.Comment #32
mr.baileysComment #33
mr.baileysThanks @peximo, looks good!
Since your test now runs in isolation and for every test a new environment is set up, there is no reason to store the previous value of file_test.hook_file_download_called, You can just assert that at the end of the test that the hook_file_download count === 0.
Can you update the test and provide an interdiff (see Creating an interdiff)?
Comment #34
peximo commentedThanks @mr.baileys, updated
Comment #35
francescoq commentedSeems good to me! I applied the patch and everything was fine also testing with xdebug to make sure that the hook was not called without file argument.
Also the test is green for me.
Comment #36
francescoq commentedComment #37
mr.baileysThe patch could not be applied in #34, so still some work to be done.
Comment #38
peximo commentedMissing added file.
Comment #39
rachel_norfolkretagging
Comment #40
scuba_flyHere's the interdiff of 34->38
Comment #41
mr.baileysI think we are almost there!
The message in an assertion needs to be a statement that you expect to always be true, so instead of "... was triggered but should not have been", the assertion message should be something like "hook_file_download() was not triggered."
Comment #42
mr.baileysComment #43
peximo commentedUpdated the message.
Comment #44
mr.baileysLooks good, and the tests pass.
@peximo, just one more question since the test has changed quite a bit since #12: could you upload a "test only" patch? If that one fails, and the combined patch succeeds (as it did in #43), it proves that the test is correct. If the test-only patch succeeds, we know it's not correctly testing the issue.
Comment #45
peximo commentedComment #47
scuba_flyComment #48
scuba_flySee #44 the TEST-ONLY.patch needs to fail. So I've set it to needs review.
Comment #49
scuba_flyAs mentioned earlier, looks good.
The state is set to 0 + 1 if empty, or the number of calls + 1 if already called.
Check the state Equals still 0.
I think this can be set to RTBC?
Comment #50
alexpottAll the complexity of have this as a count is not needed for the test. It should be a flag ie TRUE or FALSE. Also we have no test that the flag/count ever gets set so this test is very vulnerable to become a false positive - testing for the absence of doing something is always tricky.
It is always helpful if negative tests like this are placed alongside positive tests.
Comment #51
alexpottWe can leverage existing file test plumbing to test this and add the test to
core/modules/file/tests/src/Functional/DownloadTest.phpComment #53
init90The code looks good, the patch applied clearly, during manual testing the result was as expected. Thanks!
Comment #54
neslee canil pinto@init90, Thanks for the review. Can you please apply a screenshot for the manual testing results.
Comment #55
jungleRerolled from #51
Comment #56
init90@neslee-canil-pinto thanks for your message. Actually, I don't think that screenshots here are needed. One difference that we have, without patch when we don't specify a file we will get 403-page status and potential errors from contrib/custom code which don't check in hook_file_download if the file really exists. In the same case with the patch, we will get 404-page status and no potential errors, because hook_file_download won't be executed.
@jungle thanks for the reroll. I don't know why but the patch from #51 applies clearly in my machine with the last update in 8.9.x branch.
Comment #57
alexpottCredited everyone who worked with @peximo on this at Drupalcon.
Committed 24e1692 and pushed to 9.1.x. Thanks!
I improved the test text on commit. Going to ping release managers about backporting this to 9.0.x and 8.9.x
Comment #59
alexpottDiscussed with @catch and we agreed to cherry-pick this to 8.9.x and 9.0.x
Comment #63
vctlzac commentedIs there a version of this code for drupal 7?