fix: improve output_file validation and error messages

Co-Authored-By: Joe Moura <joao@crewai.com>
This commit is contained in:
Devin AI
2024-12-29 03:38:33 +00:00
parent 83b4e0b4c0
commit bdb32dd3e6
2 changed files with 57 additions and 19 deletions

View File

@@ -236,12 +236,13 @@ class Task(BaseModel):
if ".." in value:
raise ValueError("Path traversal attempts are not allowed in output_file paths")
if any(char in value for char in ['|', '>', '<', '&', ';', '$']):
raise ValueError("Shell special characters are not allowed in output_file paths")
# Check for absolute paths that might bypass restrictions
# Check for shell expansion first
if value.startswith('~') or value.startswith('$'):
raise ValueError("Shell expansion characters are not allowed in output_file paths")
# Then check other shell special characters
if any(char in value for char in ['|', '>', '<', '&', ';']):
raise ValueError("Shell special characters are not allowed in output_file paths")
# Don't strip leading slash if it's a template path with variables
if "{" in value or "}" in value:
@@ -478,24 +479,25 @@ class Task(BaseModel):
Args:
input_string: The string containing template variables to interpolate.
Can be None, in which case an empty string is returned.
Can be None or empty, in which case an empty string is returned.
inputs: Dictionary mapping template variables to their values.
Supported value types are strings, integers, and floats.
If input_string is empty or has no placeholders, inputs can be empty.
Returns:
The interpolated string with all template variables replaced with their values.
Empty string if input_string is None.
Empty string if input_string is None or empty.
Raises:
ValueError: If a required template variable is missing from inputs.
KeyError: If a template variable is not found in the inputs dictionary.
"""
if input_string is None:
if input_string is None or not input_string:
return ""
if not input_string:
raise ValueError("Input string cannot be empty when provided")
if "{" not in input_string and "}" not in input_string:
return input_string
if not inputs:
raise ValueError("Inputs dictionary cannot be empty")
raise ValueError("Inputs dictionary cannot be empty when interpolating variables")
try:
# Validate input types

View File

@@ -880,20 +880,56 @@ def test_key():
def test_output_file_validation():
"""Test output file path validation."""
# Valid paths
assert Task(output_file="output.txt").output_file == "output.txt"
assert Task(output_file="/tmp/output.txt").output_file == "tmp/output.txt"
assert Task(output_file="{dir}/output_{date}.txt").output_file == "{dir}/output_{date}.txt"
assert Task(
description="Test task",
expected_output="Test output",
output_file="output.txt"
).output_file == "output.txt"
assert Task(
description="Test task",
expected_output="Test output",
output_file="/tmp/output.txt"
).output_file == "tmp/output.txt"
assert Task(
description="Test task",
expected_output="Test output",
output_file="{dir}/output_{date}.txt"
).output_file == "{dir}/output_{date}.txt"
# Invalid paths
with pytest.raises(ValueError, match="Path traversal"):
Task(output_file="../output.txt")
Task(
description="Test task",
expected_output="Test output",
output_file="../output.txt"
)
with pytest.raises(ValueError, match="Path traversal"):
Task(output_file="folder/../output.txt")
Task(
description="Test task",
expected_output="Test output",
output_file="folder/../output.txt"
)
with pytest.raises(ValueError, match="Shell special characters"):
Task(output_file="output.txt | rm -rf /")
Task(
description="Test task",
expected_output="Test output",
output_file="output.txt | rm -rf /"
)
with pytest.raises(ValueError, match="Shell expansion"):
Task(output_file="~/output.txt")
Task(
description="Test task",
expected_output="Test output",
output_file="~/output.txt"
)
with pytest.raises(ValueError, match="Shell expansion"):
Task(output_file="$HOME/output.txt")
Task(
description="Test task",
expected_output="Test output",
output_file="$HOME/output.txt"
)
with pytest.raises(ValueError, match="Invalid template variable"):
Task(output_file="{invalid-name}/output.txt")
Task(
description="Test task",
expected_output="Test output",
output_file="{invalid-name}/output.txt"
)