From ee7011dabbd0de1afa71123741ddfff54e3955f5 Mon Sep 17 00:00:00 2001 From: immanuwell Date: Mon, 22 Jun 2026 21:37:37 +0400 Subject: [PATCH] fix: handle empty files in last_n_bytes_of Signed-off-by: immanuwell --- py/envoy.base.utils/envoy/base/utils/utils.py | 3 ++- py/envoy.base.utils/tests/test_utils.py | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/py/envoy.base.utils/envoy/base/utils/utils.py b/py/envoy.base.utils/envoy/base/utils/utils.py index ba0f0613ed..6365b667f7 100644 --- a/py/envoy.base.utils/envoy/base/utils/utils.py +++ b/py/envoy.base.utils/envoy/base/utils/utils.py @@ -139,7 +139,8 @@ def last_n_bytes_of(target: str | pathlib.Path, n: int = 1) -> bytes: """Return the last `n` bytes from a file, defaults to 1 byte.""" with open(target, "rb") as f: f.seek(0, os.SEEK_END) - f.seek(f.tell() - n) + # Clamp to the start of the file so empty or short files do not raise on negative seek. + f.seek(max(f.tell() - n, 0)) return f.read(n) diff --git a/py/envoy.base.utils/tests/test_utils.py b/py/envoy.base.utils/tests/test_utils.py index 8ddb1c436e..80361aed7e 100644 --- a/py/envoy.base.utils/tests/test_utils.py +++ b/py/envoy.base.utils/tests/test_utils.py @@ -1,4 +1,5 @@ import pathlib +import tempfile from unittest.mock import MagicMock import pytest @@ -271,7 +272,7 @@ def test_last_n_bytes_of(patches, n): assert ( m_open.return_value.__enter__.return_value.seek.call_args_list == [[(0, m_os.SEEK_END), {}], - [(23 - (n or 1), ), {}]]) + [(max(23 - (n or 1), 0), ), {}]]) assert ( m_open.return_value.__enter__.return_value.tell.call_args == [(), {}]) @@ -280,6 +281,11 @@ def test_last_n_bytes_of(patches, n): == [(n or 1, ), {}]) +def test_last_n_bytes_of_empty_file(): + with tempfile.NamedTemporaryFile() as f: + assert utils.last_n_bytes_of(f.name) == b"" + + def test_minor_version_for(patches): patched = patches( "_version",