Closed (fixed)
Project:
Drupal core
Version:
7.x-dev
Component:
base system
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
26 Jun 2010 at 20:25 UTC
Updated:
26 Oct 2015 at 09:57 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
criticalpatch commentedI can confirm this bug exists in drupal 7 as well as the current stable release 6.17.
To clarify the steps to reproduce this error, you must visit a uid that does not exist!
Since I believe uid 1 will always exist, the url mentioned above will not display the error.
Try visiting user/reset/0/1/1 instead.
I've attached a screenshot taken in a fresh install of 6.17 (The page looks similar in Drupal 7, of course).
I manually checked all the places where drupal_access_denied() is called in core, and I have confirmed that this is the only affected page. I've attached a patch... it simply adds a drupal_exit() after the offending function call.
This issue is also reported in the drupal 6.x queue here:
#653404: Use of drupal_access_denied inside drupal_get_form is not correct
Comment #2
berdirYou can replace the call in this function with "return MENU_ACCESS_DENIED;", that should work too without having to call drupal_exit(). If this is the only place in core where it is used wrong, then I guess we don't need to add the drupal_exit().
Comment #3
criticalpatch commentedWhen I replace the call with "return MENU_ACCESS_DENIED", I get the error:
Unsupported operand types in /var/shared/sites/drupal7/site/includes/form.inc on line 855.
I think this is because the page callback is drupal_get_form(), which calls user_pass_reset() indirectly. Other places in core use drupal_access_denied() followed by drupal_exit() to avoid this problem, as per the comments in common.inc:710:
Comment #5
criticalpatch commentedWhoops, I made a small mistake generating the patch. Lets see if this does it.
Comment #7
criticalpatch commentedOkay, now it should really work...I was making my patch from the module directory instead of the root.
Comment #8
criticalpatch commentedQueued for testing.
Comment #9
moshe weitzman commenteder, if we are denying access we need to generate a 403 header and say so. this patch does neither, AFAICT
Comment #10
berdirThat is already done. All we do here is avoid to print it *twice*. The existing drupal_access_denied() call calls drupal_deliver_page(MENU_ACCESS_DENIED) and that calls http://api.drupal.org/api/function/drupal_deliver_html_page/7
Comment #11
moshe weitzman commentedi see. thx.
Comment #12
damien tournoud commentedThe fix should be ok for Drupal 6, but for D7, could we please fix that properly?
A form callback should not contain anything that has a side effect. The form part of this function (which is buried down below a pile of action logic) should be moved to a separate callback. The main callback should use
return MENU_ACCESS_DENIED, problem solved.Comment #13
criticalpatch commented@Damien Tournoud: That is a good point. I think I have done what you wanted, could you please verify?
Comment #14
criticalpatch commented*Shameless bump* Or anyone else for that matter. It should simple to follow.
Comment #15
nette_sk commented#1: add-drupal-exit-after-access-denied.patch queued for re-testing.
Comment #16
damien tournoud commentedI'm very sorry for the delay. This felt completely out of my radar.
The patch looks pretty close to me. Two small concerns:
There should be a new line after the function summary.
You can pass the fully loaded $user object from the menu callback instead of reloading it.
Comment #17
moshe weitzman commentedComment #18
halmsx commentedhi
i was creating a custom page using the same function and got the same double page display.
but..
Comment #19
berdirPlease don't change the version. This needs to be changed in 7.x first and it is not a bug in drupal_access_denied() that is the way that function works and why it's much better to use "return MENU_ACCESS_DENIED" in 7.x
Comment #20
damien tournoud commented@halmsx: Please do not change the version information.
This issue is to solve a bug in a specific form of Drupal core, that does not use the API properly.
If you want to return an Access denied from your menu callback, in Drupal 6, use either:
Or (preferably, because compatible with Drupal 7):
None of the code examples you provided are actually correct.
Comment #21
halmsx commentedapology. my bad. didnt noticed the version.
Comment #22
charlie-s commentedDamien, thanks for your note. I like how simple
return MENU_ACCESS_DENIED;works, but I don't understand why drupal_access_denied() function even exists if it doesn't handle the return itself. Can you explain?Comment #23
Johnny vd Laar commentedI am still experiencing this issue in drupal 7.16.
Comment #24
andeersg commentedI think this is not a problem anymore. This commit: http://cgit.drupalcode.org/drupal/commit/modules/user/user.pages.inc?h=7..., solves it by calling "drupal_exit() after access denied.
.