Skip to content

Commit

Permalink
fix: regex usage in w3c extraction (#121)
Browse files Browse the repository at this point in the history
Usage of std::regex_match was problematic for traceparent with trailing
spaces. The overload use is `std::regex_match(str, str + std::char_traits<CharT>::length(str), m, e, flags)`,
which resolves as the whole input instead of the trimmed input.

Changes:
  - Fix std::regex_match usage.
  - Add unit test.
  • Loading branch information
dmehala authored May 22, 2024
1 parent fad4e8d commit 622585c
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 18 deletions.
39 changes: 21 additions & 18 deletions src/datadog/w3c_propagation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ namespace datadog {
namespace tracing {
namespace {

// Note that match group 0 is the entire match.
constexpr StringView k_traceparent_pattern =
"([0-9a-f]{2})" // hex version number (match group 1)
"-"
"([0-9a-f]{32})" // hex trace ID (match group 2)
"-"
"([0-9a-f]{16})" // hex parent span ID (match group 3)
"-"
"([0-9a-f]{2})" // hex "trace-flags" (match group 4)
"($|-.*)"; // either the end, or a hyphen preceding further fields (match
// group 5)

// Return a predicate that returns whether its `char` argument is any of the
// following:
//
Expand Down Expand Up @@ -45,32 +57,23 @@ Optional<std::string> extract_traceparent(ExtractedData& result,

const auto traceparent = trim(*maybe_traceparent);

// Note that leading and trailing whitespace was already removed above.
// Note that match group 0 is the entire match.
static const auto& pattern =
"([0-9a-f]{2})" // hex version number (match group 1)
"-"
"([0-9a-f]{32})" // hex trace ID (match group 2)
"-"
"([0-9a-f]{16})" // hex parent span ID (match group 3)
"-"
"([0-9a-f]{2})" // hex "trace-flags" (match group 4)
"($|-.*)"; // either the end, or a hyphen preceding further fields (match
// group 5)
static const std::regex regex{pattern};
static const std::regex regex{k_traceparent_pattern.data()};

std::cmatch match;
if (!std::regex_match(traceparent.data(), match, regex)) {
if (!std::regex_match(traceparent.data(),
traceparent.data() + traceparent.size(), match,
regex)) {
return "malformed_traceparent";
}

assert(match.ready());
assert(match.size() == 5 + 1);
assert(match.size() == 6);

const auto to_string_view = [traceparent](const std::cmatch& match,
const std::size_t index) {
const auto to_string_view = [traceparent_beg = traceparent.data()](
const std::cmatch& match,
const std::size_t index) {
assert(index < match.size());
return StringView(traceparent.data() + match.position(index),
return StringView(traceparent_beg + match.position(index),
std::size_t(match.length(index)));
};

Expand Down
7 changes: 7 additions & 0 deletions test/test_tracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,13 @@ TEST_CASE("span extraction") {
67667974448284343ULL, // expected_parent_id
0}, // expected_sampling_priority

{__LINE__, "valid: leading and trailing spaces",
" 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01 \t", // traceparent
nullopt,
*TraceID::parse_hex("4bf92f3577b34da6a3ce929d0e0e4736"), // expected_trace_id
67667974448284343ULL, // expected_parent_id
1}, // expected_sampling_priority

{__LINE__, "no traceparent",
nullopt}, // traceparent

Expand Down

0 comments on commit 622585c

Please sign in to comment.