Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#18979 closed Bug (fixed)

PermWrapper + template "if in" interaction

Reported by: akaariai Owned by: akaariai
Component: Template system Version: 1.4
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


Trying to do

{% if 'someperm' in perms.someapp %}has perm{% else %}no perm{% endif %}

will result in endless loop. Above, the perms is PermWrapper as installed by the RequestContext.

Doing if perms.someapp.someperm  works correctly. I tried the above because I have a permission codename (from external database) which contains '-', so I can't use the documented syntax.

The attached tester project shows this error. run devserver, click the link, and you will have the dev-server in endless loop which isn't even killable by Ctrl-c... So, be prepared to kill the server by force.

I know the above isn't documented use of PermWrapper. But, to me it seems this bug isn't a PermWrapper bug, what it does looks sane to me. So, I am suspecting there could be some underlying bug in the template engine. So, I am marking this into Template system, though the bug could be elsewhere, too.

Tested with 1.4.1 and 1.5.dev20120918050907 with Python 2.7.3.

Attachments (1)

test_project.tar.gz (8.3 KB) - added by akaariai 3 years ago.

Download all attachments as: .zip

Change History (6)

Changed 3 years ago by akaariai

comment:1 Changed 3 years ago by akaariai

I am completely lost with this ticket... I replaced the contents of the some_view (testing/ with this:

def some_view(request):
    testing_perms = context_instance['perms']['testing']
    'foo' in testing_perms
    ret =  render_to_response('a_template.html', {'foo': 'bar'},
    return ret

Then, I placed a print(__getitem__(%s) % perm_name) into django/contrib/auth/ . Access the view and it prints this endlessly:


The stack trace is this:

^Cakaariai@akaariai-UX31E:~/Programming/tester$ python runserver
Validating models...

0 errors found
September 18, 2012 - 13:46:04
Django version 1.5.dev20120917231511, using settings 'tester.settings'
Development server is running at
Quit the server with CONTROL-C.
> /home/akaariai/Programming/tester/django/contrib/auth/
-> return self.user.has_perm("%s.%s" % (self.module_name, perm_name))
(Pdb) perm_name
(Pdb) bt
-> self.__bootstrap_inner()
-> self.__target(*self.__args, **self.__kwargs)
-> self.finish_request(request, client_address)
-> self.RequestHandlerClass(request, client_address, self)
-> super(WSGIRequestHandler, self).__init__(*args, **kwargs)
-> self.handle()
-> self.result = application(self.environ, self.start_response)
-> return self.application(environ, start_response)
-> response = self.get_response(request)
-> response = callback(request, *callback_args, **callback_kwargs)
-> 'foo' in testing_perms
> /home/akaariai/Programming/tester/django/contrib/auth/
-> return self.user.has_perm("%s.%s" % (self.module_name, perm_name))

Tested both on Python 3.2 and Python 2.7, and at least 1.4.0 has this already.

comment:2 Changed 3 years ago by akaariai

  • Owner changed from nobody to akaariai
  • Triage Stage changed from Unreviewed to Accepted

An irc-discussion with Alex, and the reason for this is now clear. The reason is that if there isn't __iter__ defined for an object, but it has a __getitem__ which never raises IndexError, then the 'something' in obj will continuously check for obj[i] == 'something'; i++...

The solution is to define an __iter__ which raises TypeError.

I am assigning this to myself. The only question is how to test this... A possible test would be to check False not in perms - the reason is that __getitem__ will return False for the first index, 0, and then the in check will see False in the perms incorrectly. And, there should be no possibility of forever-loop.

I am going to backpatch this to 1.4, too.

comment:3 Changed 3 years ago by akaariai

  • Triage Stage changed from Accepted to Ready for checkin

comment:4 Changed 3 years ago by Anssi Kääriäinen <akaariai@…>

  • Resolution set to fixed
  • Status changed from new to closed

In 50d573d2c0b3e17cbf1aa240b03b52e4ad0c32cd:

Fixed #18979 -- Avoid endless loop caused by "val in PermLookupDict"

Fixed by defining iter which raises TypeError. This was done to
PermWrapper earlier.

comment:5 Changed 3 years ago by Anssi Kääriäinen <akaariai@…>

In 1f537335d9ff659cb0996d6523ad8ab7b3c49f4e:

[1.4.x] Fixed #18979 -- Avoid endless loop caused by "val in PermLookupDict"

Fixed by defining iter which raises TypeError. This was done to
PermWrapper earlier.

Backport of 50d573d2c0b3e17cbf1aa240b03b52e4ad0c32cd

Note: See TracTickets for help on using tickets.
Back to Top