diff --git a/files/classes/comment.py b/files/classes/comment.py index 93cc46c12..187aa717b 100644 --- a/files/classes/comment.py +++ b/files/classes/comment.py @@ -81,7 +81,7 @@ class Comment(Base): author = relationship("User", primaryjoin="User.id==Comment.author_id") senttouser = relationship("User", primaryjoin="User.id==Comment.sentto") parent_comment = relationship("Comment", remote_side=[id], back_populates="child_comments") - child_comments = relationship("Comment", lazy="dynamic", remote_side=[parent_comment_id], back_populates="parent_comment") + child_comments = relationship("Comment", remote_side=[parent_comment_id], back_populates="parent_comment") awards = relationship("AwardRelationship", order_by="AwardRelationship.awarded_utc.desc()", back_populates="comment") flags = relationship("CommentFlag", order_by="CommentFlag.created_utc") options = relationship("CommentOption", order_by="CommentOption.id") @@ -207,19 +207,24 @@ class Comment(Base): @lazy def replies(self, sort=None): - if self.replies2 != None: return [x for x in self.replies2 if not x.author.shadowbanned] - if not self.parent_submission: - return [x for x in self.child_comments.order_by(Comment.id) if not x.author.shadowbanned] - - comments = self.child_comments - return [x for x in comments if not x.author.shadowbanned] + if self.replies2 != None: + return [x for x in self.replies2 if not x.author.shadowbanned] + if not self.parent_submission: + return g.db.query(Comment).options( + joinedload(Comment.author) + ).filter_by(parent_comment_id=self.id, shadowbanned=None).order_by(Comment.id).all() + + return [x for x in self.child_comments if not x.author.shadowbanned] + @lazy def replies3(self, sort): - if self.replies2 != None: return self.replies2 + if self.replies2 != None: + return self.replies2 + if not self.parent_submission: - return self.child_comments.order_by(Comment.id).all() + return g.db.query(Comment).filter_by(parent_comment_id=self.id).order_by(Comment.id).all() return self.child_comments diff --git a/files/helpers/const.py b/files/helpers/const.py index 6c4153614..25ccd886f 100644 --- a/files/helpers/const.py +++ b/files/helpers/const.py @@ -916,8 +916,11 @@ approved_embed_hosts = { } +def is_site_url(url): + return '\\' not in url and (url.startswith('/') or url.startswith(f'{SITE_FULL}/')) + def is_safe_url(url): - return '\\' not in url and (url.startswith('/') or tldextract.extract(url).registered_domain in approved_embed_hosts) + return is_site_url(url) or tldextract.extract(url).registered_domain in approved_embed_hosts hosts = "|".join(approved_embed_hosts).replace('.','\.') diff --git a/files/helpers/sanitize.py b/files/helpers/sanitize.py index 4d6e98711..a93647e1d 100644 --- a/files/helpers/sanitize.py +++ b/files/helpers/sanitize.py @@ -67,7 +67,7 @@ def allowed_attributes(tag, name, value): if name == 'data-bs-toggle' and value == 'tooltip': return True if name in ['g','b','glow'] and not value: return True if name in ['alt','title']: return True - if name == 'referrpolicy' and value == 'no-referrer': return True + if name == 'referrerpolicy' and value == 'no-referrer': return True return False if tag == 'lite-youtube': @@ -213,10 +213,14 @@ def sanitize(sanitized, edit=False): tag["data-src"] = tag["src"] tag["src"] = "/i/l.webp" tag['alt'] = f'![]({tag["data-src"]})' - tag['referrerpolicy'] = "no-referrer" + + if not is_site_url(tag["data-src"]): + tag['referrerpolicy'] = "no-referrer" if tag.parent.name != 'a': - a = soup.new_tag("a", href=tag["data-src"], rel="nofollow noopener noreferrer") + a = soup.new_tag("a", href=tag["data-src"]) + if not is_site_url(a["href"]): + a["rel"] = "nofollow noopener noreferrer" tag = tag.replace_with(a) a.append(tag) diff --git a/files/routes/errors.py b/files/routes/errors.py index 23b2ad7b5..1357de3c6 100644 --- a/files/routes/errors.py +++ b/files/routes/errors.py @@ -80,7 +80,5 @@ def error_500(e): def allow_nsfw(): session["over_18"] = int(time.time()) + 3600 redir = request.values.get("redir") - if redir: - if redir.startswith(f'{SITE_FULL}/'): return redirect(redir) - if redir.startswith('/') and '\\' not in redir: return redirect(f'{SITE_FULL}{redir}') + if redir and is_site_url(redir): return redirect(redir) return redirect('/') \ No newline at end of file diff --git a/files/routes/front.py b/files/routes/front.py index 75792f8c6..8ed7e7d92 100644 --- a/files/routes/front.py +++ b/files/routes/front.py @@ -141,7 +141,7 @@ def notifications(v): if c.parent_submission: if c.replies2 == None: - c.replies2 = c.child_comments.filter(or_(Comment.author_id == v.id, Comment.id.in_(cids))).all() + c.replies2 = g.db.query(Comment).filter_by(parent_comment_id=c.id).filter(or_(Comment.author_id == v.id, Comment.id.in_(cids))).all() for x in c.replies2: if x.replies2 == None: x.replies2 = [] count = 0 @@ -149,10 +149,10 @@ def notifications(v): count += 1 c = c.parent_comment if c.replies2 == None: - c.replies2 = c.child_comments.filter(or_(Comment.author_id == v.id, Comment.id.in_(cids))).all() + c.replies2 = g.db.query(Comment).filter_by(parent_comment_id=c.id).filter(or_(Comment.author_id == v.id, Comment.id.in_(cids))).all() for x in c.replies2: if x.replies2 == None: - x.replies2 = x.child_comments.filter(or_(Comment.author_id == v.id, Comment.id.in_(cids))).all() + x.replies2 = g.db.query(Comment).filter_by(parent_comment_id=x.id).filter(or_(Comment.author_id == v.id, Comment.id.in_(cids))).all() else: while c.parent_comment: c = c.parent_comment diff --git a/files/routes/login.py b/files/routes/login.py index 24482a283..531d6c349 100644 --- a/files/routes/login.py +++ b/files/routes/login.py @@ -14,11 +14,8 @@ def login_get(v): redir = request.values.get("redirect") if redir: redir = redir.replace("/logged_out", "").strip() - if not redir.startswith(f'{SITE_FULL}/') and not (redir.startswith('/') and '\\' not in redir): redir = None - - if v and redir: - if redir.startswith(f'{SITE_FULL}/'): return redirect(redir) - elif redir.startswith('/') and '\\' not in redir: return redirect(f'{SITE_FULL}{redir}') + if not is_site_url(redir): redir = None + if v: return redirect(redir) return render_template("login.html", failed=False, redirect=redir) @@ -152,11 +149,7 @@ def login_post(): redir = request.values.get("redirect") if redir: redir = redir.replace("/logged_out", "").strip() - if not redir.startswith(f'{SITE_FULL}/') and not (redir.startswith('/') and '\\' not in redir): redir = '/' - - if redir: - if redir.startswith(f'{SITE_FULL}/'): return redirect(redir) - if redir.startswith('/') and '\\' not in redir: return redirect(f'{SITE_FULL}{redir}') + if is_site_url(redir): return redirect(redir) return redirect('/') @app.get("/me")