Changed enrich filter

This commit is contained in:
Yusur 2019-10-14 14:30:22 +02:00
parent a646c96b86
commit 5e7c6097d4
3 changed files with 39 additions and 3 deletions

View file

@ -4,6 +4,7 @@
* Removed `type` and `info` fields from `Message` table and merged `privacy` field, previously into a separate table, into that table. In order to make the app work, when upgrading you should run the `migrate_0_4_to_0_5.py` script. * Removed `type` and `info` fields from `Message` table and merged `privacy` field, previously into a separate table, into that table. In order to make the app work, when upgrading you should run the `migrate_0_4_to_0_5.py` script.
* Added flask-login dependency. Now, user logins can be persistent up to 365 days. * Added flask-login dependency. Now, user logins can be persistent up to 365 days.
* Rewritten `enrich` filter, correcting a serious security flaw. The new filter uses a tokenizer and escapes all non-markup text. Plus, now the `+` of the mention is visible, but weakened; newlines are now visible in the message.
## 0.4.0 ## 0.4.0

40
app.py
View file

@ -3,7 +3,7 @@ from flask import (
send_from_directory, session, url_for) send_from_directory, session, url_for)
import hashlib import hashlib
from peewee import * from peewee import *
import datetime, time, re, os, sys, string, json import datetime, time, re, os, sys, string, json, html
from functools import wraps from functools import wraps
import argparse import argparse
from flask_login import LoginManager, login_user, logout_user, login_required from flask_login import LoginManager, login_user, logout_user, login_required
@ -566,10 +566,44 @@ def username_availability(username):
is_available = False is_available = False
return jsonify({'is_valid':is_valid, 'is_available':is_available, 'status':'ok'}) return jsonify({'is_valid':is_valid, 'is_available':is_available, 'status':'ok'})
_enrich_symbols = [
(r'\n', 'NEWLINE'),
(r'https?://(?:[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*|\[[A-Fa-f0-9:]+\])'
r'(?::\d+)?(?:/.*)?(?:\?.*)?(?:#.*)?', 'URL'),
(_mention_re, 'MENTION'),
(r'[^\n+]+', 'TEXT'),
(r'.', 'TEXT')
]
def _tokenize(characters, table):
pos = 0
tokens = []
while pos < len(characters):
mo = None
for pattern, tag in table:
mo = re.compile(pattern).match(characters, pos)
if mo:
if tag:
text = mo.group(0)
tokens.append((text, tag))
break
pos = mo.end(0)
return tokens
@app.template_filter() @app.template_filter()
def enrich(s): def enrich(s):
'''Filter for mentioning users.''' tokens = _tokenize(s, _enrich_symbols)
return Markup(re.sub(_mention_re, r'<a href="/+\1">\1</a>', s)) r = []
for text, tag in tokens:
if tag == 'TEXT':
r.append(html.escape(text))
elif tag == 'URL':
r.append('<a href="{0}">{0}</a>'.format(html.escape(text)))
elif tag == 'MENTION':
r.append('<span class="weak">+</span><a href="/{0}">{1}</a>'.format(text, text.lstrip('+')))
elif tag == 'NEWLINE':
r.append('<br>')
return Markup(''.join(r))
@app.template_filter('is_following') @app.template_filter('is_following')
def is_following(from_user, to_user): def is_following(from_user, to_user):

View file

@ -8,6 +8,7 @@ body{margin:0}
.metanav{float:right} .metanav{float:right}
.header h1{margin:0;display:inline-block} .header h1{margin:0;display:inline-block}
.flash{background-color:#ff9;border:yellow 1px solid} .flash{background-color:#ff9;border:yellow 1px solid}
.weak{opacity:.5}
.message-visual img{max-width:100%;max-height:8em} .message-visual img{max-width:100%;max-height:8em}
.create_text{width:100%;height:8em} .create_text{width:100%;height:8em}
.follow_button,input[type="submit"]{background-color:#ff3018;color:white;border-radius:3px;border:1px solid #ff3018} .follow_button,input[type="submit"]{background-color:#ff3018;color:white;border-radius:3px;border:1px solid #ff3018}