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

Fix #85 #90

Merged
merged 1 commit into from
Jan 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/Log/AbstractXmlLogger.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,30 @@ protected function isUtf8($string)
return true;
}

/**
* Escapes a string for inclusion inside an XML tag.
*
* Converts the string to UTF-8, substitutes the unicode replacement
* character for every character disallowed in XML, and escapes
* special characters.
*
* @param string $string
* @return string
*/
protected function escapeForXml($string)
{
$string = $this->convertToUtf8($string);

// Substitute the unicode replacement character for disallowed chars
$string = preg_replace(
'/[^\x09\x0A\x0D\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]/u',
"\xEF\xBF\xBD",
$string
);

return htmlspecialchars($string, ENT_COMPAT, 'UTF-8');
}

/**
* Processes a list of clones.
*
Expand Down
6 changes: 1 addition & 5 deletions src/Log/PMD.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,7 @@ public function processClones(CodeCloneMap $clones)
$duplication->appendChild(
$this->document->createElement(
'codefragment',
htmlspecialchars(
$this->convertToUtf8($clone->getLines()),
ENT_COMPAT,
'UTF-8'
)
$this->escapeForXml($clone->getLines())
)
);
}
Expand Down
70 changes: 70 additions & 0 deletions tests/Log/PMDTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php
use SebastianBergmann\PHPCPD\CodeClone;
use SebastianBergmann\PHPCPD\CodeCloneFile;
use SebastianBergmann\PHPCPD\CodeCloneMap;
use SebastianBergmann\PHPCPD\Log\PMD;

class PHPCPD_Log_PMDTest extends PHPUnit_Framework_TestCase
{
/** @var string */
private $testFile1;
/** @var @var string */
private $testFile2;
/** @var string */
private $pmdLogFile;
/** @var string */
private $expectedPmdLogFile;
/** @var \SebastianBergmann\PHPCPD\Log\PMD */
private $pmdLogger;

protected function setUp()
{
$this->testFile1 = __DIR__ . '/_files/with_ascii_escape.php';
$this->testFile2 = __DIR__ . '/_files/with_ascii_escape2.php';

$this->pmdLogFile = tempnam(sys_get_temp_dir(), 'pmd');

$this->expectedPmdLogFile = tempnam(sys_get_temp_dir(), 'pmd');
$expectedPmdLogTemplate = __DIR__ . '/_files/pmd_expected.xml';
$expectedPmdLogContents = strtr(
file_get_contents($expectedPmdLogTemplate),
array(
'%file1%' => $this->testFile1,
'%file2%' => $this->testFile2
)
);
file_put_contents($this->expectedPmdLogFile, $expectedPmdLogContents);

$this->pmdLogger = new PMD($this->pmdLogFile);
}

protected function tearDown()
{
if (file_exists($this->pmdLogFile)) {
unlink($this->pmdLogFile);
}
if (file_exists($this->expectedPmdLogFile)) {
unlink($this->expectedPmdLogFile);
}
}

/**
* @covers SebastianBergmann\PHPCPD\Log\PMD
* @covers SebastianBergmann\PHPCPD\Log\AbstractXmlLogger
*/
public function testSubstitutesDisallowedCharacters()
{
$file1 = new CodeCloneFile($this->testFile1, 8);
$file2 = new CodeCloneFile($this->testFile2, 8);
$clone = new CodeClone($file1, $file2, 4, 4);
$cloneMap = new CodeCloneMap();
$cloneMap->addClone($clone);

$this->pmdLogger->processClones($cloneMap);

$this->assertXmlFileEqualsXmlFile(
$this->expectedPmdLogFile,
$this->pmdLogFile
);
}
}
12 changes: 12 additions & 0 deletions tests/Log/_files/pmd_expected.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<pmd-cpd>
<duplication lines="4" tokens="4">
<file path="%file1%" line="8"/>
<file path="%file2%" line="8"/>
<codefragment>function getAsciiEscapeChar()
{
return "�";
}
</codefragment>
</duplication>
</pmd-cpd>
11 changes: 11 additions & 0 deletions tests/Log/_files/with_ascii_escape.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

/**
* This function returns an ASCII escape character:
*
* @return string
*/
function getAsciiEscapeChar()
{
return "";
}