1<?php 2 3/** 4 * webtrees: online genealogy 5 * Copyright (C) 2019 webtrees development team 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18declare(strict_types=1); 19 20namespace Fisharebest\Webtrees\Services; 21 22use HTMLPurifier; 23use HTMLPurifier_AttrDef_Enum; 24use HTMLPurifier_Config; 25 26/** 27 * Filter/sanitize HTML 28 */ 29class HtmlService 30{ 31 /** 32 * Take some dirty HTML (as provided by the user), and clean it before 33 * we save/display it. 34 * 35 * @param string $html 36 * 37 * @return string 38 */ 39 public function sanitize(string $html): string 40 { 41 $config = HTMLPurifier_Config::createDefault(); 42 43 $config->set('Cache.DefinitionImpl', null); 44 45 $config->set('HTML.TidyLevel', 'none'); // Only XSS cleaning now 46 47 $def = $config->getHTMLDefinition(true); 48 49 // Allow image maps. 50 $def->addAttribute('img', 'usemap', 'CDATA'); 51 52 // Allow link targets. 53 $def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(['_blank', '_self', '_target', '_top'])); 54 55 $map = $def->addElement('map', 'Block', 'Flow', 'Common', [ 56 'name' => 'CDATA', 57 'id' => 'ID', 58 'title' => 'CDATA', 59 ]); 60 61 $map->excludes = ['map' => true]; 62 63 $area = $def->addElement('area', 'Block', 'Empty', 'Common', [ 64 'name' => 'CDATA', 65 'id' => 'ID', 66 'alt' => 'Text', 67 'coords' => 'CDATA', 68 'accesskey' => 'Character', 69 'nohref' => new HTMLPurifier_AttrDef_Enum(['nohref']), 70 'href' => 'URI', 71 'shape' => new HTMLPurifier_AttrDef_Enum(['rect', 'circle', 'poly', 'default']), 72 'tabindex' => 'Number', 73 ]); 74 75 $area->excludes = ['area' => true]; 76 77 $purifier = new HTMLPurifier($config); 78 79 return $purifier->purify($html); 80 } 81} 82