diff options
| author | Daniel Schadt <kingdread@gmx.de> | 2023-05-25 20:59:43 +0200 | 
|---|---|---|
| committer | Daniel Schadt <kingdread@gmx.de> | 2023-05-25 20:59:43 +0200 | 
| commit | e1aa29d92094aafe5109c9fb42e9146bc25ce380 (patch) | |
| tree | 11ba8efb4faf39691e7de46ab9fe593c351d112e | |
| parent | cd60935d777aee984224844badc7f260caa3bb46 (diff) | |
| download | fietsboek-e1aa29d92094aafe5109c9fb42e9146bc25ce380.tar.gz fietsboek-e1aa29d92094aafe5109c9fb42e9146bc25ce380.tar.bz2 fietsboek-e1aa29d92094aafe5109c9fb42e9146bc25ce380.zip  | |
html-encode the link when saving GPX files
This fixes links that contain ampersands by encoding them as &. It
is a quick workaround, not a proper fix, but at least it makes BRouter
exports working.
| -rw-r--r-- | fietsboek/actions.py | 2 | ||||
| -rw-r--r-- | fietsboek/data.py | 10 | ||||
| -rw-r--r-- | fietsboek/util.py | 23 | 
3 files changed, 26 insertions, 9 deletions
diff --git a/fietsboek/actions.py b/fietsboek/actions.py index 6afbfa4..b9221c3 100644 --- a/fietsboek/actions.py +++ b/fietsboek/actions.py @@ -208,7 +208,7 @@ def execute_transformers(request: Request, track: models.Track) -> Optional[gpxp          transformer.execute(gpx)      LOGGER.debug("Saving transformed file for %d", track.id) -    manager.compress_gpx(gpx.to_xml().encode("utf-8")) +    manager.compress_gpx(util.encode_gpx(gpx))      LOGGER.debug("Saving new transformers on %d", track.id)      track.transformers = serialized diff --git a/fietsboek/data.py b/fietsboek/data.py index 7457986..debddf1 100644 --- a/fietsboek/data.py +++ b/fietsboek/data.py @@ -16,7 +16,7 @@ import brotli  import gpxpy  from filelock import FileLock -from .util import secure_filename +from . import util  LOGGER = logging.getLogger(__name__) @@ -31,7 +31,7 @@ def generate_filename(filename: Optional[str]) -> str:      :return: The generated filename.      """      if filename: -        good_name = secure_filename(filename) +        good_name = util.secure_filename(filename)          if good_name:              random_prefix = "".join(random.choice(string.ascii_lowercase) for _ in range(5))              return f"{random_prefix}_{good_name}" @@ -313,7 +313,7 @@ class TrackDataDir:          gpx.description = description          gpx.time = time -        self.compress_gpx(gpx.to_xml().encode("utf-8")) +        self.compress_gpx(util.encode_gpx(gpx))      def backup(self):          """Create a backup of the GPX file.""" @@ -345,7 +345,7 @@ class TrackDataDir:          :param image_id: ID of the image.          :return: A path pointing to the requested image.          """ -        image = self.path / "images" / secure_filename(image_id) +        image = self.path / "images" / util.secure_filename(image_id)          if not image.exists():              raise FileNotFoundError("The requested image does not exist")          return image @@ -377,7 +377,7 @@ class TrackDataDir:          :param image_id: ID of the image.          """          # Be sure to not delete anything else than the image file -        image_id = secure_filename(image_id) +        image_id = util.secure_filename(image_id)          if "/" in image_id or "\\" in image_id:              return          path = self.image_path(image_id) diff --git a/fietsboek/util.py b/fietsboek/util.py index a296151..199baab 100644 --- a/fietsboek/util.py +++ b/fietsboek/util.py @@ -1,5 +1,6 @@  """Various utility functions."""  import datetime +import html  import importlib.resources  import os  import re @@ -65,9 +66,9 @@ def safe_markdown(md_source: str) -> Markup:      :param md_source: The markdown source.      :return: The safe HTML transformed version.      """ -    html = markdown.markdown(md_source, output_format="html") -    html = nh3.clean(html, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRIBUTES) -    return Markup(html) +    converted = markdown.markdown(md_source, output_format="html") +    converted = nh3.clean(converted, tags=ALLOWED_TAGS, attributes=ALLOWED_ATTRIBUTES) +    return Markup(converted)  def fix_iso_timestamp(timestamp: str) -> str: @@ -354,6 +355,22 @@ def tile_url(request: Request, route_name: str, **kwargs: str) -> str:      return route.replace("__x__", "{x}").replace("__y__", "{y}").replace("__z__", "{z}") +def encode_gpx(gpx: gpxpy.gpx.GPX) -> bytes: +    """Encodes a GPX in-memory representation to the XML representation. + +    This ensures that the resulting XML file is valid. + +    Returns the contents of the XML as bytes, ready to be written to disk. + +    :param gpx: The GPX file to encode. Might be modified! +    :return: The encoded GPX content. +    """ +    for track in gpx.tracks: +        if track.link: +            track.link = html.escape(track.link) +    return gpx.to_xml().encode("utf-8") + +  def secure_filename(filename: str) -> str:      r"""Pass it a filename and it will return a secure version of it.  This      filename can then safely be stored on a regular file system and passed  | 
