mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-10-01 01:36:12 -04:00
reduce max comment depth to 50
This commit is contained in:
parent
5a4d348bcb
commit
c2d813f3ec
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -17,8 +17,7 @@ checksum = "8f27d075294830fcab6f66e320dab524bc6d048f4a151698e153205559113772"
|
||||
[[package]]
|
||||
name = "activitypub_federation"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b86eea7a032da501fe07b04a83c10716ea732c45e6943d7f045bc053aca03f2a"
|
||||
source = "git+https://github.com/LemmyNet/activitypub-federation-rust.git?branch=nested-comments-stack-overflow#4b94af9ea0580226aaa10a4abb004d0b8ca10eae"
|
||||
dependencies = [
|
||||
"activitystreams-kinds",
|
||||
"actix-web",
|
||||
|
@ -100,7 +100,7 @@ lemmy_db_views = { version = "=0.19.6-beta.7", path = "./crates/db_views" }
|
||||
lemmy_db_views_actor = { version = "=0.19.6-beta.7", path = "./crates/db_views_actor" }
|
||||
lemmy_db_views_moderator = { version = "=0.19.6-beta.7", path = "./crates/db_views_moderator" }
|
||||
lemmy_federate = { version = "=0.19.6-beta.7", path = "./crates/federate" }
|
||||
activitypub_federation = { version = "0.5.8", default-features = false, features = [
|
||||
activitypub_federation = { git = "https://github.com/LemmyNet/activitypub-federation-rust.git", branch = "nested-comments-stack-overflow", default-features = false, features = [
|
||||
"actix-web",
|
||||
] }
|
||||
diesel = "2.1.6"
|
||||
|
@ -860,9 +860,7 @@ test("Dont send a comment reply to a blocked community", async () => {
|
||||
});
|
||||
|
||||
/// Fetching a deeply nested comment can lead to stack overflow as all parent comments are also
|
||||
/// fetched recursively. Ensure that it works properly. Stack size depends on the OS so this
|
||||
/// may fail in some cases. In release builds Lemmy is more optimized and can handle the max depth
|
||||
/// of 100.
|
||||
/// fetched recursively. Ensure that it works properly.
|
||||
test("Fetch a deeply nested comment", async () => {
|
||||
let lastComment;
|
||||
for (let i = 0; i < 50; i++) {
|
||||
|
@ -29,11 +29,9 @@ use lemmy_db_schema::{
|
||||
use lemmy_db_views::structs::{LocalUserView, PostView};
|
||||
use lemmy_utils::{
|
||||
error::{LemmyErrorExt, LemmyErrorType, LemmyResult},
|
||||
utils::{mention::scrape_text_for_mentions, validation::is_valid_body_field},
|
||||
utils::{mention::scrape_text_for_mentions, validation::is_valid_body_field}, MAX_COMMENT_DEPTH_LIMIT,
|
||||
};
|
||||
|
||||
const MAX_COMMENT_DEPTH_LIMIT: usize = 100;
|
||||
|
||||
#[tracing::instrument(skip(context))]
|
||||
pub async fn create_comment(
|
||||
data: Json<CreateComment>,
|
||||
|
@ -20,7 +20,7 @@ use lemmy_db_schema::{
|
||||
source::{community::Community, post::Post},
|
||||
traits::Crud,
|
||||
};
|
||||
use lemmy_utils::{error::LemmyResult, LemmyErrorType};
|
||||
use lemmy_utils::{error::{LemmyError, LemmyResult}, LemmyErrorType, MAX_COMMENT_DEPTH_LIMIT};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::skip_serializing_none;
|
||||
use url::Url;
|
||||
@ -57,13 +57,24 @@ impl Note {
|
||||
&self,
|
||||
context: &Data<LemmyContext>,
|
||||
) -> LemmyResult<(ApubPost, Option<ApubComment>)> {
|
||||
// Fetch parent comment chain in a box, otherwise it can cause a stack overflow.
|
||||
// We use recursion here to fetch the entire comment chain up to the top-level parent. This is
|
||||
// necessary because we need to know the post and parent comment in order to insert a new
|
||||
// comment. However it can also lead to stack overflow when fetching many comments recursively.
|
||||
// To avoid this we check the request count against max comment depth, which based on testing
|
||||
// can be handled without risking stack overflow. This is not a perfect solution, because in
|
||||
// some cases we have to fetch user profiles too, and reach the limit after only 25 comments
|
||||
// or so.
|
||||
// A cleaner solution would be converting the recursion into a loop, but that is tricky.
|
||||
// Use a lower request limit here. Otherwise we can run into stack overflow due to recursion.
|
||||
if context.request_count() > MAX_COMMENT_DEPTH_LIMIT as u32 {
|
||||
Err(LemmyErrorType::MaxCommentDepthReached)?;
|
||||
}
|
||||
let parent = self.in_reply_to.dereference(context).await?;
|
||||
match parent {
|
||||
PostOrComment::Post(p) => Ok((p.clone(), None)),
|
||||
PostOrComment::Comment(c) => {
|
||||
let post_id = c.post_id;
|
||||
let post = Post::read(&mut context.pool(), post_id)
|
||||
let post = Box::pin(Post::read(&mut context.pool(), post_id))
|
||||
.await?
|
||||
.ok_or(LemmyErrorType::CouldntFindPost)?;
|
||||
Ok((post.into(), Some(c.clone())))
|
||||
|
@ -29,6 +29,8 @@ pub const CACHE_DURATION_FEDERATION: Duration = Duration::from_secs(60);
|
||||
|
||||
pub const CACHE_DURATION_API: Duration = Duration::from_secs(1);
|
||||
|
||||
pub const MAX_COMMENT_DEPTH_LIMIT: usize = 50;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! location_info {
|
||||
() => {
|
||||
|
Loading…
Reference in New Issue
Block a user