Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Traceback formatting in Python 3.6 32-bit Windows causes hang #1162

Closed
samuelchen opened this issue Feb 27, 2020 · 12 comments
Closed

Traceback formatting in Python 3.6 32-bit Windows causes hang #1162

samuelchen opened this issue Feb 27, 2020 · 12 comments
Labels
bug
Milestone

Comments

@samuelchen
Copy link

@samuelchen samuelchen commented Feb 27, 2020

Hi,

I was facing an issue when using incorrect variable name in Flask template. An dash "-" linked variable name in template cause Flask to hang without throwing any exception.

At first I doubt it's Jinja issue but I found Jinja raised the exception and Werkzeug handled it.

Eventually, I found an endless loop in Python\Lib\traceback.py to walk trackback stacks. The
trackbacks are stored in a link which nodes point to next. In flask\templating.py,
flask\app.py and werkzeug\debug\tbtools.py, the exception was catched. In
handle_exception() of flask\app.py, Werkzeug wants to log it and print it out.

The trackback link has looped reference as below picture.

Hope its helpful. Thanks you.

Expected Behavior

Render variable out or throw exception out.

import sys
from flask import Flask, request, render_template_string, make_response, url_for, redirect

### {{ font-size }} causes app hang ###

app = Flask(__name__)

template_page = '''
<html>
<head>
<meta charset="{{ encoding }}" />
<meta http-equiv="content-type" content="text/html; charset={{ encoding }}" />
<style type="text/css">
  body, pre, p, div, input, h1,h2,h3,h4,h5 {
    font-family : Consolas, Courier New;
  }
</style>
</head>
<body>
    <div id="wrapper" style="font-size:{{ font-size }}em">
        {{ content | safe }}
    </div>
</body>'''


@app.route('/', methods=['GET'])
def index():
    context = {
        "encoding": 'utf-8',
        "font-size": 0.9,
        "content": 'hello flask'
    }
    resp = make_response(render_template_string(template_page, **context))
    resp.headers['Content-Type'] = 'text/html; charset=utf-8'
    return resp


if __name__ == "__main__":
    # app.run(debug=True, host='0.0.0.0', port=8080)

    app.run()

Actual Behavior

App hangs.

N/A

Environment

  • Python version: 3.6.8
  • Flask version: 1.1.1
  • Werkzeug version: 0.16.1
@shivamguys

This comment was marked as off-topic.

Copy link

@shivamguys shivamguys commented Feb 28, 2020

The reason is render_template_string assumes style="font-size:{{ font-size }}em"
font size is your key and it throws an error
Screenshot from 2020-02-28 13-33-26

I would advice you to use string format function where ever in your html uses key:value syntax like css.

Use render_template_string only where key:value dosen't exist in syntax, as a normal parser

@mitsuhiko

This comment has been minimized.

Copy link
Member

@mitsuhiko mitsuhiko commented Feb 28, 2020

Which version of Jinja is that? The traceback must not have loops which to me would indicate that this is potentially a regression in Jinja.

@shivamguys

This comment was marked as off-topic.

Copy link

@shivamguys shivamguys commented Feb 28, 2020

Yes..
Jinja Version: 2.10.1
Werkzeug Version: 0.16.1

@davidism

This comment has been minimized.

Copy link
Member

@davidism davidism commented Feb 28, 2020

I'm having trouble reproducing this. I used your exact code and the mentioned versions, and got the expected traceback, not a reference loop or hang. Just in case, I also tested with the latest Werkzeug and Jinja versions and didn't see the issue either.

@davidism

This comment was marked as off-topic.

Copy link
Member

@davidism davidism commented Feb 28, 2020

As @shivamguys showed, they didn't get an infinite loop either, they got the expected traceback that identified 'font' is undefined.

@samuelchen

This comment has been minimized.

Copy link
Author

@samuelchen samuelchen commented Feb 28, 2020

Which version of Jinja is that? The traceback must not have loops which to me would indicate that this is potentially a regression in Jinja.

@mitsuhiko Jinja2 2.11.1

@samuelchen

This comment was marked as off-topic.

Copy link
Author

@samuelchen samuelchen commented Feb 28, 2020

The reason is render_template_string assumes style="font-size:{{ font-size }}em"
font size is your key and it throws an error
Screenshot from 2020-02-28 13-33-26

I would advice you to use string format function where ever in your html uses key:value syntax like css.

Use render_template_string only where key:value dosen't exist in syntax, as a normal parser

Yes.. you are right. I was just trying to write an one file tool to render DB. It was supposed to throw exceptions out.

@samuelchen

This comment has been minimized.

Copy link
Author

@samuelchen samuelchen commented Feb 28, 2020

As @shivamguys showed, they didn't get an infinite loop either, they got the expected traceback that identified 'font' is undefined.

@davidism
Win 10 64bit
Python 3.6.8 32bit
Jinja2 2.11.1

hope it's helpful.

@ThiefMaster ThiefMaster changed the title dash in template vairable name causes Flask hang. dash in template variable name causes Flask to hang Feb 28, 2020
@samuelchen

This comment has been minimized.

Copy link
Author

@samuelchen samuelchen commented Feb 28, 2020

I'm having trouble reproducing this. I used your exact code and the mentioned versions, and got the expected traceback, not a reference loop or hang. Just in case, I also tested with the latest Werkzeug and Jinja versions and didn't see the issue either.

I am not sure if my environment will impact it. But I tried running it directly in command line. It's the same.

@davidism davidism transferred this issue from pallets/flask Feb 28, 2020
@mitsuhiko

This comment has been minimized.

Copy link
Member

@mitsuhiko mitsuhiko commented Feb 28, 2020

@mitsuhiko Jinja2 2.11.1

Can you check if this also happens on 2.10?

@davidism

This comment has been minimized.

Copy link
Member

@davidism davidism commented Feb 29, 2020

I can reproduce this with 2.11 on Python 3.6.8 32-bit on Windows. Python 3.6.8 64-bit does not have the issue. 2.10.3 does not have the issue.

from jinja2 import Template
Template("{{ a-b }}").render()
@davidism davidism changed the title dash in template variable name causes Flask to hang Traceback formatting in Python 3.6 32-bit Windows causes hang Feb 29, 2020
@davidism davidism added the bug label Feb 29, 2020
@davidism davidism added this to the 2.11.2 milestone Feb 29, 2020
@davidism

This comment has been minimized.

Copy link
Member

@davidism davidism commented Feb 29, 2020

Looks like a bad assumption about the size of PyObject_HEAD, a holdover from the previous version that I kept instead of the suggested alternative. Changing from

ctypes.c_byte * (32 if hasattr(sys, "getobjects") else 16)

to

ctypes.c_byte * object().__sizeof__()

fixes the issue. On Python 3.6 32-bit, the size is actually 8, not 32 or 16, so the wrong slot was being written to when setting tb_next.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.