This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Wikibase\View\Tests; |
||
4 | |||
5 | use HamcrestPHPUnitIntegration; |
||
6 | use Wikibase\DataModel\Entity\EntityId; |
||
7 | use Wikibase\DataModel\Entity\ItemId; |
||
8 | use Wikibase\DataModel\Services\Lookup\LabelDescriptionLookup; |
||
9 | use Wikibase\DataModel\Term\AliasGroup; |
||
10 | use Wikibase\DataModel\Term\AliasGroupList; |
||
11 | use Wikibase\DataModel\Term\Term; |
||
12 | use Wikibase\DataModel\Term\TermList; |
||
13 | use Wikibase\View\DummyLocalizedTextProvider; |
||
14 | use Wikibase\View\EditSectionGenerator; |
||
15 | use Wikibase\View\HtmlTermRenderer; |
||
16 | use Wikibase\View\SimpleEntityTermsView; |
||
17 | use Wikibase\View\Template\TemplateFactory; |
||
18 | use Wikibase\View\TermsListView; |
||
19 | |||
20 | /** |
||
21 | * @covers \Wikibase\View\SimpleEntityTermsView |
||
22 | * |
||
23 | * @uses Wikibase\View\Template\Template |
||
24 | * @uses Wikibase\View\Template\TemplateFactory |
||
25 | * @uses Wikibase\View\Template\TemplateRegistry |
||
26 | * @uses Wikibase\View\TermsListView |
||
27 | * |
||
28 | * @group Wikibase |
||
29 | * @group WikibaseView |
||
30 | * |
||
31 | * @license GPL-2.0-or-later |
||
32 | * @author Bene* < [email protected] > |
||
33 | * @author Thiemo Kreuz |
||
34 | */ |
||
35 | class SimpleEntityTermsViewTest extends \PHPUnit\Framework\TestCase { |
||
36 | use HamcrestPHPUnitIntegration; |
||
37 | |||
38 | private function getEntityTermsView( $editSectionCalls = 0, TermsListView $termsListView = null ) { |
||
39 | $editSectionGenerator = $this->createMock( EditSectionGenerator::class ); |
||
40 | $editSectionGenerator->expects( $this->exactly( $editSectionCalls ) ) |
||
41 | ->method( 'getLabelDescriptionAliasesEditSection' ) |
||
42 | ->will( $this->returnValue( '<EDITSECTION>' ) ); |
||
43 | |||
44 | $textProvider = new DummyLocalizedTextProvider( 'lkt' ); |
||
0 ignored issues
–
show
|
|||
45 | |||
46 | $termsListView = $termsListView ?: $this->getMockBuilder( TermsListView::class ) |
||
47 | ->disableOriginalConstructor() |
||
48 | ->getMock(); |
||
49 | |||
50 | $htmlTermRenderer = $this->createMock( HtmlTermRenderer::class ); |
||
51 | $htmlTermRenderer->method( 'renderTerm' ) |
||
52 | ->will( $this->returnCallback( function( Term $term ) { |
||
53 | return htmlspecialchars( $term->getText() ); |
||
54 | } ) ); |
||
55 | |||
56 | $labelDescriptionLookup = $this->createMock( LabelDescriptionLookup::class ); |
||
57 | $labelDescriptionLookup->method( 'getLabel' ) |
||
58 | ->will( $this->returnCallback( function( EntityId $entityId ) { |
||
59 | $terms = [ |
||
60 | 'Q111' => new Term( 'language', '<LABEL>' ), |
||
61 | 'Q666' => new Term( 'language', '<a href="#">evil html</a>' ), |
||
62 | ]; |
||
63 | return $terms[$entityId->getSerialization()] ?? null; |
||
64 | } ) ); |
||
65 | $labelDescriptionLookup->method( 'getDescription' ) |
||
66 | ->will( $this->returnCallback( function( EntityId $entityId ) { |
||
67 | return $entityId->getSerialization() === 'Q111' ? new Term( 'language', '<DESCRIPTION>' ) : null; |
||
68 | } ) ); |
||
69 | |||
70 | return new SimpleEntityTermsView( |
||
71 | $htmlTermRenderer, |
||
72 | $labelDescriptionLookup, |
||
73 | TemplateFactory::getDefaultInstance(), |
||
74 | $editSectionGenerator, |
||
75 | $termsListView, |
||
76 | $textProvider |
||
77 | ); |
||
78 | } |
||
79 | |||
80 | private function getTermList( $term, $languageCode = 'en' ) { |
||
81 | return new TermList( [ new Term( $languageCode, $term ) ] ); |
||
82 | } |
||
83 | |||
84 | private function getAliasGroupList( array $aliases, $languageCode = 'en' ) { |
||
85 | return new AliasGroupList( [ new AliasGroup( $languageCode, $aliases ) ] ); |
||
86 | } |
||
87 | |||
88 | public function testGetHtml_containsAliases() { |
||
89 | $alias1 = '<ALIAS1>'; |
||
90 | $alias2 = '<ALIAS2>'; |
||
91 | $entityTermsView = $this->getEntityTermsView( 1 ); |
||
92 | $aliasGroups = $this->getAliasGroupList( [ $alias1, $alias2 ] ); |
||
93 | $html = $entityTermsView->getHtml( 'en', new TermList(), new TermList(), $aliasGroups, null ); |
||
94 | |||
95 | $matchingAliasMarkup = tagMatchingOutline( |
||
96 | '<li class="wikibase-entitytermsview-aliases-alias" data-aliases-separator="(wikibase-aliases-separator)">' |
||
97 | ); |
||
98 | $this->assertThatHamcrest( $html, is( htmlPiece( |
||
99 | both( havingChild( both( $matchingAliasMarkup )->andAlso( havingTextContents( $alias1 ) ) ) ) |
||
100 | ->andAlso( |
||
101 | havingChild( both( $matchingAliasMarkup )->andAlso( havingTextContents( $alias2 ) ) ) |
||
102 | ) |
||
103 | ) ) ); |
||
104 | } |
||
105 | |||
106 | public function entityFingerprintProvider() { |
||
107 | $labels = $this->getTermList( '<LABEL>' ); |
||
108 | $descriptions = $this->getTermList( '<DESCRIPTION>' ); |
||
109 | $emptyAliases = new AliasGroupList(); |
||
110 | |||
111 | return [ |
||
112 | 'empty' => [ new TermList(), new TermList(), $emptyAliases, new ItemId( 'Q42' ), 'en' ], |
||
113 | 'other language' => [ $labels, $descriptions, $emptyAliases, new ItemId( 'Q42' ), 'de' ], |
||
114 | 'other id' => [ $labels, $descriptions, $emptyAliases, new ItemId( 'Q12' ), 'en' ], |
||
115 | ]; |
||
116 | } |
||
117 | |||
118 | /** |
||
119 | * @dataProvider entityFingerprintProvider |
||
120 | */ |
||
121 | public function testGetHtml_isEditable( |
||
122 | TermList $labels, |
||
123 | TermList $descriptions, |
||
124 | AliasGroupList $aliasGroups, |
||
125 | ItemId $entityId, |
||
126 | $languageCode |
||
127 | ) { |
||
128 | $entityTermsView = $this->getEntityTermsView( 1 ); |
||
129 | $html = $entityTermsView->getHtml( $languageCode, $labels, $descriptions, $aliasGroups, $entityId ); |
||
130 | |||
131 | $this->assertStringContainsString( '<EDITSECTION>', $html ); |
||
132 | } |
||
133 | |||
134 | public function testGetHtml_valuesAreEscaped() { |
||
135 | $descriptions = $this->getTermList( '<script>alert( "xss" );</script>' ); |
||
136 | $aliasGroups = $this->getAliasGroupList( [ '<a href="#">evil html</a>', '<b>bold</b>', '<i>italic</i>' ] ); |
||
137 | |||
138 | $view = $this->getEntityTermsView( 1 ); |
||
139 | $html = $view->getHtml( 'en', new TermList(), $descriptions, $aliasGroups, null ); |
||
140 | |||
141 | $this->assertStringContainsString( 'evil html', $html, 'make sure it works' ); |
||
142 | $this->assertStringNotContainsString( 'href="#"', $html ); |
||
143 | $this->assertStringNotContainsString( '<script>', $html ); |
||
144 | $this->assertStringNotContainsString( '<b>', $html ); |
||
145 | $this->assertStringNotContainsString( '<i>', $html ); |
||
146 | $this->assertStringNotContainsString( '&', $html, 'no double escaping' ); |
||
147 | } |
||
148 | |||
149 | public function testGetHtml_isMarkedAsEmptyValue() { |
||
150 | $view = $this->getEntityTermsView( 1 ); |
||
151 | $html = $view->getHtml( 'en', new TermList(), new TermList() ); |
||
152 | |||
153 | $this->assertStringContainsString( 'wb-empty', $html ); |
||
154 | $this->assertStringContainsString( '(wikibase-description-empty)', $html ); |
||
155 | $this->assertStringNotContainsString( 'wikibase-entitytermsview-heading-aliases', $html ); |
||
156 | } |
||
157 | |||
158 | public function testGetHtml_isNotMarkedAsEmpty() { |
||
159 | $entityTermsView = $this->getEntityTermsView( 1 ); |
||
160 | $terms = $this->getTermList( 'not empty' ); |
||
161 | $aliasGroups = $this->getAliasGroupList( [ 'not empty' ] ); |
||
162 | $html = $entityTermsView->getHtml( 'en', $terms, $terms, $aliasGroups, new ItemId( 'Q111' ) ); |
||
163 | |||
164 | $this->assertStringNotContainsString( 'wb-empty', $html ); |
||
165 | $this->assertStringNotContainsString( '(wikibase-description-empty)', $html ); |
||
166 | $this->assertStringContainsString( 'wikibase-entitytermsview-aliases', $html ); |
||
167 | } |
||
168 | |||
169 | public function testGetHtml_containsEmptyDescriptionPlaceholder() { |
||
170 | $view = $this->getEntityTermsView( 1 ); |
||
171 | $labels = $this->getTermList( 'not empty' ); |
||
172 | $descriptions = new TermList(); |
||
173 | $aliasGroups = $this->getAliasGroupList( [ 'not empty' ] ); |
||
174 | $html = $view->getHtml( 'en', $labels, $descriptions, $aliasGroups, null ); |
||
175 | |||
176 | $this->assertStringContainsString( 'wb-empty', $html ); |
||
177 | $this->assertStringContainsString( '(wikibase-description-empty)', $html ); |
||
178 | $this->assertStringContainsString( 'wikibase-entitytermsview-aliases', $html ); |
||
179 | } |
||
180 | |||
181 | public function testGetHtml_containsEmptyAliasesList() { |
||
182 | $view = $this->getEntityTermsView( 1 ); |
||
183 | $html = $view->getHtml( 'en', new TermList(), new TermList(), new AliasGroupList() ); |
||
184 | |||
185 | $this->assertStringContainsString( '<div class="wikibase-entitytermsview-heading-aliases wb-empty"></div>', $html ); |
||
186 | } |
||
187 | |||
188 | /** |
||
189 | * @dataProvider entityFingerprintProvider |
||
190 | */ |
||
191 | public function testGetHtml_containsAllTerms( |
||
192 | TermList $labels, |
||
193 | TermList $descriptions, |
||
194 | AliasGroupList $aliases, |
||
195 | ItemId $entityId, |
||
196 | $languageCode |
||
197 | ) { |
||
198 | $termsListView = $this->getMockBuilder( TermsListView::class ) |
||
199 | ->disableOriginalConstructor() |
||
200 | ->getMock(); |
||
201 | $termsListView->expects( $this->once() ) |
||
202 | ->method( 'getHtml' ) |
||
203 | ->with( |
||
204 | $labels, |
||
205 | $descriptions, |
||
206 | $aliases, |
||
207 | $this->equalTo( $languageCode === 'de' ? [ 'de', 'en' ] : [ 'en' ] ) |
||
208 | ) |
||
209 | ->will( $this->returnValue( '<TERMSLISTVIEW>' ) ); |
||
210 | $entityTermsView = $this->getEntityTermsView( 1, $termsListView ); |
||
211 | $html = $entityTermsView->getHtml( $languageCode, $labels, $descriptions, $aliases, $entityId ); |
||
212 | |||
213 | $this->assertStringContainsString( '<TERMSLISTVIEW>', $html ); |
||
214 | } |
||
215 | |||
216 | public function testGetTitleHtml_withEntityId() { |
||
217 | $entityTermsView = $this->getEntityTermsView( 0 ); |
||
218 | $html = $entityTermsView->getTitleHtml( new ItemId( 'Q111' ) ); |
||
219 | |||
220 | $this->assertStringContainsString( '(parentheses: Q111)', $html ); |
||
221 | $this->assertStringContainsString( '<LABEL>', $html ); |
||
222 | } |
||
223 | |||
224 | public function testGetTitleHtml_withoutEntityId() { |
||
225 | $entityTermsView = $this->getEntityTermsView( 0 ); |
||
226 | $html = $entityTermsView->getTitleHtml( null ); |
||
227 | |||
228 | $this->assertStringNotContainsString( '(parentheses', $html ); |
||
229 | $this->assertStringNotContainsString( '<LABEL>', $html ); |
||
230 | } |
||
231 | |||
232 | public function testGetTitleHtml_labelIsEscaped() { |
||
233 | $entityTermsView = $this->getEntityTermsView( 0 ); |
||
234 | $html = $entityTermsView->getTitleHtml( new ItemId( 'Q666' ) ); |
||
235 | |||
236 | $this->assertStringContainsString( 'evil html', $html, 'make sure it works' ); |
||
237 | $this->assertStringNotContainsString( 'href="#"', $html ); |
||
238 | $this->assertStringNotContainsString( '&', $html, 'no double escaping' ); |
||
239 | } |
||
240 | |||
241 | public function testGetTitleHtml_isMarkedAsEmpty() { |
||
242 | $entityTermsView = $this->getEntityTermsView( 0 ); |
||
243 | $html = $entityTermsView->getTitleHtml( null ); |
||
244 | |||
245 | $this->assertStringContainsString( 'wb-empty', $html ); |
||
246 | $this->assertStringContainsString( '(wikibase-label-empty)', $html ); |
||
247 | } |
||
248 | |||
249 | public function testGetTitleHtml_isNotMarkedAsEmpty() { |
||
250 | $entityTermsView = $this->getEntityTermsView( 0 ); |
||
251 | $html = $entityTermsView->getTitleHtml( new ItemId( 'Q111' ) ); |
||
252 | |||
253 | $this->assertStringNotContainsString( 'wb-empty', $html ); |
||
254 | $this->assertStringNotContainsString( '(wikibase-label-empty)', $html ); |
||
255 | } |
||
256 | |||
257 | } |
||
258 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.