From 0c70aa641d64515e90211538bf211f2dd5006c1e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 21 Jun 2024 16:18:16 +0200 Subject: [PATCH 1/6] scp: Avoid crashing when remote file does not exist Signed-off-by: Jakub Jelen --- src/pylibsshext/scp.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pylibsshext/scp.pyx b/src/pylibsshext/scp.pyx index 46004f959..c3f9933f5 100644 --- a/src/pylibsshext/scp.pyx +++ b/src/pylibsshext/scp.pyx @@ -96,7 +96,7 @@ cdef class SCP: :param local_file: The path on the local host where the file should be placed :type local_file: str """ - cdef char *read_buffer + cdef char *read_buffer = NULL remote_file_b = remote_file if isinstance(remote_file_b, unicode): From 21ff5ede5040424837e9d9d93f6750fed92222b4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 21 Jun 2024 16:18:35 +0200 Subject: [PATCH 2/6] tests: Reproducer for non-existing remote file Signed-off-by: Jakub Jelen --- tests/unit/scp_test.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/unit/scp_test.py b/tests/unit/scp_test.py index 4b210cb14..7279ce56d 100644 --- a/tests/unit/scp_test.py +++ b/tests/unit/scp_test.py @@ -6,6 +6,8 @@ import pytest +from pylibsshext.errors import LibsshSCPException + @pytest.fixture def ssh_scp(ssh_client_session): @@ -57,3 +59,18 @@ def test_get(dst_path, src_path, ssh_scp, transmit_payload): """Check that SCP file download works.""" ssh_scp.get(str(src_path), str(dst_path)) assert dst_path.read_bytes() == transmit_payload + + +@pytest.fixture +def src_path_missing(tmp_path): + """Return a remote path that does not exist.""" + path = tmp_path / 'non-existing.txt' + assert not path.exists() + return path + + +def test_get_missing_src(dst_path, src_path_missing, ssh_scp): + """Check that SCP file download raises exception if the remote file is missing.""" + error_msg = '^Error receiving information about file:' + with pytest.raises(LibsshSCPException, match=error_msg): + ssh_scp.get(str(src_path_missing), str(dst_path)) From 8d6558c943df45ec466dc508bad6d82a73fcac0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sviatoslav=20Sydorenko=20=28=D0=A1=D0=B2=D1=8F=D1=82=D0=BE?= =?UTF-8?q?=D1=81=D0=BB=D0=B0=D0=B2=20=D0=A1=D0=B8=D0=B4=D0=BE=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE=29?= Date: Wed, 26 Jun 2024 23:02:24 +0200 Subject: [PATCH 3/6] Clarify the `path_to_non_existent_src_file` fixture name --- tests/unit/scp_test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/unit/scp_test.py b/tests/unit/scp_test.py index 7279ce56d..025bea622 100644 --- a/tests/unit/scp_test.py +++ b/tests/unit/scp_test.py @@ -62,15 +62,15 @@ def test_get(dst_path, src_path, ssh_scp, transmit_payload): @pytest.fixture -def src_path_missing(tmp_path): +def path_to_non_existent_src_file(tmp_path): """Return a remote path that does not exist.""" path = tmp_path / 'non-existing.txt' assert not path.exists() return path -def test_get_missing_src(dst_path, src_path_missing, ssh_scp): +def test_get_missing_src(dst_path, path_to_non_existent_src_file, ssh_scp): """Check that SCP file download raises exception if the remote file is missing.""" error_msg = '^Error receiving information about file:' with pytest.raises(LibsshSCPException, match=error_msg): - ssh_scp.get(str(src_path_missing), str(dst_path)) + ssh_scp.get(str(path_to_non_existent_src_file), str(dst_path)) From 37f906236bf4c4a0d025e962d5132be70039320b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sviatoslav=20Sydorenko=20=28=D0=A1=D0=B2=D1=8F=D1=82=D0=BE?= =?UTF-8?q?=D1=81=D0=BB=D0=B0=D0=B2=20=D0=A1=D0=B8=D0=B4=D0=BE=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE=29?= Date: Wed, 26 Jun 2024 23:04:52 +0200 Subject: [PATCH 4/6] Use `/dev/null` @ copy non-existing remote file test --- tests/unit/scp_test.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/unit/scp_test.py b/tests/unit/scp_test.py index 025bea622..697ba5f5b 100644 --- a/tests/unit/scp_test.py +++ b/tests/unit/scp_test.py @@ -2,6 +2,7 @@ """Tests suite for scp.""" +import os import uuid import pytest @@ -69,8 +70,8 @@ def path_to_non_existent_src_file(tmp_path): return path -def test_get_missing_src(dst_path, path_to_non_existent_src_file, ssh_scp): +def test_get_missing_src(path_to_non_existent_src_file, ssh_scp): """Check that SCP file download raises exception if the remote file is missing.""" error_msg = '^Error receiving information about file:' with pytest.raises(LibsshSCPException, match=error_msg): - ssh_scp.get(str(path_to_non_existent_src_file), str(dst_path)) + ssh_scp.get(str(path_to_non_existent_src_file), os.devnull) From 6700cb8b2485c1528cde5fd4ff38aee99c6c1222 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sviatoslav=20Sydorenko=20=28=D0=A1=D0=B2=D1=8F=D1=82=D0=BE?= =?UTF-8?q?=D1=81=D0=BB=D0=B0=D0=B2=20=D0=A1=D0=B8=D0=B4=D0=BE=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE=29?= Date: Wed, 26 Jun 2024 23:07:18 +0200 Subject: [PATCH 5/6] Clarify `test_copy_from_non_existent_remote_path` name --- tests/unit/scp_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/scp_test.py b/tests/unit/scp_test.py index 697ba5f5b..07072124e 100644 --- a/tests/unit/scp_test.py +++ b/tests/unit/scp_test.py @@ -70,7 +70,7 @@ def path_to_non_existent_src_file(tmp_path): return path -def test_get_missing_src(path_to_non_existent_src_file, ssh_scp): +def test_copy_from_non_existent_remote_path(path_to_non_existent_src_file, ssh_scp): """Check that SCP file download raises exception if the remote file is missing.""" error_msg = '^Error receiving information about file:' with pytest.raises(LibsshSCPException, match=error_msg): From 6b6e5661578e118c60557f63c4863f0e88a4159d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 21 Jun 2024 16:27:29 +0200 Subject: [PATCH 6/6] Add changelog entry Signed-off-by: Jakub Jelen --- docs/changelog-fragments/208.bugfix.rst | 1 + docs/changelog-fragments/325.bugfix.rst | 1 + docs/changelog-fragments/620.bugfix.rst | 1 + 3 files changed, 3 insertions(+) create mode 120000 docs/changelog-fragments/208.bugfix.rst create mode 120000 docs/changelog-fragments/325.bugfix.rst create mode 100644 docs/changelog-fragments/620.bugfix.rst diff --git a/docs/changelog-fragments/208.bugfix.rst b/docs/changelog-fragments/208.bugfix.rst new file mode 120000 index 000000000..aad01ce8b --- /dev/null +++ b/docs/changelog-fragments/208.bugfix.rst @@ -0,0 +1 @@ +620.bugfix.rst \ No newline at end of file diff --git a/docs/changelog-fragments/325.bugfix.rst b/docs/changelog-fragments/325.bugfix.rst new file mode 120000 index 000000000..aad01ce8b --- /dev/null +++ b/docs/changelog-fragments/325.bugfix.rst @@ -0,0 +1 @@ +620.bugfix.rst \ No newline at end of file diff --git a/docs/changelog-fragments/620.bugfix.rst b/docs/changelog-fragments/620.bugfix.rst new file mode 100644 index 000000000..d4db77c88 --- /dev/null +++ b/docs/changelog-fragments/620.bugfix.rst @@ -0,0 +1 @@ +Downloading non-existent remote files via SCP no longer crashes the program -- by :user:`Jakuje`.