@@ -53,7 +53,8 @@ Optional<std::string> extract_traceparent(ExtractedData& result,
5353 " ([0-9a-f]{16})" // hex parent span ID (match group 3)
5454 " -"
5555 " ([0-9a-f]{2})" // hex "trace-flags" (match group 4)
56- " (?:$|-.*)" ; // either the end, or a hyphen preceding further fields
56+ " ($|-.*)" ; // either the end, or a hyphen preceding further fields (match
57+ // group 5)
5758 static const std::regex regex{pattern};
5859
5960 std::match_results<StringView::iterator> match;
@@ -62,18 +63,23 @@ Optional<std::string> extract_traceparent(ExtractedData& result,
6263 }
6364
6465 assert (match.ready ());
65- assert (match.size () == 4 + 1 );
66+ assert (match.size () == 5 + 1 );
6667
6768 const auto to_string_view = [](const auto & submatch) {
6869 assert (submatch.first <= submatch.second );
6970 return StringView{submatch.first ,
7071 std::size_t (submatch.second - submatch.first )};
7172 };
7273
73- if (to_string_view (match[1 ]) == " ff" ) {
74+ const auto version = to_string_view (match[1 ]);
75+ if (version == " ff" ) {
7476 return " invalid_version" ;
7577 }
7678
79+ if (version == " 00" && !to_string_view (match[5 ]).empty ()) {
80+ return " malformed_traceparent" ;
81+ }
82+
7783 result.trace_id = *TraceID::parse_hex (to_string_view (match[2 ]));
7884 if (result.trace_id == 0 ) {
7985 return " trace_id_zero" ;
@@ -190,6 +196,11 @@ void parse_datadog_tracestate(ExtractedData& result, StringView datadog_value) {
190196 const auto value = range (kv_separator + 1 , pair_end);
191197 if (key == " o" ) {
192198 result.origin = std::string{value};
199+ // Equal signs are allowed in the value of "origin," but equal signs are
200+ // also special characters in the `tracestate` encoding. So, equal signs
201+ // that would appear in the "origin" value are converted to tildes during
202+ // encoding. Here, in decoding, we undo the conversion.
203+ std::replace (result.origin ->begin (), result.origin ->end (), ' ~' , ' =' );
193204 } else if (key == " s" ) {
194205 const auto maybe_priority = parse_int (value, 10 );
195206 if (!maybe_priority) {
@@ -322,7 +333,8 @@ std::string encode_datadog_tracestate(
322333 result += " ;o:" ;
323334 result += *origin;
324335 std::replace_if (result.end () - origin->size (), result.end (),
325- verboten (0x20 , 0x7e , " ,;=" ), ' _' );
336+ verboten (0x20 , 0x7e , " ,;~" ), ' _' );
337+ std::replace (result.end () - origin->size (), result.end (), ' =' , ' ~' );
326338 }
327339
328340 for (const auto & [key, value] : trace_tags) {
0 commit comments