Skip to content
Merged
54 changes: 53 additions & 1 deletion eZ/Publish/API/Repository/Tests/SearchServiceLocationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
namespace eZ\Publish\API\Repository\Tests;

use eZ\Publish\API\Repository\Tests\SetupFactory\LegacyElasticsearch;
use eZ\Publish\API\Repository\Values\Content\Content;
use eZ\Publish\Core\Repository\Values\Content\Location;
use eZ\Publish\API\Repository\Values\Content\LocationQuery;
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
Expand Down Expand Up @@ -54,7 +55,7 @@ public function testFindFacetedLocation(LocationQuery $query, $fixture)
/**
* Create test Content with ezcountry field having multiple countries selected.
*
* @return \eZ\Publish\API\Repository\Values\Content\Content
* @return Content
*/
protected function createMultipleCountriesContent()
{
Expand Down Expand Up @@ -101,6 +102,30 @@ protected function createMultipleCountriesContent()
return $content;
}

protected function createFolderWithNonPrintableUtf8Characters(): Content
{
$repository = $this->getRepository();
$contentTypeService = $repository->getContentTypeService();
$contentService = $repository->getContentService();

$contentType = $contentTypeService->loadContentTypeByIdentifier('folder');
$createStruct = $contentService->newContentCreateStruct($contentType, 'eng-GB');
$createStruct->remoteId = 'non-printable-char-folder-123';
$createStruct->alwaysAvailable = false;
$createStruct->setField(
'name',
utf8_decode("Non\x09Printable\x0EFolder")
);

$locationCreateStruct = $repository->getLocationService()->newLocationCreateStruct(2);
$draft = $contentService->createContent($createStruct, [$locationCreateStruct]);
$content = $contentService->publishVersion($draft->getVersionInfo());

$this->refreshSearch($repository);

return $content;
}

/**
* Test for the findLocations() method.
*
Expand Down Expand Up @@ -157,6 +182,33 @@ public function testFieldCollectionContainsNoMatch()
$this->assertEquals(0, $result->totalCount);
}

/**
* @covers \eZ\Publish\API\Repository\SearchService::findLocations
*/
public function testNonPrintableUtf8Characters(): void
{
$folder = $this->createFolderWithNonPrintableUtf8Characters();
$query = new LocationQuery(
[
'query' => new Criterion\Field(
'name',
Criterion\Operator::EQ,
utf8_decode("Non\x09Printable\x0EFolder")
),
]
);

$repository = $this->getRepository();
$searchService = $repository->getSearchService();
$result = $searchService->findLocations($query);

$this->assertEquals(1, $result->totalCount);
$this->assertEquals(
$folder->contentInfo->mainLocationId,
$result->searchHits[0]->valueObject->id
);
}

/**
* @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
*/
Expand Down
15 changes: 13 additions & 2 deletions eZ/Publish/Core/Search/Common/FieldValueMapper/StringMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
*/
class StringMapper extends FieldValueMapper
{
public const REPLACE_WITH_SPACE_PATTERN = '([\x09\x0B\x0C]+)';
public const REMOVE_PATTERN = '([\x00-\x08\x0E-\x1F]+)';


/**
* Check if field can be mapped.
*
Expand Down Expand Up @@ -51,9 +55,16 @@ public function map(Field $field)
*/
protected function convert($value)
{
// Remove non-printable characters
// Replace tab, vertical tab, form-feed chars to single space.
$value = preg_replace(
self::REPLACE_WITH_SPACE_PATTERN,
' ',
(string)$value
);

// Remove non-printable characters.
return preg_replace(
'([\x00-\x09\x0B\x0C\x1E\x1F]+)',
self::REMOVE_PATTERN,
'',
(string)$value
);
Expand Down