Skip to content

Commit

Permalink
Avoid warning (and dismissal) of objects in input array when using mb…
Browse files Browse the repository at this point in the history
…_convert_encoding
  • Loading branch information
remyroussel committed Oct 7, 2024
1 parent 80855fc commit b54cd77
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ private function audit(array $data): void
$dt = new \DateTimeImmutable('now', new \DateTimeZone($this->provider->getAuditor()->getConfiguration()->getTimezone()));
$diff = $data['diff'];
$convertCharEncoding = (\is_string($diff) || \is_array($diff));
$diff = $convertCharEncoding ? mb_convert_encoding($diff, 'UTF-8', 'UTF-8') : $diff;
$diff = $convertCharEncoding ? $this->convertEncoding($diff) : $diff;

$payload = [
'entity' => $data['entity'],
Expand All @@ -232,6 +232,22 @@ private function audit(array $data): void
$this->notify($payload);
}

// Avoid warning (and dismissal) of objects in input array when using mb_convert_encoding
private function convertEncoding(mixed $input): mixed
{
if (\is_string($input)) {
return mb_convert_encoding($input, 'UTF-8', 'UTF-8');
}
if (\is_array($input)) {
foreach ($input as $key => $value) {
$input[$this->convertEncoding($key)] = $this->convertEncoding($value); // inbuilt mb_convert_encoding also converts keys
}
}

// Leave any other thing as is
return $input;
}

private function getDiscriminator(object $entity, int $inheritanceType): ?string
{
return ClassMetadata::INHERITANCE_TYPE_SINGLE_TABLE === $inheritanceType ? DoctrineHelper::getRealClassName($entity) : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,50 @@ public function testProcessDeletions(): void
$this->assertCount(1, $audits, 'TransactionProcessor::processDeletions() creates a "'.Transaction::REMOVE.'" audit entry.');
}

public function testEncodingConversion(): void
{
$processor = new TransactionProcessor($this->provider);
$method = $this->reflectMethod(TransactionProcessor::class, 'convertEncoding');

$invalidUtf8String = "\xC3\x28"; // Invalid UTF-8 byte sequence.
$convertedString = $method->invokeArgs($processor, [$invalidUtf8String]);

// Invalid UTF-8 byte sequence should be converted to valid UTF-8.
$this->assertNotSame(
$invalidUtf8String,
$convertedString,
);
$this->assertTrue(mb_check_encoding($convertedString, 'UTF-8'));

$obj = new \stdClass();
$complexArray = [
1,
false,
'string',
[
'key' => 'value',
'invalid' => $invalidUtf8String,
],
$obj,
];

$convertedArray = $method->invokeArgs($processor, [$complexArray]);
// Invalid UTF-8 byte sequence should be converted to valid UTF-8 and the rest of the array should remain unchanged.
$this->assertSame(
[
1,
false,
'string',
[
'key' => 'value',
'invalid' => $convertedString,
],
$obj,
],
$convertedArray,
);
}

private function configureEntities(): void
{
$this->provider->getConfiguration()->setEntities([
Expand Down

0 comments on commit b54cd77

Please sign in to comment.