Skip to content
This repository has been archived by the owner on Jan 31, 2020. It is now read-only.

Commit

Permalink
Merge branch 'security/zf2014-03'
Browse files Browse the repository at this point in the history
ZF2014-03 fixes
  • Loading branch information
weierophinney committed Apr 15, 2014
164 parents b273593 + 7b4d532 + f3d9b3a + f7ab865 + d9d9b78 + fefc773 + 83cbc8a + 1b9fd60 + 8a8b989 + 10da323 + e6aba5a + b71d0a2 + 2aa926c + 8405746 + bf1a8de + f16339d + ed1dbc8 + dbf56da + bdb277e + 364ced3 + 9fccdf3 + 40f5963 + 9d7ddea + e1e4aa8 + 870703b + 958decf + e49a08e + a051e7e + b9f6e35 + 2bbef72 + aea30ce + faec0a2 + 098e166 + 51d6372 + 8757ace + 42477b6 + 32cf329 + 0ebadc5 + 188fa4d + a41bbf0 + a29bbbc + 941280d + d691226 + e547023 + d91c234 + 006ef75 + 69d1518 + 7dc0d1a + a995715 + e780008 + e810876 + 9e4090a + 269bf01 + 3a1f2fd + 0cab32d + 704cc7f + e20c9e6 + a0dfc1a + 76b3e1c + fd429e8 + 187ea79 + 2b43ea6 + e3b1be1 + 19f0ef6 + 33bf9c0 + 3729984 + a5ce396 + 698dbe0 + 0efca0b + 08b2a78 + ddaa846 + 7fe4493 + 0da7331 + 7226b1d + 851904c + a2eb795 + f658a03 + de83270 + 806df8a + 4e7ff23 + 409b768 + 1b97191 + d2649e3 + f0162d1 + 6f01416 + a2b3753 + 1786961 + d157fcb + 4444c37 + 192d20c + 811122b + 3a2cf9b + eb2029b + 7a6edab + 8d8a05d + c1ddf21 + 0090b4d + ef80e35 + 59b30de + 4656098 + 377b920 + ccba82c + 5d2770e + 41714a1 + 8adef43 + a78628f + b35fa7a + 3953c79 + aa28e42 + 38f9a49 + 47ed633 + 0a6bf6e + b61d89d + a1fbb6f + 238512b + f40a328 + 62dc143 + 328df3b + e12fe2d + e34a942 + 04e956d + a19a8c2 + ac4b6c0 + d28282e + bd5af3d + b976cb5 + 4feb67b + 7164be7 + 40174df + e4918ae + 1d9f9a2 + c77ae57 + 223b881 + c2f4e25 + e08b166 + e58e548 + 85e6bbd + 0ac2052 + c7ba6af + f443c57 + 1380626 + 5316b6e + a6136d4 + d233be3 + c100a2a + c6a0e2c + e7eef3c + 812f35d + 604cdcd + 5472285 + 6e2f420 + 76c4d1c + c60cca9 + 77f718e + 6bc8c90 + 6ec1d0f + 53d9070 + a67cdeb + 5d412ee + 132380c + 2809ef0 + a883a8d + 4aa93a8 + 8e9a467 commit 274ca2b
Show file tree
Hide file tree
Showing 34 changed files with 289 additions and 236 deletions.
13 changes: 5 additions & 8 deletions src/Helper/AbstractHtmlElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ protected function isXhtml()
*/
protected function htmlAttribs($attribs)
{
$xhtml = '';
$escaper = $this->getView()->plugin('escapehtml');
$xhtml = '';
$escaper = $this->getView()->plugin('escapehtml');
$escapeHtmlAttr = $this->getView()->plugin('escapehtmlattr');

foreach ((array) $attribs as $key => $val) {
$key = $escaper($key);
Expand All @@ -77,18 +78,14 @@ protected function htmlAttribs($attribs)
// non-scalar data should be cast to JSON first
$val = \Zend\Json\Json::encode($val);
}
// Escape single quotes inside event attribute values.
// This will create html, where the attribute value has
// single quotes around it, and escaped single quotes or
// non-escaped double quotes inside of it
$val = str_replace('\'', ''', $val);
} else {
if (is_array($val)) {
$val = implode(' ', $val);
}
$val = $escaper($val);
}

$val = $escapeHtmlAttr($val);

if ('id' == $key) {
$val = $this->normalizeId($val);
}
Expand Down
13 changes: 9 additions & 4 deletions src/Helper/Navigation/Menu.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,9 @@ protected function renderDeepestMenu(
$active['page'] = $active['page']->getParent();
}

$ulClass = $ulClass ? ' class="' . $ulClass . '"' : '';
/* @var $escaper \Zend\View\Helper\EscapeHtmlAttr */
$escaper = $this->view->plugin('escapeHtmlAttr');
$ulClass = $ulClass ? ' class="' . $escaper($ulClass) . '"' : '';
$html = $indent . '<ul' . $ulClass . '>' . PHP_EOL;

foreach ($active['page'] as $subPage) {
Expand All @@ -170,7 +172,7 @@ protected function renderDeepestMenu(
if ($addClassToListItem && $subPage->getClass()) {
$liClasses[] = $subPage->getClass();
}
$liClass = empty($liClasses) ? '' : ' class="' . implode(' ', $liClasses) . '"';
$liClass = empty($liClasses) ? '' : ' class="' . $escaper(implode(' ', $liClasses)) . '"';

$html .= $indent . ' <li' . $liClass . '>' . PHP_EOL;
$html .= $indent . ' ' . $this->htmlify($subPage, $escapeLabels, $addClassToListItem) . PHP_EOL;
Expand Down Expand Up @@ -262,6 +264,9 @@ protected function renderNormalMenu(

// find deepest active
$found = $this->findActive($container, $minDepth, $maxDepth);
/* @var $escaper \Zend\View\Helper\EscapeHtmlAttr */
$escaper = $this->view->plugin('escapeHtmlAttr');

if ($found) {
$foundPage = $found['page'];
$foundDepth = $found['depth'];
Expand Down Expand Up @@ -314,7 +319,7 @@ protected function renderNormalMenu(
if ($depth > $prevDepth) {
// start new ul tag
if ($ulClass && $depth == 0) {
$ulClass = ' class="' . $ulClass . '"';
$ulClass = ' class="' . $escaper($ulClass) . '"';
} else {
$ulClass = '';
}
Expand Down Expand Up @@ -343,7 +348,7 @@ protected function renderNormalMenu(
if ($addClassToListItem && $page->getClass()) {
$liClasses[] = $page->getClass();
}
$liClass = empty($liClasses) ? '' : ' class="' . implode(' ', $liClasses) . '"';
$liClass = empty($liClasses) ? '' : ' class="' . $escaper(implode(' ', $liClasses)) . '"';

$html .= $myIndent . ' <li' . $liClass . '>' . PHP_EOL
. $myIndent . ' ' . $this->htmlify($page, $escapeLabels, $addClassToListItem) . PHP_EOL;
Expand Down
51 changes: 51 additions & 0 deletions test/Helper/AbstractHtmlElementTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace ZendTest\View\Helper;

use PHPUnit_Framework_TestCase as TestCase;
use Zend\View\Renderer\PhpRenderer;

/**
* Tests for {@see \Zend\View\Helper\AbstractHtmlElement}
*
* @covers \Zend\View\Helper\AbstractHtmlElement
*/
class AbstractHtmlElementTest extends TestCase
{
/**
* @var \Zend\View\Helper\AbstractHtmlElement|\PHPUnit_Framework_MockObject_MockObject
*/
protected $helper;

/**
* {@inheritDoc}
*/
public function setUp()
{
$this->helper = $this->getMockForAbstractClass('Zend\View\Helper\AbstractHtmlElement');

$this->helper->setView(new PhpRenderer());
}

/**
* @group 5991
*/
public function testWillEscapeValueAttributeValuesCorrectly()
{
$reflectionMethod = new \ReflectionMethod($this->helper, 'htmlAttribs');

$reflectionMethod->setAccessible(true);

$this->assertSame(
' data-value="breaking&#x20;your&#x20;HTML&#x20;like&#x20;a&#x20;boss&#x21;&#x20;&#x5C;"',
$reflectionMethod->invoke($this->helper, array('data-value' => 'breaking your HTML like a boss! \\'))
);
}
}
12 changes: 6 additions & 6 deletions test/Helper/GravatarTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public function testSetSecure()
public function testHttpsSource()
{
$this->assertRegExp(
'#src="https://secure.gravatar.com/avatar/[a-z0-9]{32}.+"#',
'#src="https\&\#x3A\;\&\#x2F\;\&\#x2F\;secure.gravatar.com\&\#x2F\;avatar\&\#x2F\;[a-z0-9]{32}.+"#',
$this->helper->__invoke("example@example.com", array('secure' => true))->__toString()
);
}
Expand All @@ -179,7 +179,7 @@ public function testImgAttribs()
public function testGravatarOptions()
{
$this->assertRegExp(
'#src="http://www.gravatar.com/avatar/[a-z0-9]{32}\?s=125&amp;d=wavatar&amp;r=pg"#',
'#src="http\&\#x3A\;\&\#x2F\;\&\#x2F\;www.gravatar.com\&\#x2F\;avatar\&\#x2F\;[a-z0-9]{32}&\#x3F;s&\#x3D;125&amp;d&\#x3D;wavatar&amp;r&\#x3D;pg"#',
$this->helper->__invoke("example@example.com", array('rating' => 'pg', 'imgSize' => 125, 'defaultImg' => 'wavatar', 'secure' => false))->__toString()
);
}
Expand Down Expand Up @@ -207,7 +207,7 @@ public function testAutoDetectLocation()
foreach ($values as $value) {
$_SERVER['HTTPS'] = $value;
$this->assertRegExp(
'#src="https://secure.gravatar.com/avatar/[a-z0-9]{32}.+"#',
'#src="https\&\#x3A\;\&\#x2F\;\&\#x2F\;secure.gravatar.com\&\#x2F\;avatar\&\#x2F\;[a-z0-9]{32}.+"#',
$this->helper->__invoke("example@example.com")->__toString()
);
}
Expand All @@ -221,7 +221,7 @@ public function testAutoDetectLocationOnIis()
$_SERVER['HTTPS'] = "off";

$this->assertRegExp(
'/src="http:\/\/www.gravatar.com\/avatar\/[a-z0-9]{32}.+"/',
'/src="http\&\#x3A\;\&\#x2F\;\&\#x2F\;www.gravatar.com\&\#x2F\;avatar\&\#x2F\;[a-z0-9]{32}.+"/',
$this->helper->__invoke("example@example.com")->__toString()
);
}
Expand All @@ -237,15 +237,15 @@ public function testSetAttribsWithSrcKey()
));

$this->assertRegExp(
'#src="http://www.gravatar.com/avatar/[a-z0-9]{32}.+"#',
'#src="http\&\#x3A\;\&\#x2F\;\&\#x2F\;www.gravatar.com\&\#x2F\;avatar\&\#x2F\;[a-z0-9]{32}.+"#',
$this->helper->getImgTag()
);
}

public function testForgottenEmailParameter()
{
$this->assertRegExp(
'#(src="http://www.gravatar.com/avatar/[a-z0-9]{32}.+")#',
'#(src="http\&\#x3A\;\&\#x2F\;\&\#x2F\;www.gravatar.com\&\#x2F\;avatar\&\#x2F\;[a-z0-9]{32}.+")#',
$this->helper->getImgTag()
);
}
Expand Down
2 changes: 1 addition & 1 deletion test/Helper/HtmlFlashTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public function testMakeHtmlFlash()
{
$htmlFlash = $this->helper->__invoke('/path/to/flash.swf');

$objectStartElement = '<object data="/path/to/flash.swf" type="application/x-shockwave-flash">';
$objectStartElement = '<object data="&#x2F;path&#x2F;to&#x2F;flash.swf" type="application&#x2F;x-shockwave-flash">';

$this->assertContains($objectStartElement, $htmlFlash);
$this->assertContains('</object>', $htmlFlash);
Expand Down
6 changes: 3 additions & 3 deletions test/Helper/HtmlPageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ public function testMakeHtmlPage()
{
$htmlPage = $this->helper->__invoke('/path/to/page.html');

$objectStartElement = '<object data="/path/to/page.html"'
. ' type="text/html"'
. ' classid="clsid:25336920-03F9-11CF-8FD0-00AA00686F13">';
$objectStartElement = '<object data="&#x2F;path&#x2F;to&#x2F;page.html"'
. ' type="text&#x2F;html"'
. ' classid="clsid&#x3A;25336920-03F9-11CF-8FD0-00AA00686F13">';

$this->assertContains($objectStartElement, $htmlPage);
$this->assertContains('</object>', $htmlPage);
Expand Down
8 changes: 4 additions & 4 deletions test/Helper/HtmlQuicktimeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ public function testMakeHtmlQuicktime()
{
$htmlQuicktime = $this->helper->__invoke('/path/to/quicktime.mov');

$objectStartElement = '<object data="/path/to/quicktime.mov"'
. ' type="video/quicktime"'
. ' classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"'
. ' codebase="http://www.apple.com/qtactivex/qtplugin.cab">';
$objectStartElement = '<object data="&#x2F;path&#x2F;to&#x2F;quicktime.mov"'
. ' type="video&#x2F;quicktime"'
. ' classid="clsid&#x3A;02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"'
. ' codebase="http&#x3A;&#x2F;&#x2F;www.apple.com&#x2F;qtactivex&#x2F;qtplugin.cab">';

$this->assertContains($objectStartElement, $htmlQuicktime);
$this->assertContains('</object>', $htmlQuicktime);
Expand Down
14 changes: 7 additions & 7 deletions test/Helper/Navigation/LinksTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -637,10 +637,10 @@ public function testSingleRenderFlags()
$this->_helper->setRenderFlag($newFlag);
$expectedOutput = '<link '
. 'rel="' . $type . '" '
. 'href="http://www.example.com/">' . constant($this->_helperName.'::EOL')
. 'href="http&#x3A;&#x2F;&#x2F;www.example.com&#x2F;">' . constant($this->_helperName.'::EOL')
. '<link '
. 'rev="' . $type . '" '
. 'href="http://www.example.com/">';
. 'href="http&#x3A;&#x2F;&#x2F;www.example.com&#x2F;">';
$actualOutput = $this->_helper->render();

$expected[$type] = $expectedOutput;
Expand All @@ -663,9 +663,9 @@ public function testRenderFlagBitwiseOr()
$active->active = true;

// test data
$expected = '<link rel="next" href="page2" title="Page 2">'
$expected = '<link rel="next" href="page2" title="Page&#x20;2">'
. constant($this->_helperName.'::EOL')
. '<link rel="prev" href="page1" title="Page 1">';
. '<link rel="prev" href="page1" title="Page&#x20;1">';
$actual = $this->_helper->render();

$this->assertEquals($expected, $actual);
Expand All @@ -681,9 +681,9 @@ public function testIndenting()
$active->active = true;

// build expected and actual result
$expected = ' <link rel="next" href="page2" title="Page 2">'
$expected = ' <link rel="next" href="page2" title="Page&#x20;2">'
. constant($this->_helperName.'::EOL')
. ' <link rel="prev" href="page1" title="Page 1">';
. ' <link rel="prev" href="page1" title="Page&#x20;1">';
$actual = $this->_helper->render();

$this->assertEquals($expected, $actual);
Expand All @@ -695,7 +695,7 @@ public function testSetMaxDepth()
$this->_helper->findOneByLabel('Page 2.3.3')->setActive(); // level 2
$flag = Navigation\Links::RENDER_NEXT;

$expected = '<link rel="next" href="page2/page2_3/page2_3_1" title="Page 2.3.1">';
$expected = '<link rel="next" href="page2&#x2F;page2_3&#x2F;page2_3_1" title="Page&#x20;2.3.1">';
$actual = $this->_helper->setRenderFlag($flag)->render();

$this->assertEquals($expected, $actual);
Expand Down
2 changes: 1 addition & 1 deletion test/Helper/Navigation/_files/expected/bc/acl.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<a href="page2">Page 2</a> &gt; <a href="page2/page2_2">Page 2.2</a> &gt; Page 2.2.2
<a href="page2">Page 2</a> &gt; <a href="page2&#x2F;page2_2">Page 2.2</a> &gt; Page 2.2.2
2 changes: 1 addition & 1 deletion test/Helper/Navigation/_files/expected/bc/default.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<a href="page2">Page 2</a> &gt; <a href="page2/page2_3">Page 2.3</a> &gt; <a href="page2/page2_3/page2_3_3">Page 2.3.3</a> &gt; Page 2.3.3.1
<a href="page2">Page 2</a> &gt; <a href="page2&#x2F;page2_3">Page 2.3</a> &gt; <a href="page2&#x2F;page2_3&#x2F;page2_3_3">Page 2.3.3</a> &gt; Page 2.3.3.1
2 changes: 1 addition & 1 deletion test/Helper/Navigation/_files/expected/bc/linklast.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<a href="page2">Page 2</a> &gt; <a href="page2/page2_3">Page 2.3</a> &gt; <a href="page2/page2_3/page2_3_3">Page 2.3.3</a> &gt; <a href="page2/page2_3/page2_3_3/1">Page 2.3.3.1</a>
<a href="page2">Page 2</a> &gt; <a href="page2&#x2F;page2_3">Page 2.3</a> &gt; <a href="page2&#x2F;page2_3&#x2F;page2_3_3">Page 2.3.3</a> &gt; <a href="page2&#x2F;page2_3&#x2F;page2_3_3&#x2F;1">Page 2.3.3.1</a>
2 changes: 1 addition & 1 deletion test/Helper/Navigation/_files/expected/bc/separator.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<a href="page2">Page 2</a>foo<a href="page2/page2_3">Page 2.3</a>foo<a href="page2/page2_3/page2_3_3">Page 2.3.3</a>fooPage 2.3.3.1
<a href="page2">Page 2</a>foo<a href="page2&#x2F;page2_3">Page 2.3</a>foo<a href="page2&#x2F;page2_3&#x2F;page2_3_3">Page 2.3.3</a>fooPage 2.3.3.1
2 changes: 1 addition & 1 deletion test/Helper/Navigation/_files/expected/bc/textdomain.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<a href="page2">TextDomain1 2</a> &gt; <a href="page2/page2_3">Page 2.3</a> &gt; <a href="page2/page2_3/page2_3_3">TextDomain1 2.3.3</a> &gt; TextDomain2 2.3.3.1
<a href="page2">TextDomain1 2</a> &gt; <a href="page2&#x2F;page2_3">Page 2.3</a> &gt; <a href="page2&#x2F;page2_3&#x2F;page2_3_3">TextDomain1 2.3.3</a> &gt; TextDomain2 2.3.3.1
2 changes: 1 addition & 1 deletion test/Helper/Navigation/_files/expected/bc/translated.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<a href="page2">Side 2</a> &gt; <a href="page2/page2_3">Side 2.3</a> &gt; <a href="page2/page2_3/page2_3_3">Page 2.3.3</a> &gt; Side 2.3.3.1
<a href="page2">Side 2</a> &gt; <a href="page2&#x2F;page2_3">Side 2.3</a> &gt; <a href="page2&#x2F;page2_3&#x2F;page2_3_3">Page 2.3.3</a> &gt; Side 2.3.3.1
12 changes: 6 additions & 6 deletions test/Helper/Navigation/_files/expected/links/default.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<link rel="start" href="index" title="Home">
<link rel="next" href="page2/page2_3/page2_3_3/2" title="Page 2.3.3.2">
<link rel="prev" href="page2/page2_3/page2_3_3" title="Page 2.3.3">
<link rel="chapter" href="page1" title="Page 1">
<link rel="chapter" href="page2" title="Page 2">
<link rel="chapter" href="page3" title="Page 3">
<link rel="chapter" href="http://www.zym-project.com/" title="Zym">
<link rel="next" href="page2&#x2F;page2_3&#x2F;page2_3_3&#x2F;2" title="Page&#x20;2.3.3.2">
<link rel="prev" href="page2&#x2F;page2_3&#x2F;page2_3_3" title="Page&#x20;2.3.3">
<link rel="chapter" href="page1" title="Page&#x20;1">
<link rel="chapter" href="page2" title="Page&#x20;2">
<link rel="chapter" href="page3" title="Page&#x20;3">
<link rel="chapter" href="http&#x3A;&#x2F;&#x2F;www.zym-project.com&#x2F;" title="Zym">
28 changes: 14 additions & 14 deletions test/Helper/Navigation/_files/expected/menu/acl.html
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
<ul class="navigation">
<li>
<a title="Go home" href="index">Home</a>
<a title="Go&#x20;home" href="index">Home</a>
</li>
<li>
<a href="page1">Page 1</a>
<ul>
<li>
<a href="page1/page1_1">Page 1.1</a>
<a href="page1&#x2F;page1_1">Page 1.1</a>
</li>
</ul>
</li>
<li class="active">
<a href="page2">Page 2</a>
<ul>
<li>
<a href="page2/page2_1">Page 2.1</a>
<a href="page2&#x2F;page2_1">Page 2.1</a>
</li>
<li class="active">
<a href="page2/page2_2">Page 2.2</a>
<a href="page2&#x2F;page2_2">Page 2.2</a>
<ul>
<li>
<a href="page2/page2_2/page2_2_1">Page 2.2.1</a>
<a href="page2&#x2F;page2_2&#x2F;page2_2_1">Page 2.2.1</a>
</li>
<li class="active">
<a href="page2/page2_2/page2_2_2">Page 2.2.2</a>
<a href="page2&#x2F;page2_2&#x2F;page2_2_2">Page 2.2.2</a>
</li>
</ul>
</li>
<li class="active">
<a href="page2/page2_3">Page 2.3</a>
<a href="page2&#x2F;page2_3">Page 2.3</a>
<ul>
<li>
<a href="page2/page2_3/page2_3_1">Page 2.3.1</a>
<a href="page2&#x2F;page2_3&#x2F;page2_3_1">Page 2.3.1</a>
</li>
</ul>
</li>
Expand All @@ -41,25 +41,25 @@
<a href="page3">Page 3</a>
<ul>
<li>
<a href="page3/page3_1">Page 3.1</a>
<a href="page3&#x2F;page3_1">Page 3.1</a>
</li>
<li>
<a href="page3/page3_2">Page 3.2</a>
<a href="page3&#x2F;page3_2">Page 3.2</a>
<ul>
<li>
<a href="page3/page3_2/page3_2_1">Page 3.2.1</a>
<a href="page3&#x2F;page3_2&#x2F;page3_2_1">Page 3.2.1</a>
</li>
<li>
<a href="page3/page3_2/page3_2_2">Page 3.2.2</a>
<a href="page3&#x2F;page3_2&#x2F;page3_2_2">Page 3.2.2</a>
</li>
</ul>
</li>
<li>
<a href="page3/page3_3">Page 3.3</a>
<a href="page3&#x2F;page3_3">Page 3.3</a>
</li>
</ul>
</li>
<li>
<a href="http://www.zym-project.com/">Zym</a>
<a href="http&#x3A;&#x2F;&#x2F;www.zym-project.com&#x2F;">Zym</a>
</li>
</ul>
Loading

0 comments on commit 274ca2b

Please sign in to comment.