7

このジンジャnl2brフィルターを実装しようとしています。<br>追加する がエスケープされていることを除いて、正しく機能しています。<p>がエスケープされておらず、すべて同じ文字列にあるため、これは奇妙です。

Jinjaautoescapeが有効になっているので、フラスコを使用しています。この男が とが二重エスケープを引き起こしている可能性があるautoescapeと言っているのを見つけたとき、私は本当に期待していましたが、 を削除しても解決しませんでした。escape(value)escape()

ここに私の変更されたコードとその出力があります:

@app.template_filter()
@evalcontextfilter
def nl2br(eval_ctx, value):
    _paragraph_re = re.compile(r'(?:\r\n|\r(?!\n)|\n){2,}')
    result = u'\n\n'.join(u'<p>%s</p>' % escape(p.replace(u'\r\n', u'<br>\n')) for p in _paragraph_re.split(value))
    if eval_ctx.autoescape:
        result = Markup(result)
    return result

入力:

u'1\r\n2\r\n\r\n3\r\n4\r\n\r\n5\r\n6\r\n7'

出力:

<p>1&lt;br&gt;
2</p>

<p>3&lt;br&gt;
4</p>

<p>5&lt;br&gt;
6&lt;br&gt;
7</p>

望ましい出力:

<p>1<br>2</p>

<p>3<br>4</p>

<p>5<br>6<br>7</p>

<br>'s がエスケープされているのに 's が許可されている原因は何<p>ですか?

4

3 に答える 3

5

これを書いている時点での他の2つの回答は<br/>タグをエスケープしませんが、XSSに対して脆弱です。次の入力文字列でテストします。

';alert(String.fromCharCode(88,83,83))//';alert(String.fromCharCode(88,83,83))//";
alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83))//--
></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>

Dan Jacob によるオリジナルのnl2br jinja スニペットはほぼ完成しています。

import re

from jinja2 import evalcontextfilter, Markup, escape

_paragraph_re = re.compile(r'(?:\r\n|\r|\n){2,}')

app = Flask(__name__)

@app.template_filter()
@evalcontextfilter
def nl2br(eval_ctx, value):
    result = u'\n\n'.join(u'<p>%s</p>' % p.replace('\n', '<br>\n') \
        for p in _paragraph_re.split(escape(value)))
    if eval_ctx.autoescape:
        result = Markup(result)
    return result

value上記のコードは、単なる文字列である限り、既に機能しています。valueすでにMarkupオブジェクトである場合にのみ失敗します。その場合、.replace()呼び出しによって'<br>'文字列がエスケープされるためです。これは、Jinja2 が一般的にエスケープを処理する方法に従います。Markupオブジェクトは安全であると推定され、通常の文字列オブジェクトは安全でないと推定されるため、この 2 つを組み合わせる操作は、通常の文字列オブジェクトのエスケープを自動的に呼び出します。

Markup('<br/>\n')これを修正するには、オブジェクトを作成するという @joemaller の回答と組み合わせてください。すなわち:

result = u'\n\n'.join(u'<p>%s</p>' % p.replace('\n', Markup('<br/>\n')) \
    for p in _paragraph_re.split(escape(value)))
于 2014-01-16T06:33:19.587 に答える
4

エスケープを外して試してみましたか?以下が私のために働くので?

@app.template_filter()
@evalcontextfilter
def nl2br(eval_ctx, value):
   _paragraph_re = re.compile(r'(?:\r\n|\r(?!\n)|\n){2,}')
   result = u'\n\n'.join(u'<p>%s</p>' % p.replace(u'\r\n', u'<br/>') for p in _paragraph_re.split(value))
   if eval_ctx.autoescape:
       result = Markup(result)
   return result

以下のようなテンプレートで使用する場合:

{{ '1\r\n2\r\n\r\n3\r\n4\r\n\r\n5\r\n6\r\n7' | nl2br}}

以下の出力が得られます

<p>1<br/>2</p>

<p>3<br/>4</p>

<p>5<br/>6<br/>7</p>
于 2012-09-21T10:19:08.170 に答える