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 // Remove the default maximum width/height for images. This enables percentage values. 48 $config->set('CSS.MaxImgLength', null); 49 50 $def = $config->getHTMLDefinition(true); 51 52 // Allow link targets. 53 $def->addAttribute('a', 'target', new HTMLPurifier_AttrDef_Enum(['_blank', '_self', '_target', '_top'])); 54 55 // Allow image maps. 56 $def->addAttribute('img', 'usemap', 'CDATA'); 57 58 $map = $def->addElement('map', 'Block', 'Flow', 'Common', [ 59 'name' => 'CDATA', 60 'id' => 'ID', 61 'title' => 'CDATA', 62 ]); 63 64 $map->excludes = ['map' => true]; 65 66 $area = $def->addElement('area', 'Block', 'Empty', 'Common', [ 67 'name' => 'CDATA', 68 'id' => 'ID', 69 'alt' => 'Text', 70 'coords' => 'CDATA', 71 'accesskey' => 'Character', 72 'nohref' => new HTMLPurifier_AttrDef_Enum(['nohref']), 73 'href' => 'URI', 74 'shape' => new HTMLPurifier_AttrDef_Enum(['rect', 'circle', 'poly', 'default']), 75 'tabindex' => 'Number', 76 ]); 77 78 $area->excludes = ['area' => true]; 79 80 $purifier = new HTMLPurifier($config); 81 82 return $purifier->purify($html); 83 } 84} 85