Skip to content

[BUG] ETW Properties::to_vector doubles the result and reads past a string_view #4347

Description

@thc1006

Properties::to_vector(span<string_view>) in exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h:94 has two defects on adjacent lines:

std::vector<std::string> static to_vector(const nostd::span<const nostd::string_view> &source)
{
  std::vector<std::string> result(source.size());
  for (const auto &item : source)
  {
    result.push_back(std::string(item.data()));
  }
  return result;
}

The result is twice the size it should be. std::vector<std::string> result(source.size()) value-initialises source.size() empty strings, and the loop then appends source.size() more. A span of three views comes back as six entries whose first three are empty.

std::string(item.data()) reads until a NUL. The function's own comment says the input is a span of "non-owning string views", and nostd::string_view::data() is not required to point at a NUL terminated buffer, so this can read past the view and copy whatever follows it.

The generic overload immediately above, at line 84, is correct and does neither:

template <typename T>
static std::vector<T> to_vector(const nostd::span<const T, nostd::dynamic_extent> &source)
{
  return std::vector<T>(source.begin(), source.end());
}

so the string_view overload looks like a copy that diverged.

It is live code. PropertyVariant::operator= calls it at line 260 for AttributeType::kTypeSpanString, so any ETW span or log record carrying a string-array attribute goes through it.

Why this is a report rather than a pull request

No CI job builds the ETW exporter. WITH_ETW appears in no workflow and in no branch of ci/do_ci.sh; the only workflow that names ETW at all is cppcheck.yml, which analyses rather than compiles. A fix here cannot be verified by the pipeline, and the to_vector change is entangled with the sizing bug rather than being a one line correction, so I would rather not push a blind change into a Windows-only path.

The suggested shape, if a maintainer wants it:

std::vector<std::string> result;
result.reserve(source.size());
for (const auto &item : source)
{
  result.push_back(static_cast<std::string>(item));
}
return result;

nostd::string_view has an explicit operator std::string() that copies by length.

I am happy to send that, but it would be more useful alongside a job that compiles the ETW exporter, since the sizing bug is the kind a single assertion would have caught. Found while sweeping the same string_view::data() shape for #4346, which fixes the four occurrences in components that CI does build.

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageIndicates an issue or PR lacks a `triage/foo` label and requires one.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions