diff --git a/app/scodoc/sco_bulletins_pdf.py b/app/scodoc/sco_bulletins_pdf.py index 81df5b1e..b28e9db5 100644 --- a/app/scodoc/sco_bulletins_pdf.py +++ b/app/scodoc/sco_bulletins_pdf.py @@ -51,23 +51,24 @@ Chaque semestre peut si nécessaire utiliser un type de bulletin différent. """ import io -import os import re import time import traceback +from pydoc import html from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate -from flask import g, url_for, request +from flask import g, request import app.scodoc.sco_utils as scu -from app import log +from app import log, ScoValueError from app.scodoc import sco_cache from app.scodoc import sco_formsemestre from app.scodoc import sco_pdf from app.scodoc import sco_preferences from app.scodoc import sco_etud import sco_version +from app.scodoc.sco_logos import find_logo def pdfassemblebulletins( @@ -110,6 +111,17 @@ def pdfassemblebulletins( return data +def replacement_function(match): + balise = match.group(1) + name = match.group(3) + logo = find_logo(logoname=name, dept_id=g.scodoc_dept_id) + if logo is not None: + return r'' % (match.group(2), logo.filepath, match.group(4)) + raise ScoValueError( + 'balise "%s": logo "%s" introuvable' % (html.escape(balise), html.escape(name)) + ) + + def process_field(field, cdict, style, suppress_empty_pars=False, format="pdf"): """Process a field given in preferences, returns - if format = 'pdf': a list of Platypus objects @@ -141,24 +153,18 @@ def process_field(field, cdict, style, suppress_empty_pars=False, format="pdf"): return text # --- PDF format: # handle logos: - image_dir = scu.SCODOC_LOGOS_DIR + "/logos_" + g.scodoc_dept + "/" - if not os.path.exists(image_dir): - image_dir = scu.SCODOC_LOGOS_DIR + "/" # use global logos - if not os.path.exists(image_dir): - log(f"Warning: missing global logo directory ({image_dir})") - image_dir = None - text = re.sub( r"<(\s*)logo(.*?)src\s*=\s*(.*?)>", r"<\1logo\2\3>", text ) # remove forbidden src attribute - if image_dir is not None: - text = re.sub( - r'<\s*logo(.*?)name\s*=\s*"(\w*?)"(.*?)/?>', - r'' % image_dir, - text, - ) - # nota: le match sur \w*? donne le nom du logo et interdit les .. et autres - # tentatives d'acceder à d'autres fichiers ! + text = re.sub( + r'(<\s*logo(.*?)name\s*=\s*"(\w*?)"(.*?)/?>)', + replacement_function, + text, + ) + # nota: le match sur \w*? donne le nom du logo et interdit les .. et autres + # tentatives d'acceder à d'autres fichiers ! + # la protection contre des noms malveillants est aussi assurée par l'utilisation de + # secure_filename dans la classe Logo # log('field: %s' % (text)) return sco_pdf.makeParas(text, style, suppress_empty=suppress_empty_pars)