Skip to content

Commit f50c803

Browse files
committed
Add bundle version of utf8_range to validate attribute values
1 parent 62ba4de commit f50c803

File tree

16 files changed

+1069
-9
lines changed

16 files changed

+1069
-9
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#pragma once
5+
6+
#include <cstdint>
7+
#include <initializer_list>
8+
#include <map>
9+
#include <string>
10+
#include <unordered_map>
11+
#include <utility>
12+
#include <vector>
13+
14+
#include "opentelemetry/common/attribute_value.h"
15+
#include "opentelemetry/common/key_value_iterable.h"
16+
#include "opentelemetry/nostd/string_view.h"
17+
#include "opentelemetry/nostd/variant.h"
18+
#include "opentelemetry/sdk/common/attribute_utils.h"
19+
#include "opentelemetry/version.h"
20+
21+
OPENTELEMETRY_BEGIN_NAMESPACE
22+
namespace sdk
23+
{
24+
namespace common
25+
{
26+
27+
OPENTELEMETRY_EXPORT bool AttributeIsValidString(nostd::string_view value) noexcept;
28+
29+
/**
30+
* Validate if an attribute value is valid.
31+
*/
32+
struct AttributeValidator
33+
{
34+
bool operator()(bool /*v*/) noexcept { return true; }
35+
bool operator()(int32_t /*v*/) noexcept { return true; }
36+
bool operator()(uint32_t /*v*/) noexcept { return true; }
37+
bool operator()(int64_t /*v*/) noexcept { return true; }
38+
bool operator()(uint64_t /*v*/) noexcept { return true; }
39+
bool operator()(double /*v*/) noexcept { return true; }
40+
bool operator()(nostd::string_view v) noexcept { return AttributeIsValidString(v); }
41+
bool operator()(std::string v) noexcept { return AttributeIsValidString(v); }
42+
bool operator()(const char *v) noexcept { return AttributeIsValidString(v); }
43+
bool operator()(nostd::span<const uint8_t> /*v*/) noexcept { return true; }
44+
bool operator()(nostd::span<const bool> /*v*/) noexcept { return true; }
45+
bool operator()(nostd::span<const int32_t> /*v*/) noexcept { return true; }
46+
bool operator()(nostd::span<const uint32_t> /*v*/) noexcept { return true; }
47+
bool operator()(nostd::span<const int64_t> /*v*/) noexcept { return true; }
48+
bool operator()(nostd::span<const uint64_t> /*v*/) noexcept { return true; }
49+
bool operator()(nostd::span<const double> /*v*/) noexcept { return true; }
50+
bool operator()(nostd::span<const nostd::string_view> v) noexcept
51+
{
52+
for (const auto &s : v)
53+
{
54+
if (!AttributeIsValidString(s))
55+
{
56+
return false;
57+
}
58+
}
59+
return true;
60+
}
61+
bool operator()(const std::vector<bool> & /*v*/) noexcept { return true; }
62+
bool operator()(const std::vector<int32_t> & /*v*/) noexcept { return true; }
63+
bool operator()(const std::vector<uint32_t> & /*v*/) noexcept { return true; }
64+
bool operator()(const std::vector<int64_t> & /*v*/) noexcept { return true; }
65+
bool operator()(const std::vector<double> & /*v*/) noexcept { return true; }
66+
bool operator()(const std::vector<std::string> &v)
67+
{
68+
for (const auto &s : v)
69+
{
70+
if (!AttributeIsValidString(s))
71+
{
72+
return false;
73+
}
74+
}
75+
return true;
76+
}
77+
bool operator()(const std::vector<uint64_t> & /*v*/) noexcept { return true; }
78+
bool operator()(const std::vector<uint8_t> & /*v*/) noexcept { return true; }
79+
80+
OPENTELEMETRY_EXPORT static bool IsValid(const OwnedAttributeValue &value) noexcept;
81+
82+
OPENTELEMETRY_EXPORT static bool IsValid(
83+
const opentelemetry::common::AttributeValue &value) noexcept;
84+
85+
OPENTELEMETRY_EXPORT static bool IsAllValid(const AttributeMap &attributes) noexcept;
86+
87+
OPENTELEMETRY_EXPORT static bool IsAllValid(const OrderedAttributeMap &attributes) noexcept;
88+
89+
OPENTELEMETRY_EXPORT static void Filter(AttributeMap &attributes, nostd::string_view log_hint);
90+
91+
OPENTELEMETRY_EXPORT static void Filter(OrderedAttributeMap &attributes,
92+
nostd::string_view log_hint);
93+
};
94+
95+
/**
96+
* Supports internal iteration over a collection of key-value pairs and filtering of invalid
97+
* attributes.
98+
*/
99+
class OPENTELEMETRY_EXPORT KeyValueFilterIterable : public opentelemetry::common::KeyValueIterable
100+
{
101+
public:
102+
KeyValueFilterIterable(const opentelemetry::common::KeyValueIterable &origin,
103+
opentelemetry::nostd::string_view log_hint) noexcept;
104+
105+
~KeyValueFilterIterable() override;
106+
107+
bool ForEachKeyValue(
108+
opentelemetry::nostd::function_ref<bool(opentelemetry::nostd::string_view,
109+
opentelemetry::common::AttributeValue)> callback)
110+
const noexcept override;
111+
112+
size_t size() const noexcept override;
113+
114+
private:
115+
// Pointer to the original KeyValueIterable
116+
const opentelemetry::common::KeyValueIterable *origin_;
117+
118+
// Size of valid attributes
119+
mutable size_t size_;
120+
121+
// Log hint for invalid attributes
122+
opentelemetry::nostd::string_view log_hint_;
123+
};
124+
125+
} // namespace common
126+
} // namespace sdk
127+
OPENTELEMETRY_END_NAMESPACE

sdk/include/opentelemetry/sdk/instrumentationscope/instrumentation_scope.h

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include "opentelemetry/nostd/unique_ptr.h"
1313
#include "opentelemetry/nostd/variant.h"
1414
#include "opentelemetry/sdk/common/attribute_utils.h"
15+
#include "opentelemetry/sdk/common/attribute_validity.h"
16+
#include "opentelemetry/sdk/common/global_log_handler.h"
1517
#include "opentelemetry/version.h"
1618

1719
OPENTELEMETRY_BEGIN_NAMESPACE
@@ -42,6 +44,7 @@ class InstrumentationScope
4244
nostd::string_view schema_url = "",
4345
InstrumentationScopeAttributes &&attributes = {})
4446
{
47+
common::AttributeValidator::Filter(attributes, "[InstrumentationScope]");
4548
return nostd::unique_ptr<InstrumentationScope>(
4649
new InstrumentationScope{name, version, schema_url, std::move(attributes)});
4750
}
@@ -60,8 +63,19 @@ class InstrumentationScope
6063
nostd::string_view schema_url,
6164
const InstrumentationScopeAttributes &attributes)
6265
{
63-
return nostd::unique_ptr<InstrumentationScope>(new InstrumentationScope{
64-
name, version, schema_url, InstrumentationScopeAttributes(attributes)});
66+
// Copy attributes only when we find some invalid attributes and try to remove them.
67+
if (common::AttributeValidator::IsAllValid(attributes))
68+
{
69+
return nostd::unique_ptr<InstrumentationScope>(new InstrumentationScope{
70+
name, version, schema_url, InstrumentationScopeAttributes(attributes)});
71+
}
72+
else
73+
{
74+
InstrumentationScopeAttributes copy_attributes = attributes;
75+
common::AttributeValidator::Filter(copy_attributes, "[InstrumentationScope]");
76+
return nostd::unique_ptr<InstrumentationScope>(new InstrumentationScope{
77+
name, version, schema_url, InstrumentationScopeAttributes(copy_attributes)});
78+
}
6579
}
6680

6781
/**
@@ -88,6 +102,12 @@ class InstrumentationScope
88102
result->attributes_.reserve(opentelemetry::nostd::size(arg));
89103
for (auto &argv : arg)
90104
{
105+
if (!common::AttributeValidator::IsValid(argv.second))
106+
{
107+
OTEL_INTERNAL_LOG_WARN("[InstrumentationScope] Invalid attribute value for: "
108+
<< std::string{argv.first} << ". This attribute will be ignored.");
109+
continue;
110+
}
91111
result->SetAttribute(argv.first, argv.second);
92112
}
93113

@@ -148,6 +168,12 @@ class InstrumentationScope
148168
void SetAttribute(nostd::string_view key,
149169
const opentelemetry::common::AttributeValue &value) noexcept
150170
{
171+
if (!common::AttributeValidator::IsValid(value))
172+
{
173+
OTEL_INTERNAL_LOG_WARN("[InstrumentationScope] Invalid attribute value for: "
174+
<< std::string{key} << ". This attribute will be ignored.");
175+
return;
176+
}
151177
attributes_[std::string(key)] =
152178
nostd::visit(opentelemetry::sdk::common::AttributeConverter(), value);
153179
}

sdk/src/common/BUILD

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,36 @@
33

44
package(default_visibility = ["//visibility:public"])
55

6+
cc_library(
7+
name = "utf8_range",
8+
srcs = [
9+
"internal/utf8_range/uft8_range.cc",
10+
],
11+
hdrs = [
12+
"internal/utf8_range/utf8_range.h",
13+
"internal/utf8_range/utf8_range_neon.inc",
14+
"internal/utf8_range/utf8_range_sse.inc",
15+
],
16+
include_prefix = "src/common",
17+
deps = [
18+
"//api",
19+
],
20+
)
21+
22+
cc_library(
23+
name = "attribute_validity",
24+
srcs = [
25+
"attribute_validity.cc",
26+
],
27+
include_prefix = "src/common",
28+
deps = [
29+
"//api",
30+
"//sdk:headers",
31+
"//sdk/src/common:global_log_handler",
32+
"//sdk/src/common:utf8_range",
33+
],
34+
)
35+
636
cc_library(
737
name = "random",
838
srcs = [

sdk/src/common/CMakeLists.txt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
# Copyright The OpenTelemetry Authors
22
# SPDX-License-Identifier: Apache-2.0
33

4-
set(COMMON_SRCS random.cc global_log_handler.cc env_variables.cc base64.cc
5-
disabled.cc)
4+
set(COMMON_SRCS
5+
random.cc
6+
global_log_handler.cc
7+
env_variables.cc
8+
base64.cc
9+
disabled.cc
10+
attribute_validity.cc
11+
internal/utf8_range/uft8_range.cc)
612
if(WIN32)
713
list(APPEND COMMON_SRCS platform/fork_windows.cc)
814
else()

0 commit comments

Comments
 (0)