From 1610fc3497241ea88963a718c59602f5e8e95ae0 Mon Sep 17 00:00:00 2001 From: SergeantPanda Date: Mon, 7 Apr 2025 18:11:47 -0500 Subject: [PATCH] fix: escape XML special characters in EPG generation --- apps/output/views.py | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/apps/output/views.py b/apps/output/views.py index ef1ca227..3d268e10 100644 --- a/apps/output/views.py +++ b/apps/output/views.py @@ -5,6 +5,7 @@ from apps.epg.models import ProgramData from django.utils import timezone from datetime import datetime, timedelta import re +import html # Add this import for XML escaping def generate_m3u(request, profile_name=None): """ @@ -59,9 +60,9 @@ def generate_dummy_epg(name, channel_id, num_days=7, interval_hours=4): start_str = start_time.strftime("%Y%m%d%H%M%S") + " 0000" stop_str = stop_time.strftime("%Y%m%d%H%M%S") + " 0000" - # Create the XML-like programme entry + # Create the XML-like programme entry with escaped name xml_lines.append(f'') - xml_lines.append(f' {name}') + xml_lines.append(f' {html.escape(name)}') xml_lines.append(f'') return xml_lines @@ -91,7 +92,7 @@ def generate_epg(request, profile_name=None): channel_id = channel.channel_number or channel.id display_name = channel.epg_data.name if channel.epg_data else channel.name xml_lines.append(f' ') - xml_lines.append(f' {display_name}') + xml_lines.append(f' {html.escape(display_name)}') # Add channel logo if available if channel.logo: @@ -104,7 +105,7 @@ def generate_epg(request, profile_name=None): base_url = request.build_absolute_uri('/')[:-1] logo_url = f"{base_url}{logo_uri}" - xml_lines.append(f' ') + xml_lines.append(f' ') xml_lines.append(' ') @@ -119,15 +120,15 @@ def generate_epg(request, profile_name=None): start_str = prog.start_time.strftime("%Y%m%d%H%M%S %z") stop_str = prog.end_time.strftime("%Y%m%d%H%M%S %z") xml_lines.append(f' ') - xml_lines.append(f' {prog.title}') + xml_lines.append(f' {html.escape(prog.title)}') # Add subtitle if available if prog.sub_title: - xml_lines.append(f' {prog.sub_title}') + xml_lines.append(f' {html.escape(prog.sub_title)}') # Add description if available if prog.description: - xml_lines.append(f' {prog.description}') + xml_lines.append(f' {html.escape(prog.description)}') # Process custom properties if available if prog.custom_properties: @@ -138,7 +139,7 @@ def generate_epg(request, profile_name=None): # Add categories if available if 'categories' in custom_data and custom_data['categories']: for category in custom_data['categories']: - xml_lines.append(f' {category}') + xml_lines.append(f' {html.escape(category)}') # Handle episode numbering - multiple formats supported # Standard episode number if available @@ -147,7 +148,7 @@ def generate_epg(request, profile_name=None): # Handle onscreen episode format (like S06E128) if 'onscreen_episode' in custom_data: - xml_lines.append(f' {custom_data["onscreen_episode"]}') + xml_lines.append(f' {html.escape(custom_data["onscreen_episode"])}') # Add season and episode numbers in xmltv_ns format if available if 'season' in custom_data and 'episode' in custom_data: @@ -158,8 +159,8 @@ def generate_epg(request, profile_name=None): # Add rating if available if 'rating' in custom_data: rating_system = custom_data.get('rating_system', 'TV Parental Guidelines') - xml_lines.append(f' ') - xml_lines.append(f' {custom_data["rating"]}') + xml_lines.append(f' ') + xml_lines.append(f' {html.escape(custom_data["rating"])}') xml_lines.append(f' ') # Add actors/directors/writers if available @@ -168,22 +169,22 @@ def generate_epg(request, profile_name=None): for role, people in custom_data['credits'].items(): if isinstance(people, list): for person in people: - xml_lines.append(f' <{role}>{person}') + xml_lines.append(f' <{role}>{html.escape(person)}') else: - xml_lines.append(f' <{role}>{people}') + xml_lines.append(f' <{role}>{html.escape(people)}') xml_lines.append(f' ') # Add program date/year if available if 'year' in custom_data: - xml_lines.append(f' {custom_data["year"]}') + xml_lines.append(f' {html.escape(custom_data["year"])}') # Add country if available if 'country' in custom_data: - xml_lines.append(f' {custom_data["country"]}') + xml_lines.append(f' {html.escape(custom_data["country"])}') # Add icon if available if 'icon' in custom_data: - xml_lines.append(f' ') + xml_lines.append(f' ') # Add special flags as proper tags if custom_data.get('previously_shown', False): @@ -196,7 +197,7 @@ def generate_epg(request, profile_name=None): xml_lines.append(f' ') except Exception as e: - xml_lines.append(f' ') + xml_lines.append(f' ') xml_lines.append(' ')