Skip to content

Commit

Permalink
Fix conversion of non-utf8 sequences to AnyValue (#1253)
Browse files Browse the repository at this point in the history
String values which are not valid Unicode sequences SHOULD be converted to AnyValue's bytes_value with the bytes representing the string in the original order and format of the source string.
  • Loading branch information
Nevay authored Mar 13, 2024
1 parent 01c46a2 commit 1753fbe
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/Contrib/Otlp/AttributesConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,23 @@ public static function convertAnyValue($value): AnyValue
$result->setDoubleValue($value);
}
if (is_string($value)) {
$result->setStringValue($value);
if (self::isUtf8($value)) {
$result->setStringValue($value);
} else {
$result->setBytesValue($value);
}
}

return $result;
}

private static function isUtf8(string $value): bool
{
return \extension_loaded('mbstring')
? \mb_check_encoding($value, 'UTF-8')
: (bool) \preg_match('//u', $value);
}

/**
* Test whether an array is simple (non-KeyValue)
*/
Expand Down
7 changes: 7 additions & 0 deletions tests/Unit/Contrib/Otlp/AttributesConverterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ public static function basicTypesProvider(): array
];
}

public function test_convert_bytes(): void
{
$anyValue = AttributesConverter::convertAnyValue("\xe2");
$this->assertTrue($anyValue->hasBytesValue());
$this->assertSame("\xe2", $anyValue->getBytesValue());
}

/**
* @dataProvider arrayProvider
*/
Expand Down
44 changes: 44 additions & 0 deletions tests/Unit/Contrib/Otlp/SpanExporterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,48 @@ public function test_json_span_and_trace_id_hex_format(): void
}
TRACE, stream_get_contents($stream));
}

public function test_json_invalid_utf8_sequence_is_encoded_as_bytes_value(): void
{
$stream = fopen('php://memory', 'a+b');
$transport = new StreamTransport($stream, 'application/json');
$exporter = new SpanExporter($transport);

$exporter->export([
(new SpanData())
->setContext(SpanContext::create('0af7651916cd43dd8448eb211c80319c', 'b7ad6b7169203331'))
->addAttribute('invalid-utf8', "\xe2"),
]);

fseek($stream, 0);
$this->assertJsonStringEqualsJsonString(<<<TRACE
{
"resourceSpans": [
{
"resource": {},
"scopeSpans": [
{
"scope": {},
"spans": [
{
"traceId": "0af7651916cd43dd8448eb211c80319c",
"spanId": "b7ad6b7169203331",
"name": "test-span-data",
"kind": 1,
"startTimeUnixNano": "1505855794194009601",
"endTimeUnixNano": "1505855799465726528",
"status": {},
"attributes": [{
"key": "invalid-utf8",
"value": {"bytesValue": "4g=="}
}]
}
]
}
]
}
]
}
TRACE, stream_get_contents($stream));
}
}

0 comments on commit 1753fbe

Please sign in to comment.