auto: 2026-09-02 16:48 (EOMSANGDON-HOME)
This commit is contained in:
@@ -120,3 +120,28 @@ def resolve_stored_project_path(relative_path: str) -> str:
|
||||
os.makedirs(path, exist_ok=True)
|
||||
ensure_project_storage_layout(path)
|
||||
return path
|
||||
|
||||
|
||||
def read_stored_asset(relative_path: str | None) -> bytes | None:
|
||||
"""`storage/` 기준 상대 경로의 **파일**을 읽는다. 없거나 수상하면 None.
|
||||
|
||||
회사 로고·개인 서명처럼 DB에 경로만 담아 두는 자산용이다.
|
||||
`resolve_stored_project_path()`는 폴더를 만들어 주는 프로젝트 루트용이라 파일에는
|
||||
쓸 수 없다. 검증 규칙(상대 경로·`storage/` 시작·루트 밖 금지)은 같다.
|
||||
"""
|
||||
if not relative_path:
|
||||
return None
|
||||
normalized = PurePosixPath(str(relative_path).replace("\\", "/"))
|
||||
if normalized.is_absolute() or ".." in normalized.parts:
|
||||
return None
|
||||
if not normalized.parts or normalized.parts[0] != "storage":
|
||||
return None
|
||||
|
||||
storage_root = os.path.realpath(STORAGE_BASE_DIR)
|
||||
path = os.path.realpath(os.path.join(storage_root, *normalized.parts[1:]))
|
||||
if os.path.commonpath((storage_root, path)) != storage_root or path == storage_root:
|
||||
return None
|
||||
if not os.path.isfile(path):
|
||||
return None
|
||||
with open(path, "rb") as file:
|
||||
return file.read()
|
||||
|
||||
Reference in New Issue
Block a user