diff --git a/cwltool/builder.py b/cwltool/builder.py index f5d6824e0..ff1c099e5 100644 --- a/cwltool/builder.py +++ b/cwltool/builder.py @@ -86,7 +86,7 @@ def content_limit_respected_read(f: IO[bytes]) -> str: :returns: the file contents :raises WorkflowException: if the file is too large """ - return content_limit_respected_read_bytes(f).decode("utf-8") + return str(content_limit_respected_read_bytes(f), "utf-8") def substitute(value: str, replace: str) -> str: diff --git a/cwltool/command_line_tool.py b/cwltool/command_line_tool.py index 5b2bea5b2..b11bb4bc3 100644 --- a/cwltool/command_line_tool.py +++ b/cwltool/command_line_tool.py @@ -1369,8 +1369,8 @@ def collect_output( else: if binding.get("loadContents"): with fs_access.open(cast(str, rfile["location"]), "rb") as f: - files["contents"] = content_limit_respected_read_bytes(f).decode( - "utf-8" + files["contents"] = str( + content_limit_respected_read_bytes(f), "utf-8" ) if compute_checksum: with fs_access.open(cast(str, rfile["location"]), "rb") as f: diff --git a/cwltool/cwlrdf.py b/cwltool/cwlrdf.py index 7dcf85cbc..dbe9e2f97 100644 --- a/cwltool/cwlrdf.py +++ b/cwltool/cwlrdf.py @@ -27,7 +27,7 @@ def printrdf(wflow: Process, ctx: ContextType, style: str) -> str: rdf = gather(wflow, ctx).serialize(format=style, encoding="utf-8") if not rdf: return "" - return rdf.decode("utf-8") + return str(rdf, "utf-8") def lastpart(uri: Any) -> str: diff --git a/cwltool/docker.py b/cwltool/docker.py index a1b9c8a37..4114173b2 100644 --- a/cwltool/docker.py +++ b/cwltool/docker.py @@ -116,10 +116,11 @@ def get_image( if (docker_image_id := docker_requirement.get("dockerImageId")) is not None: try: manifest = json.loads( - subprocess.check_output( - [self.docker_exec, "inspect", docker_image_id] - ).decode( # nosec - "utf-8" + str( + subprocess.check_output( + [self.docker_exec, "inspect", docker_image_id] + ), # nosec + "utf-8", ) ) found = manifest is not None diff --git a/cwltool/utils.py b/cwltool/utils.py index 219f91830..c8620994a 100644 --- a/cwltool/utils.py +++ b/cwltool/utils.py @@ -200,7 +200,7 @@ def bytes2str_in_dicts( # if value is bytes, return decoded string, elif isinstance(inp, bytes): - return inp.decode("utf-8") + return str(inp, "utf-8") # simply return elements itself return inp diff --git a/tests/test_path_checks.py b/tests/test_path_checks.py index 018a92120..0532f3cde 100644 --- a/tests/test_path_checks.py +++ b/tests/test_path_checks.py @@ -12,7 +12,9 @@ from cwltool.main import main from cwltool.stdfsaccess import StdFsAccess from cwltool.update import INTERNAL_VERSION -from cwltool.utils import CWLObjectType +from cwltool.utils import CWLObjectType, CONTENT_LIMIT, bytes2str_in_dicts +from cwltool.builder import content_limit_respected_read +from cwltool.errors import WorkflowException from .util import needs_docker @@ -214,3 +216,26 @@ def test_clt_returns_specialchar_names(tmp_path: Path) -> None: result["location"] == "keep:ae755cd1b3cff63152ff4200f4dea7e9+52/%3A%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D" ) + + +def test_content_limit_respected_read() -> None: + b1 = b"abcd" * 100 + b1io = BytesIO(b1) + + assert len(b1) < CONTENT_LIMIT + assert content_limit_respected_read(b1io) == str("abcd" * 100) + + b2 = b"abcd" * 20000 + b2io = BytesIO(b2) + + assert len(b2) > CONTENT_LIMIT + with pytest.raises(WorkflowException): + content_limit_respected_read(b2io) + + +def test_bytes2str_in_dicts() -> None: + assert bytes2str_in_dicts({"foo": b"bar"}) == {"foo": "bar"} + + assert bytes2str_in_dicts({"foo": [b"bar"]}) == {"foo": ["bar"]} + + assert bytes2str_in_dicts({"foo": {"foo2": b"bar"}}) == {"foo": {"foo2": "bar"}}