1*b66f5d1aSGreg Roach<?php 2*b66f5d1aSGreg Roach 3*b66f5d1aSGreg Roach/** 4*b66f5d1aSGreg Roach * webtrees: online genealogy 5*b66f5d1aSGreg Roach * Copyright (C) 2023 webtrees development team 6*b66f5d1aSGreg Roach * This program is free software: you can redistribute it and/or modify 7*b66f5d1aSGreg Roach * it under the terms of the GNU General Public License as published by 8*b66f5d1aSGreg Roach * the Free Software Foundation, either version 3 of the License, or 9*b66f5d1aSGreg Roach * (at your option) any later version. 10*b66f5d1aSGreg Roach * This program is distributed in the hope that it will be useful, 11*b66f5d1aSGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 12*b66f5d1aSGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13*b66f5d1aSGreg Roach * GNU General Public License for more details. 14*b66f5d1aSGreg Roach * You should have received a copy of the GNU General Public License 15*b66f5d1aSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>. 16*b66f5d1aSGreg Roach */ 17*b66f5d1aSGreg Roach 18*b66f5d1aSGreg Roachdeclare(strict_types=1); 19*b66f5d1aSGreg Roach 20*b66f5d1aSGreg Roachnamespace Fisharebest\Webtrees\Elements; 21*b66f5d1aSGreg Roach 22*b66f5d1aSGreg Roachuse Fisharebest\Webtrees\Contracts\ElementInterface; 23*b66f5d1aSGreg Roachuse Fisharebest\Webtrees\TestCase; 24*b66f5d1aSGreg Roachuse Fisharebest\Webtrees\Tree; 25*b66f5d1aSGreg Roach 26*b66f5d1aSGreg Roach/** 27*b66f5d1aSGreg Roach * Common tests for ElementInterface 28*b66f5d1aSGreg Roach */ 29*b66f5d1aSGreg Roachabstract class AbstractElementTestCase extends TestCase 30*b66f5d1aSGreg Roach{ 31*b66f5d1aSGreg Roach private const EVIL_VALUE = '<script>evil()</script>'; 32*b66f5d1aSGreg Roach private const TEST_VALUE = '01 JAN 1970'; 33*b66f5d1aSGreg Roach 34*b66f5d1aSGreg Roach protected static ElementInterface $element; 35*b66f5d1aSGreg Roach 36*b66f5d1aSGreg Roach /** 37*b66f5d1aSGreg Roach * @return void 38*b66f5d1aSGreg Roach */ 39*b66f5d1aSGreg Roach public function testCanonical(): void 40*b66f5d1aSGreg Roach { 41*b66f5d1aSGreg Roach self::assertSame('Foo bAr baZ', self::$element->canonical('Foo bAr baZ')); 42*b66f5d1aSGreg Roach self::assertSame('Foo bAr baZ', self::$element->canonical("\t Foo\t bAr \tbaZ\t ")); 43*b66f5d1aSGreg Roach self::assertSame('Foo bAr baZ', self::$element->canonical("\nFoo \n\r bAr \r\n baZ\r")); 44*b66f5d1aSGreg Roach } 45*b66f5d1aSGreg Roach 46*b66f5d1aSGreg Roach /** 47*b66f5d1aSGreg Roach * @return void 48*b66f5d1aSGreg Roach */ 49*b66f5d1aSGreg Roach public function testEscapeAtSigns(): void 50*b66f5d1aSGreg Roach { 51*b66f5d1aSGreg Roach if (static::$element instanceof AbstractXrefElement) { 52*b66f5d1aSGreg Roach self::assertSame('@X123@', static::$element->escape('@X123@')); 53*b66f5d1aSGreg Roach } else { 54*b66f5d1aSGreg Roach self::assertSame('@@X123@@', static::$element->escape('@X123@')); 55*b66f5d1aSGreg Roach } 56*b66f5d1aSGreg Roach } 57*b66f5d1aSGreg Roach 58*b66f5d1aSGreg Roach /** 59*b66f5d1aSGreg Roach * @return void 60*b66f5d1aSGreg Roach */ 61*b66f5d1aSGreg Roach public function testXssInValue(): void 62*b66f5d1aSGreg Roach { 63*b66f5d1aSGreg Roach $tree = $this->createMock(Tree::class); 64*b66f5d1aSGreg Roach $html = static::$element->value(self::EVIL_VALUE, $tree); 65*b66f5d1aSGreg Roach $message = 'XSS vulnerability in value()'; 66*b66f5d1aSGreg Roach 67*b66f5d1aSGreg Roach self::assertStringNotContainsStringIgnoringCase(self::EVIL_VALUE, $html, $message); 68*b66f5d1aSGreg Roach } 69*b66f5d1aSGreg Roach 70*b66f5d1aSGreg Roach /** 71*b66f5d1aSGreg Roach * @return void 72*b66f5d1aSGreg Roach */ 73*b66f5d1aSGreg Roach public function testXssInLabelValue(): void 74*b66f5d1aSGreg Roach { 75*b66f5d1aSGreg Roach $tree = $this->createMock(Tree::class); 76*b66f5d1aSGreg Roach $html = static::$element->labelValue(self::EVIL_VALUE, $tree); 77*b66f5d1aSGreg Roach $message = 'XSS vulnerability in labelValue()'; 78*b66f5d1aSGreg Roach 79*b66f5d1aSGreg Roach self::assertStringNotContainsStringIgnoringCase(self::EVIL_VALUE, $html, $message); 80*b66f5d1aSGreg Roach } 81*b66f5d1aSGreg Roach 82*b66f5d1aSGreg Roach /** 83*b66f5d1aSGreg Roach * @return void 84*b66f5d1aSGreg Roach */ 85*b66f5d1aSGreg Roach public function testXssInEdit(): void 86*b66f5d1aSGreg Roach { 87*b66f5d1aSGreg Roach $tree = $this->createMock(Tree::class); 88*b66f5d1aSGreg Roach $html = static::$element->edit('id', 'name', self::EVIL_VALUE, $tree); 89*b66f5d1aSGreg Roach $message = 'XSS vulnerability in edit()'; 90*b66f5d1aSGreg Roach 91*b66f5d1aSGreg Roach self::assertStringNotContainsStringIgnoringCase(self::EVIL_VALUE, $html, $message); 92*b66f5d1aSGreg Roach } 93*b66f5d1aSGreg Roach 94*b66f5d1aSGreg Roach /** 95*b66f5d1aSGreg Roach * @return void 96*b66f5d1aSGreg Roach */ 97*b66f5d1aSGreg Roach public function testValidHtmlInValue(): void 98*b66f5d1aSGreg Roach { 99*b66f5d1aSGreg Roach $tree = $this->createMock(Tree::class); 100*b66f5d1aSGreg Roach $html = static::$element->value(self::TEST_VALUE, $tree); 101*b66f5d1aSGreg Roach 102*b66f5d1aSGreg Roach $this->validateHtml($html); 103*b66f5d1aSGreg Roach } 104*b66f5d1aSGreg Roach 105*b66f5d1aSGreg Roach /** 106*b66f5d1aSGreg Roach * @return void 107*b66f5d1aSGreg Roach */ 108*b66f5d1aSGreg Roach public function testValidHtmlInEdit(): void 109*b66f5d1aSGreg Roach { 110*b66f5d1aSGreg Roach $tree = $this->createMock(Tree::class); 111*b66f5d1aSGreg Roach $html = static::$element->edit('id', 'name', self::TEST_VALUE, $tree); 112*b66f5d1aSGreg Roach 113*b66f5d1aSGreg Roach $this->validateHtml($html); 114*b66f5d1aSGreg Roach } 115*b66f5d1aSGreg Roach} 116