Make output validate paths are absolute and normalized
Also update the checks in Symlink to use the same functions
This commit is contained in:
@@ -9,6 +9,10 @@ else:
|
|||||||
Site = "omicron.ssg.site.Site" # for runtime checking with beartype
|
Site = "omicron.ssg.site.Site" # for runtime checking with beartype
|
||||||
|
|
||||||
|
|
||||||
|
def is_normalized(path: Path) -> bool:
|
||||||
|
return ".." not in path.parts
|
||||||
|
|
||||||
|
|
||||||
class OutputError(RuntimeError):
|
class OutputError(RuntimeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -16,7 +20,12 @@ class OutputError(RuntimeError):
|
|||||||
class Output(ABC):
|
class Output(ABC):
|
||||||
def __init__(self, site: Site, destination: Path):
|
def __init__(self, site: Site, destination: Path):
|
||||||
self._site_ref = weakref.ref(site)
|
self._site_ref = weakref.ref(site)
|
||||||
|
if destination.is_absolute():
|
||||||
|
raise OutputError("destination path must be relative")
|
||||||
|
if not is_normalized(destination):
|
||||||
|
raise OutputError("destination path must be normalized")
|
||||||
self.destination = destination
|
self.destination = destination
|
||||||
|
|
||||||
url = site.base_dir + "/" + destination.as_posix()
|
url = site.base_dir + "/" + destination.as_posix()
|
||||||
url = url.removesuffix("/index.html") or "/"
|
url = url.removesuffix("/index.html") or "/"
|
||||||
self.url = url
|
self.url = url
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
from omicron.ssg.output.output import Output, OutputError
|
from omicron.ssg.output.output import Output, OutputError, is_normalized
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@@ -15,13 +15,9 @@ else:
|
|||||||
class Symlink(Output):
|
class Symlink(Output):
|
||||||
def __init__(self, site: Site, link: Path, target: Path):
|
def __init__(self, site: Site, link: Path, target: Path):
|
||||||
if target.is_absolute():
|
if target.is_absolute():
|
||||||
raise ValueError("Symlinks must be relative")
|
raise OutputError("Symlinks target must be relative")
|
||||||
if (
|
if not is_normalized(target):
|
||||||
not (site.output_path / target)
|
raise OutputError("Symlinks target must be normalized")
|
||||||
.resolve()
|
|
||||||
.is_relative_to(site.output_path.resolve())
|
|
||||||
):
|
|
||||||
raise ValueError("Symlink target escapes the output directory")
|
|
||||||
super().__init__(site, link)
|
super().__init__(site, link)
|
||||||
self.target = target
|
self.target = target
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user