From 5b328e4d63474d4d8c5f4b8e8ed9bf11bb489718 Mon Sep 17 00:00:00 2001 From: Stefan Liebl Date: Tue, 28 Apr 2026 21:29:53 +0200 Subject: [PATCH] Fix: escape XML special chars when generating GPX from Park4Night bookmarks --- get_bookmarks.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/get_bookmarks.py b/get_bookmarks.py index 05fcb7f..dd3c875 100644 --- a/get_bookmarks.py +++ b/get_bookmarks.py @@ -6,6 +6,18 @@ import os from bs4 import BeautifulSoup from dotenv import load_dotenv from datetime import datetime +from xml.sax.saxutils import escape as _xml_escape + +def xml_escape(text): + """ + Escape text for use inside XML element text nodes. + + Important: At least '&', '<', '>' must be escaped to keep GPX well-formed. + We also escape quotes defensively. + """ + if text is None: + return '' + return _xml_escape(str(text), entities={'"': '"', "'": '''}) def create_gpx(places, folder_name, output_file='places.gpx'): """Create a GPX file from the collected places.""" @@ -29,12 +41,12 @@ def create_gpx(places, folder_name, output_file='places.gpx'): waypoints.append(waypoint_template.format( lat=place['coordinates']['lat'], lon=place['coordinates']['lng'], - name=place['name'], - desc=place['description'] or '' + name=xml_escape(place['name']), + desc=xml_escape(place['description'] or '') )) gpx_content = gpx_template.format( - folder_name=folder_name, + folder_name=xml_escape(folder_name), timestamp=datetime.utcnow().isoformat(), waypoints='\n'.join(waypoints) ) @@ -283,4 +295,4 @@ def main(): print("\nFailed to get bookmarks.") if __name__ == "__main__": - main() \ No newline at end of file + main()