wbond / pybars3

Handlebars.js template support for Python 3 and 2
GNU Lesser General Public License v3.0
179 stars 46 forks source link

Infinite Recursion Inside `strlist.grow` #69

Open AlecRosenbaum opened 4 years ago

AlecRosenbaum commented 4 years ago

If you give strlist.grow a subclass of str, strlist.grow will infinitely recurse.

This has come up because of changes using futurize.builtins.str made in an effort to make sourcecode compatible with python 2 and python 3.

It looks like the very strict type checks here are to blame: https://github.com/wbond/pybars3/blob/7a8bd6d20f39ab536d761987939d611e267726e7/pybars/_compiler.py#L191-L197

In a pdb shell (running latest python 2.7) I get the following output:

(Pdb) ll
 204         def grow(self, thing):
 205             """Make the list longer, appending for unicode, extending otherwise."""
 206             if type(thing) == str_class:
 207                 self.append(thing)
 208
 209             # This will only ever match in Python 2 since str_class is str in
 210             # Python 3.
 211             elif type(thing) == str:
 212                 self.append(unicode(thing))  # noqa: F821 undefined name 'unicode'
 213
 214             else:
 215                 # Recursively expand to a flat list; may deserve a C accelerator at
 216                 # some point.
 217                 for element in thing:
 218  ->                 self.grow(element)
(Pdb) str
<type 'str'>
(Pdb) str_class
<type 'unicode'>
(Pdb) type(thing)
<class 'future.types.newstr.newstr'>
(Pdb) isinstance(thing, str)
False
(Pdb) isinstance(thing, str_class)
True

I suspect just changing the type(thing) == str_class lines to isinstance(type, str_class) will fix the issue.