mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-12-28 05:05:12 -05:00
fix: recipe recursion false positive (#6591)
Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com> Co-authored-by: Michael Genson <genson.michael@gmail.com>
This commit is contained in:
committed by
GitHub
parent
3146e99b03
commit
8f1ce1a1c3
@@ -369,25 +369,35 @@ class RecipeService(RecipeServiceBase):
|
||||
|
||||
return new_recipe
|
||||
|
||||
def has_recursive_recipe_link(self, recipe: Recipe, visited: set[str] | None = None):
|
||||
def has_recursive_recipe_link(self, recipe: Recipe, path: set[str] | None = None):
|
||||
"""Recursively checks if a recipe links to itself through its ingredients."""
|
||||
if path is None:
|
||||
path = set()
|
||||
|
||||
if visited is None:
|
||||
visited = set()
|
||||
recipe_id = str(getattr(recipe, "id", None))
|
||||
if recipe_id in visited:
|
||||
|
||||
# Check if this recipe is already in the current path (cycle detected)
|
||||
if recipe_id in path:
|
||||
return True
|
||||
|
||||
visited.add(recipe_id)
|
||||
ingredients = getattr(recipe, "recipe_ingredient", [])
|
||||
for ing in ingredients:
|
||||
try:
|
||||
sub_recipe = self.get_one(ing.referenced_recipe.id)
|
||||
except (AttributeError, exceptions.NoEntryFound):
|
||||
continue
|
||||
# Add to the current path
|
||||
path.add(recipe_id)
|
||||
|
||||
try:
|
||||
ingredients = getattr(recipe, "recipe_ingredient", [])
|
||||
for ing in ingredients:
|
||||
try:
|
||||
sub_recipe = self.get_one(ing.referenced_recipe.id)
|
||||
except (AttributeError, exceptions.NoEntryFound):
|
||||
continue
|
||||
|
||||
# Recursively check - path is modified in place and cleaned up via backtracking
|
||||
if self.has_recursive_recipe_link(sub_recipe, path):
|
||||
return True
|
||||
finally:
|
||||
# Backtrack: remove this recipe from the path when done exploring this branch
|
||||
path.discard(recipe_id)
|
||||
|
||||
if self.has_recursive_recipe_link(sub_recipe, visited):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _pre_update_check(self, slug_or_id: str | UUID, new_data: Recipe) -> Recipe:
|
||||
|
||||
Reference in New Issue
Block a user