Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions docs/project-status.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,25 +43,25 @@ The project currently supports:

Application and shared modules:

- `src/googleart_download/cli/`
- `src/googleart_download/batch/`
- `src/googleart_download/reporting/`
- `src/googleart_download/models.py`
- `src/googleart_download/errors.py`
- `src/googleart_download/logging_utils.py`
- `src/artx/cli/`
- `src/artx/batch/`
- `src/artx/reporting/`
- `src/artx/models.py`
- `src/artx/errors.py`
- `src/artx/logging_utils.py`

Download domain:

- `src/googleart_download/download/constants.py`
- `src/googleart_download/download/http_client.py`
- `src/googleart_download/download/downloader.py`
- `src/googleart_download/download/tiles.py`
- `src/googleart_download/download/image_writer.py`
- `src/artx/download/constants.py`
- `src/artx/download/http_client.py`
- `src/artx/download/downloader.py`
- `src/artx/download/tiles.py`
- `src/artx/download/image_writer.py`

Metadata domain:

- `src/googleart_download/metadata/parsers.py`
- `src/googleart_download/metadata/output.py`
- `src/artx/metadata/parsers.py`
- `src/artx/metadata/output.py`

Repo quality and automation:

Expand All @@ -87,7 +87,7 @@ Repo quality and automation:
- added batch input deduplication, targeted rerun, explicit output conflict policies, and richer size inspection
- added explicit tile-only and stitch-from-tiles workflows
- added conservative batch download/stitch pipelining for adjacent artworks
- removed compatibility-shell leftovers after package reorganization
- removed compatibility-shim leftovers after package reorganization
- moved download-specific constants into the `download/` domain
- added `ruff`, `mypy`, and GitHub Actions CI
- added CI verification that generated README assets stay up to date
Expand Down
10 changes: 9 additions & 1 deletion src/artx/download/tiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,18 @@ def decrypt_tile_if_needed(data: bytes) -> bytes:

header_size = int.from_bytes(data[-4:], "little")
encrypted_size_offset = 4 + header_size
footer_end = len(data) - 4

if encrypted_size_offset + 4 > footer_end:
raise DownloadError("encrypted tile header metadata is malformed")

encrypted_size = int.from_bytes(data[encrypted_size_offset : encrypted_size_offset + 4], "little")
encrypted_start = encrypted_size_offset + 4
encrypted_end = encrypted_start + encrypted_size
footer_end = len(data) - 4

if encrypted_end > footer_end:
raise DownloadError("encrypted tile payload length is malformed")


header = data[4 : 4 + header_size]
encrypted = data[encrypted_start:encrypted_end]
Expand Down
17 changes: 17 additions & 0 deletions tests/test_tile_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,23 @@ def build_png_bytes(color: tuple[int, int, int]) -> bytes:


class TileCacheTests(unittest.TestCase):
def test_download_tiles_rejects_malformed_encrypted_payload(self) -> None:
jobs = [TileJob(z=0, x=0, y=0, url="https://example.com/0")]
malformed_encrypted = b"\x0a\x0a\x0a\x0a\x01\x00\x00\x00"

with TemporaryDirectory() as tmpdir:
tiles_dir = ensure_cache_layout(Path(tmpdir))
client = FakeHttpClient(malformed_encrypted)

with self.assertRaises(DownloadError):
download_tiles(
jobs,
workers=1,
reporter=SilentReporter(),
http_client=client,
tiles_dir=tiles_dir,
)

def test_download_tiles_reuses_existing_cache(self) -> None:
jobs = [
TileJob(z=0, x=0, y=0, url="https://example.com/0"),
Expand Down
Loading