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