mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-27 17:18:13 +00:00
fix: improve output_file validation and error messages
Co-Authored-By: Joe Moura <joao@crewai.com>
This commit is contained in:
@@ -236,12 +236,13 @@ class Task(BaseModel):
|
|||||||
if ".." in value:
|
if ".." in value:
|
||||||
raise ValueError("Path traversal attempts are not allowed in output_file paths")
|
raise ValueError("Path traversal attempts are not allowed in output_file paths")
|
||||||
|
|
||||||
if any(char in value for char in ['|', '>', '<', '&', ';', '$']):
|
# Check for shell expansion first
|
||||||
raise ValueError("Shell special characters are not allowed in output_file paths")
|
|
||||||
|
|
||||||
# Check for absolute paths that might bypass restrictions
|
|
||||||
if value.startswith('~') or value.startswith('$'):
|
if value.startswith('~') or value.startswith('$'):
|
||||||
raise ValueError("Shell expansion characters are not allowed in output_file paths")
|
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
|
# Don't strip leading slash if it's a template path with variables
|
||||||
if "{" in value or "}" in value:
|
if "{" in value or "}" in value:
|
||||||
@@ -478,24 +479,25 @@ class Task(BaseModel):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
input_string: The string containing template variables to interpolate.
|
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.
|
inputs: Dictionary mapping template variables to their values.
|
||||||
Supported value types are strings, integers, and floats.
|
Supported value types are strings, integers, and floats.
|
||||||
|
If input_string is empty or has no placeholders, inputs can be empty.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The interpolated string with all template variables replaced with their values.
|
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:
|
Raises:
|
||||||
ValueError: If a required template variable is missing from inputs.
|
ValueError: If a required template variable is missing from inputs.
|
||||||
KeyError: If a template variable is not found in the inputs dictionary.
|
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 ""
|
return ""
|
||||||
if not input_string:
|
if "{" not in input_string and "}" not in input_string:
|
||||||
raise ValueError("Input string cannot be empty when provided")
|
return input_string
|
||||||
if not inputs:
|
if not inputs:
|
||||||
raise ValueError("Inputs dictionary cannot be empty")
|
raise ValueError("Inputs dictionary cannot be empty when interpolating variables")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Validate input types
|
# Validate input types
|
||||||
|
|||||||
@@ -880,20 +880,56 @@ def test_key():
|
|||||||
def test_output_file_validation():
|
def test_output_file_validation():
|
||||||
"""Test output file path validation."""
|
"""Test output file path validation."""
|
||||||
# Valid paths
|
# Valid paths
|
||||||
assert Task(output_file="output.txt").output_file == "output.txt"
|
assert Task(
|
||||||
assert Task(output_file="/tmp/output.txt").output_file == "tmp/output.txt"
|
description="Test task",
|
||||||
assert Task(output_file="{dir}/output_{date}.txt").output_file == "{dir}/output_{date}.txt"
|
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
|
# Invalid paths
|
||||||
with pytest.raises(ValueError, match="Path traversal"):
|
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"):
|
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"):
|
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"):
|
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"):
|
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"):
|
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"
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user