mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-15 17:30:13 +08:00
fix: validate hosted core package archive
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
import psutil
|
||||
@@ -258,6 +259,10 @@ class AstrBotUpdator(RepoZipUpdator):
|
||||
str(zip_path),
|
||||
progress_callback=progress_callback,
|
||||
)
|
||||
if not zipfile.is_zipfile(zip_path):
|
||||
raise RuntimeError(
|
||||
"Downloaded hosted package is not a valid ZIP file"
|
||||
)
|
||||
return zip_path
|
||||
except Exception as exc:
|
||||
logger.warning(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import ntpath
|
||||
import posixpath
|
||||
import zipfile
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
@@ -313,7 +314,8 @@ async def test_astrbot_updator_prefers_hosted_core_package(
|
||||
|
||||
async def fake_download_file(url: str, path: str, progress_callback=None): # noqa: ARG001
|
||||
calls.append(url)
|
||||
Path(path).write_bytes(b"hosted-core")
|
||||
with zipfile.ZipFile(path, "w") as archive:
|
||||
archive.writestr("AstrBot-v99.0.0/README.md", "hosted-core")
|
||||
|
||||
monkeypatch.setattr(updator, "fetch_release_info", fake_fetch_release_info)
|
||||
monkeypatch.setattr(updator, "_download_file", fake_download_file)
|
||||
@@ -325,7 +327,7 @@ async def test_astrbot_updator_prefers_hosted_core_package(
|
||||
)
|
||||
|
||||
assert zip_path == tmp_path / "core.zip"
|
||||
assert zip_path.read_bytes() == b"hosted-core"
|
||||
assert zipfile.is_zipfile(zip_path)
|
||||
assert calls == ["https://cdn.example/core/v99.0.0/source.zip"]
|
||||
|
||||
|
||||
@@ -376,6 +378,55 @@ async def test_astrbot_updator_falls_back_when_hosted_core_package_fails(
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_astrbot_updator_falls_back_when_hosted_core_package_is_not_zip(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
monkeypatch.delenv("ASTRBOT_CLI", raising=False)
|
||||
monkeypatch.delenv("ASTRBOT_LAUNCHER", raising=False)
|
||||
monkeypatch.setenv("ASTRBOT_CORE_PACKAGE_BASE_URL", "https://cdn.example/core")
|
||||
|
||||
updator = AstrBotUpdator()
|
||||
calls: list[str] = []
|
||||
|
||||
async def fake_fetch_release_info(url: str, latest: bool = True): # noqa: ARG001
|
||||
return [
|
||||
{
|
||||
"version": "AstrBot v99.0.0",
|
||||
"published_at": "2026-06-19T00:00:00Z",
|
||||
"body": "hosted core package",
|
||||
"tag_name": "v99.0.0",
|
||||
"zipball_url": "https://github.example/archive.zip",
|
||||
}
|
||||
]
|
||||
|
||||
async def fake_download_file(url: str, path: str, progress_callback=None): # noqa: ARG001
|
||||
calls.append(url)
|
||||
parsed = urlparse(url)
|
||||
if parsed.scheme == "https" and parsed.hostname == "cdn.example":
|
||||
Path(path).write_bytes(b"not a zip")
|
||||
return
|
||||
with zipfile.ZipFile(path, "w") as archive:
|
||||
archive.writestr("AstrBot-v99.0.0/README.md", "github-core")
|
||||
|
||||
monkeypatch.setattr(updator, "fetch_release_info", fake_fetch_release_info)
|
||||
monkeypatch.setattr(updator, "_download_file", fake_download_file)
|
||||
|
||||
zip_path = await updator.download_update_package(
|
||||
latest=False,
|
||||
version="v99.0.0",
|
||||
path=tmp_path / "core.zip",
|
||||
)
|
||||
|
||||
assert zip_path == tmp_path / "core.zip"
|
||||
assert zipfile.is_zipfile(zip_path)
|
||||
assert calls == [
|
||||
"https://cdn.example/core/v99.0.0/source.zip",
|
||||
"https://github.example/archive.zip",
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fetch_release_info_uses_httpx_client_with_env_proxy_support(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
|
||||
Reference in New Issue
Block a user