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 */ 17declare(strict_types=1); 18 19namespace Fisharebest\Webtrees\Services; 20 21use HTMLPurifier; 22use HTMLPurifier_AttrDef_Enum; 23use HTMLPurifier_Config; 24 25/** 26 * Filter/sanitize HTML 27 */ 28class HtmlService 29{ 30 /** 31 * Take some dirty HTML (as provided by the user), and clean it before 32 * we save/display it. 33 * 34 * @param string $html 35 * 36 * @return string 37 */ 38 public function sanitize(string $html): string 39 { 40 $config = HTMLPurifier_Config::createDefault(); 41 42 $config->set('Cache.DefinitionImpl', null); 43 44 $config->set('HTML.TidyLevel', 'none'); // Only XSS cleaning now 45 46 $def = $config->getHTMLDefinition(true); 47 48 // Allow image maps. 49 $def->addAttribute('img', 'usemap', 'CDATA'); 50 51 // Allow link targets. 52 $def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(['_blank', '_self', '_target', '_top'])); 53 54 $map = $def->addElement('map', 'Block', 'Flow', 'Common', [ 55 'name' => 'CDATA', 56 'id' => 'ID', 57 'title' => 'CDATA', 58 ]); 59 60 $map->excludes = ['map' => true]; 61 62 $area = $def->addElement('area', 'Block', 'Empty', 'Common', [ 63 'name' => 'CDATA', 64 'id' => 'ID', 65 'alt' => 'Text', 66 'coords' => 'CDATA', 67 'accesskey' => 'Character', 68 'nohref' => new HTMLPurifier_AttrDef_Enum(['nohref']), 69 'href' => 'URI', 70 'shape' => new HTMLPurifier_AttrDef_Enum(['rect', 'circle', 'poly', 'default']), 71 'tabindex' => 'Number', 72 ]); 73 74 $area->excludes = ['area' => true]; 75 76 $purifier = new HTMLPurifier($config); 77 78 return $purifier->purify($html); 79 } 80} 81