From 19b2f71c3b9ff116a75b6684d9377d13f9558a22 Mon Sep 17 00:00:00 2001 From: justcool393 Date: Wed, 5 Oct 2022 01:04:32 -0700 Subject: [PATCH 1/8] improve raw title sanitization and don't check the same thing like 5 times --- files/helpers/sanitize.py | 7 +++++++ files/routes/posts.py | 33 +++++++++++++-------------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/files/helpers/sanitize.py b/files/helpers/sanitize.py index d6ec18c8a..42fa895e9 100644 --- a/files/helpers/sanitize.py +++ b/files/helpers/sanitize.py @@ -189,6 +189,13 @@ def with_sigalrm_timeout(timeout: int): return inner +def sanitize_raw_title(sanitized): + if not sanitized: return None + sanitized = sanitized.replace('\u200e','').replace('\u200b','').replace("\ufeff", "").replace("\r","").replace("\n", "") + sanitized = sanitized.strip() + return sanitized[:500] # should really be a constant + + @with_sigalrm_timeout(5) def sanitize(sanitized, golden=True, limit_pings=0, showmore=True, count_marseys=False, torture=False): sanitized = sanitized.strip() diff --git a/files/routes/posts.py b/files/routes/posts.py index 7a296d17b..6600f1f49 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -374,7 +374,7 @@ def morecomments(v, cid): def edit_post(pid, v): p = get_post(pid) - title = request.values.get("title", "").strip().replace('‎','') + title = sanitize_raw_title(request.values.get("title", "")) body = request.values.get("body", "").strip().replace('‎','') @@ -389,6 +389,8 @@ def edit_post(pid, v): elif v.bird and len(body) > 140: return {"error":"You have to type less than 140 characters!"}, 403 + if not title: + return {"error": "Please enter a better title."}, 400 if title != p.title: torture = (v.agendaposter and not v.marseyawarded and p.sub != 'chudrama' and v.id == p.author_id) @@ -397,7 +399,7 @@ def edit_post(pid, v): if v.id == p.author_id and v.marseyawarded and not marseyaward_title_regex.fullmatch(title_html): return {"error":"You can only type marseys!"}, 403 - p.title = title[:500] + p.title = title p.title_html = title_html body += process_files() @@ -661,7 +663,7 @@ def submit_post(v, sub=None): if '\\' in url: abort(400) - title = request.values.get("title", "").strip()[:500].replace('‎','') + title = sanitize_raw_title(request.values.get("title", "")) body = request.values.get("body", "").strip().replace('‎','') @@ -673,6 +675,13 @@ def submit_post(v, sub=None): SUBS = [x[0] for x in g.db.query(Sub.name).order_by(Sub.name).all()] return render_template("submit.html", SUBS=SUBS, v=v, error=error, title=title, url=url, body=body), 400 + if not title: + return error("Please enter a better title.") + torture = (v.agendaposter and not v.marseyawarded and sub != 'chudrama') + title_html = filter_emojis_only(title, graceful=True, count_marseys=True, torture=torture) + if v.marseyawarded and not marseyaward_title_regex.fullmatch(title_html): + return error("You can only type marseys!") + if len(title_html) > 1500: return error("Rendered title is too big!") sub = request.values.get("sub", "").lower().replace('/h/','').strip() @@ -696,15 +705,6 @@ def submit_post(v, sub=None): return error(f"You must choose a {HOLE_NAME} for your post!") if v.is_suspended: return error("You can't perform this action while banned.") - - torture = (v.agendaposter and not v.marseyawarded and sub != 'chudrama') - - title_html = filter_emojis_only(title, graceful=True, count_marseys=True, torture=torture) - - if v.marseyawarded and not marseyaward_title_regex.fullmatch(title_html): - return error("You can only type marseys!") - - if len(title_html) > 1500: return error("Rendered title is too big!") if v.longpost and (len(body) < 280 or ' [](' in body or body.startswith('[](')): return error("You have to type more than 280 characters!") @@ -787,13 +787,6 @@ def submit_post(v, sub=None): if not url and not request.values.get("body") and not request.files.get("file") and not request.files.get("file-url"): return error("Please enter a url or some text.") - if not title: - return error("Please enter a better title.") - - - elif len(title) > 500: - return error("There's a 500 character limit for titles.") - dup = g.db.query(Submission).filter( Submission.author_id == v.id, Submission.deleted_utc == 0, @@ -908,7 +901,7 @@ def submit_post(v, sub=None): body=body[:20000], body_html=body_html, embed_url=embed, - title=title[:500], + title=title, title_html=title_html, sub=sub, ghost=ghost From 88ae00deefdde10b624b32a8b5c82fbf2d53ad01 Mon Sep 17 00:00:00 2001 From: justcool393 Date: Wed, 5 Oct 2022 01:16:56 -0700 Subject: [PATCH 2/8] sanitize raw bodies --- files/helpers/sanitize.py | 8 +++++++- files/routes/posts.py | 9 +++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/files/helpers/sanitize.py b/files/helpers/sanitize.py index 42fa895e9..79a8d531e 100644 --- a/files/helpers/sanitize.py +++ b/files/helpers/sanitize.py @@ -190,11 +190,17 @@ def with_sigalrm_timeout(timeout: int): def sanitize_raw_title(sanitized): - if not sanitized: return None + if not sanitized: return "" sanitized = sanitized.replace('\u200e','').replace('\u200b','').replace("\ufeff", "").replace("\r","").replace("\n", "") sanitized = sanitized.strip() return sanitized[:500] # should really be a constant +def sanitize_raw_body(sanitized): + if not sanitized: return "" + sanitized = sanitized.replace('\u200e','').replace('\u200b','').replace("\ufeff", "").replace("\r\n", "\n") + sanitized = sanitized.strip() + return sanitized[:20000] # this also should really be a constant + @with_sigalrm_timeout(5) def sanitize(sanitized, golden=True, limit_pings=0, showmore=True, count_marseys=False, torture=False): diff --git a/files/routes/posts.py b/files/routes/posts.py index 6600f1f49..680c87aa2 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -665,9 +665,7 @@ def submit_post(v, sub=None): title = sanitize_raw_title(request.values.get("title", "")) - body = request.values.get("body", "").strip().replace('‎','') - - body = body.replace('\r\n', '\n')[:20000] + body = sanitize_raw_body(request.values.get("body", "")) def error(error): if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": error}, 403 @@ -784,7 +782,7 @@ def submit_post(v, sub=None): embed = str(int(id)) - if not url and not request.values.get("body") and not request.files.get("file") and not request.files.get("file-url"): + if not url and not body and not request.files.get("file") and not request.files.get("file-url"): return error("Please enter a url or some text.") dup = g.db.query(Submission).filter( @@ -861,7 +859,6 @@ def submit_post(v, sub=None): body = body.replace(i.group(0), "") body += process_files() - body = body.strip() torture = (v.agendaposter and not v.marseyawarded and sub != 'chudrama') @@ -898,7 +895,7 @@ def submit_post(v, sub=None): app_id=v.client.application.id if v.client else None, is_bot = is_bot, url=url, - body=body[:20000], + body=body, body_html=body_html, embed_url=embed, title=title, From 2a53df20ffed44aa9eccc025d135870d300ec830 Mon Sep 17 00:00:00 2001 From: justcool393 Date: Wed, 5 Oct 2022 01:19:45 -0700 Subject: [PATCH 3/8] consistency in return error and returned status code --- files/routes/posts.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/files/routes/posts.py b/files/routes/posts.py index 680c87aa2..df1583043 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -668,7 +668,7 @@ def submit_post(v, sub=None): body = sanitize_raw_body(request.values.get("body", "")) def error(error): - if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": error}, 403 + if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": error}, 400 SUBS = [x[0] for x in g.db.query(Sub.name).order_by(Sub.name).all()] return render_template("submit.html", SUBS=SUBS, v=v, error=error, title=title, url=url, body=body), 400 @@ -679,7 +679,8 @@ def submit_post(v, sub=None): title_html = filter_emojis_only(title, graceful=True, count_marseys=True, torture=torture) if v.marseyawarded and not marseyaward_title_regex.fullmatch(title_html): return error("You can only type marseys!") - if len(title_html) > 1500: return error("Rendered title is too big!") + if len(title_html) > 1500: + return error("Rendered title is too big!") sub = request.values.get("sub", "").lower().replace('/h/','').strip() From 093ced7b20d50dfb3d744a23a744c80bdb19d606 Mon Sep 17 00:00:00 2001 From: justcool393 Date: Wed, 5 Oct 2022 01:35:35 -0700 Subject: [PATCH 4/8] introduce constant for post and title length --- files/helpers/const.py | 5 +++++ files/helpers/sanitize.py | 10 +++++----- files/routes/posts.py | 4 ++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/files/helpers/const.py b/files/helpers/const.py index 045adcbeb..8954d6632 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -155,6 +155,11 @@ EMOJI_SRCS = ['files/assets/emojis.json'] PIN_LIMIT = 3 POST_RATE_LIMIT = '1/second;2/minute;10/hour;50/day' +POST_TITLE_LENGTH_LIMIT = 500 # do not make larger than 500 without altering the table +POST_TITLE_HTML_LENGTH_LIMIT = 1500 # do not make larger than 1500 without altering the table +POST_BODY_LENGTH_LIMIT = 20000 # do not make larger than 20000 without altering the table +POST_BODY_HTML_LENGTH_LIMIT = 40000 # do not make larger than 40000 without altering the table + LOGGEDIN_ACTIVE_TIME = 15 * 60 PFP_DEFAULT_MARSEY = True NOTIFICATION_SPAM_AGE_THRESHOLD = 0.5 * 86400 diff --git a/files/helpers/sanitize.py b/files/helpers/sanitize.py index 79a8d531e..89cf58a5a 100644 --- a/files/helpers/sanitize.py +++ b/files/helpers/sanitize.py @@ -193,13 +193,13 @@ def sanitize_raw_title(sanitized): if not sanitized: return "" sanitized = sanitized.replace('\u200e','').replace('\u200b','').replace("\ufeff", "").replace("\r","").replace("\n", "") sanitized = sanitized.strip() - return sanitized[:500] # should really be a constant + return sanitized[:POST_TITLE_LENGTH_LIMIT] def sanitize_raw_body(sanitized): if not sanitized: return "" sanitized = sanitized.replace('\u200e','').replace('\u200b','').replace("\ufeff", "").replace("\r\n", "\n") sanitized = sanitized.strip() - return sanitized[:20000] # this also should really be a constant + return sanitized[:POST_BODY_LENGTH_LIMIT] @with_sigalrm_timeout(5) @@ -432,10 +432,10 @@ def filter_emojis_only(title, golden=True, count_marseys=False, graceful=False, title = strikethrough_regex.sub(r'\1\2', title) - title = bleach.clean(title, tags=['img','del','span'], attributes=allowed_attributes_emojis, protocols=['http','https']) + title = bleach.clean(title, tags=['img','del','span'], attributes=allowed_attributes_emojis, protocols=['http','https']).replace('\n','').strip() - if len(title) > 1500 and not graceful: abort(400) - else: return title.replace('\n','').strip() + if len(title) > POST_TITLE_HTML_LENGTH_LIMIT and not graceful: abort(400) + else: return title def normalize_url(url): url = reddit_domain_regex.sub(r'\1https://old.reddit.com/\3/', url) diff --git a/files/routes/posts.py b/files/routes/posts.py index df1583043..40910bf07 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -442,7 +442,7 @@ def edit_post(pid, v): g.db.add(v) send_repeatable_notification(CARP_ID, p.permalink) - if len(body_html) > 40000: return {"error":"Submission body_html too long! (max 40k characters)"}, 400 + if len(body_html) > POST_BODY_HTML_LENGTH_LIMIT: return {"error":"Submission body_html too long! (max 40k characters)"}, 400 p.body_html = body_html @@ -679,7 +679,7 @@ def submit_post(v, sub=None): title_html = filter_emojis_only(title, graceful=True, count_marseys=True, torture=torture) if v.marseyawarded and not marseyaward_title_regex.fullmatch(title_html): return error("You can only type marseys!") - if len(title_html) > 1500: + if len(title_html) > POST_TITLE_HTML_LENGTH_LIMIT: return error("Rendered title is too big!") sub = request.values.get("sub", "").lower().replace('/h/','').strip() From d58351637cbf2ba75f08752053f13dcacc43473b Mon Sep 17 00:00:00 2001 From: justcool393 Date: Wed, 5 Oct 2022 02:14:12 -0700 Subject: [PATCH 5/8] use constants --- files/helpers/actions.py | 4 ++-- files/routes/posts.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/files/helpers/actions.py b/files/helpers/actions.py index b7b9f16ec..3fc6d3964 100644 --- a/files/helpers/actions.py +++ b/files/helpers/actions.py @@ -139,13 +139,13 @@ def execute_snappy(post, v): body += addition archive_url(href) - body = body.strip() + body = body.strip()[:POST_BODY_LENGTH_LIMIT] body_html = sanitize(body) if len(body_html) == 0: return - if len(body_html) < 40000: + if len(body_html) < POST_BODY_HTML_LENGTH_LIMIT: c = Comment(author_id=SNAPPY_ID, distinguish_level=6, parent_submission=post.id, diff --git a/files/routes/posts.py b/files/routes/posts.py index 40910bf07..25d8faae4 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -860,7 +860,7 @@ def submit_post(v, sub=None): body = body.replace(i.group(0), "") body += process_files() - body = body.strip() + body = body.strip()[:POST_BODY_LENGTH_LIMIT] # process_files() adds content to the body, so we need to re-strip torture = (v.agendaposter and not v.marseyawarded and sub != 'chudrama') @@ -869,7 +869,7 @@ def submit_post(v, sub=None): if v.marseyawarded and marseyaward_body_regex.search(body_html): return error("You can only type marseys!") - if len(body_html) > 40000: return error("Submission body_html too long! (max 40k characters)") + if len(body_html) > POST_BODY_HTML_LENGTH_LIMIT: return error(f"Submission body_html too long! (max {POST_BODY_HTML_LENGTH_LIMIT} characters)") club = False if FEATURES['COUNTRY_CLUB']: From 2a66104d8b80f1db7dad07a733a9ffe9320a9238 Mon Sep 17 00:00:00 2001 From: justcool393 Date: Wed, 5 Oct 2022 02:54:44 -0700 Subject: [PATCH 6/8] improve body for edit_post --- files/routes/posts.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/files/routes/posts.py b/files/routes/posts.py index 25d8faae4..654cb8dcc 100644 --- a/files/routes/posts.py +++ b/files/routes/posts.py @@ -376,9 +376,7 @@ def edit_post(pid, v): title = sanitize_raw_title(request.values.get("title", "")) - body = request.values.get("body", "").strip().replace('‎','') - - body = body.replace('\r\n', '\n')[:20000] + body = sanitize_raw_body(request.values.get("body", "")) if v.id != p.author_id and v.admin_level < 2: abort(403) @@ -403,8 +401,7 @@ def edit_post(pid, v): p.title_html = title_html body += process_files() - - body = body.strip() + body = body.strip()[:POST_BODY_LENGTH_LIMIT] # process_files() may be adding stuff to the body if body != p.body: for i in poll_regex.finditer(body): @@ -442,7 +439,7 @@ def edit_post(pid, v): g.db.add(v) send_repeatable_notification(CARP_ID, p.permalink) - if len(body_html) > POST_BODY_HTML_LENGTH_LIMIT: return {"error":"Submission body_html too long! (max 40k characters)"}, 400 + if len(body_html) > POST_BODY_HTML_LENGTH_LIMIT: return {"error":f"Submission body_html too long! (max {POST_BODY_HTML_LENGTH_LIMIT} characters)"}, 400 p.body_html = body_html From 651355afdf8795e8c28a6eed738307fce2f60a01 Mon Sep 17 00:00:00 2001 From: justcool393 Date: Wed, 5 Oct 2022 16:37:16 -0700 Subject: [PATCH 7/8] should be no semicolon there --- files/classes/submission.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/classes/submission.py b/files/classes/submission.py index 45370198f..046aa1681 100644 --- a/files/classes/submission.py +++ b/files/classes/submission.py @@ -335,7 +335,7 @@ class Submission(Base): def realbody(self, v, listing=False): if self.club and not (v and (v.paid_dues or v.id == self.author_id)): return f"

{CC} ONLY

" if self.deleted_utc != 0 and not (v and (v.admin_level >= 2) or v.id == self.author.id): return "[Deleted by user]" - if self.is_banned and not (v and v.admin_level >= 2): return "[Removed by admins]"; + if self.is_banned and not (v and v.admin_level >= 2): return "[Removed by admins]" body = self.body_html or "" From cf8f0614ad2ddc6b7b737cdbc7780b5cf090a3a7 Mon Sep 17 00:00:00 2001 From: Aevann1 Date: Thu, 6 Oct 2022 01:00:03 +0000 Subject: [PATCH 8/8] sneed --- snappy_rDrama.txt | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/snappy_rDrama.txt b/snappy_rDrama.txt index 7fd16ccef..f3957dbb0 100644 --- a/snappy_rDrama.txt +++ b/snappy_rDrama.txt @@ -3094,4 +3094,20 @@ Get. a GODSDAMNED. Grip. {[para]} aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa
aaaaaaaaaaaaaa {[para]} -![](/images/16649046614498348.webp) \ No newline at end of file +![](/images/16649046614498348.webp) +{[para]} +![](/images/16630965071440427.webp) +{[para]} +``` +⠀⠀⠀⠀⠀⢰⡿⠋⠁⠀⠀⠈⠉⠙⠻⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⢀⣿⠇⠀⢀⣴⣶⡾⠿⠿⠿⢿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⣀⣀⣸⡿⠀⠀⢸⣿⣇⠀⠀⠀⠀⠀⠀⠙⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⣾⡟⠛⣿⡇⠀⠀⢸⣿⣿⣷⣤⣤⣤⣤⣶⣶⣿⠇⠀⠀⠀⠀⠀⠀⠀⣀⠀⠀ +⢀⣿⠀⢀⣿⡇⠀⠀⠀⠻⢿⣿⣿⣿⣿⣿⠿⣿⡏⠀⠀⠀⠀⢴⣶⣶⣿⣿⣿⣆ +⢸⣿⠀⢸⣿⡇⠀⠀⠀⠀⠀⠈⠉⠁⠀⠀⠀⣿⡇⣀⣠⣴⣾⣮⣝⠿⠿⠿⣻⡟ +⢸⣿⠀⠘⣿⡇⠀⠀⠀⠀⠀⠀⠀⣠⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⠉⠀ +⠸⣿⠀⠀⣿⡇⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠉⠀⠀⠀⠀ +⠀⠻⣷⣶⣿⣇⠀⠀⠀⢠⣼⣿⣿⣿⣿⣿⣿⣿⣛⣛⣻⠉⠁⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⢸⣿⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⢸⣿⣀⣀⣀⣼⡿⢿⣿⣿⣿⣿⣿⡿⣿⣿⡿ +``` \ No newline at end of file