From 78826ba29e8cc7a9c7cd2dfd1e4fa54543479fe5 Mon Sep 17 00:00:00 2001 From: Harish <140232061+perhapsmaple@users.noreply.github.com> Date: Tue, 10 Feb 2026 21:34:33 +0530 Subject: [PATCH 1/6] Handle invalid YAML (closes #3857) Signed-off-by: Harish <140232061+perhapsmaple@users.noreply.github.com> --- .../sdk/configuration/ryml_document.h | 4 ++- sdk/src/configuration/ryml_document.cc | 26 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/sdk/include/opentelemetry/sdk/configuration/ryml_document.h b/sdk/include/opentelemetry/sdk/configuration/ryml_document.h index 9d464e63be..ad78f8e559 100644 --- a/sdk/include/opentelemetry/sdk/configuration/ryml_document.h +++ b/sdk/include/opentelemetry/sdk/configuration/ryml_document.h @@ -22,7 +22,7 @@ class RymlDocument : public Document public: static std::unique_ptr Parse(const std::string &source, const std::string &content); - RymlDocument() {} + RymlDocument() : event_handler_(MakeCallbacks()) {} RymlDocument(RymlDocument &&) = delete; RymlDocument(const RymlDocument &) = delete; RymlDocument &operator=(RymlDocument &&) = delete; @@ -36,6 +36,8 @@ class RymlDocument : public Document DocumentNodeLocation Location(ryml::ConstNodeRef node) const; private: + static ryml::Callbacks MakeCallbacks(); + ryml::ParserOptions opts_; ryml::Parser::handler_type event_handler_; std::unique_ptr parser_; diff --git a/sdk/src/configuration/ryml_document.cc b/sdk/src/configuration/ryml_document.cc index 83a067455e..7a70b3873e 100644 --- a/sdk/src/configuration/ryml_document.cc +++ b/sdk/src/configuration/ryml_document.cc @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "opentelemetry/sdk/common/global_log_handler.h" @@ -15,12 +16,37 @@ #include "opentelemetry/sdk/configuration/ryml_document_node.h" #include "opentelemetry/version.h" +namespace +{ + +// Custom ryml error callback that throws instead of calling abort(). +[[noreturn]] void on_ryml_error( + const char *msg, size_t msg_len, ryml::Location location, void * /*user_data*/) +{ + std::string error_msg(msg, msg_len); + if (location.line != ryml::npos) + { + error_msg += + " at line " + std::to_string(location.line + 1) + " col " + std::to_string(location.col + 1); + } + throw std::runtime_error(error_msg); +} + +} // namespace + OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk { namespace configuration { +ryml::Callbacks RymlDocument::MakeCallbacks() +{ + ryml::Callbacks cb = ryml::get_callbacks(); + cb.m_error = &on_ryml_error; + return cb; +} + std::unique_ptr RymlDocument::Parse(const std::string &source, const std::string &content) { auto doc = std::make_unique(); From e6a2ced233183a3f795eae4af58e75c1e360fe89 Mon Sep 17 00:00:00 2001 From: Harish <140232061+perhapsmaple@users.noreply.github.com> Date: Tue, 10 Feb 2026 22:14:53 +0530 Subject: [PATCH 2/6] Integrate callback better Signed-off-by: Harish <140232061+perhapsmaple@users.noreply.github.com> --- .../sdk/configuration/ryml_document.h | 2 ++ sdk/src/configuration/ryml_document.cc | 23 ++++++++----------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/configuration/ryml_document.h b/sdk/include/opentelemetry/sdk/configuration/ryml_document.h index ad78f8e559..0f727155c9 100644 --- a/sdk/include/opentelemetry/sdk/configuration/ryml_document.h +++ b/sdk/include/opentelemetry/sdk/configuration/ryml_document.h @@ -37,6 +37,8 @@ class RymlDocument : public Document private: static ryml::Callbacks MakeCallbacks(); + [[noreturn]] static void OnError( + const char *msg, size_t msg_len, ryml::Location location, void *user_data); ryml::ParserOptions opts_; ryml::Parser::handler_type event_handler_; diff --git a/sdk/src/configuration/ryml_document.cc b/sdk/src/configuration/ryml_document.cc index 7a70b3873e..e39847b872 100644 --- a/sdk/src/configuration/ryml_document.cc +++ b/sdk/src/configuration/ryml_document.cc @@ -16,34 +16,31 @@ #include "opentelemetry/sdk/configuration/ryml_document_node.h" #include "opentelemetry/version.h" -namespace +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace configuration { // Custom ryml error callback that throws instead of calling abort(). -[[noreturn]] void on_ryml_error( +// This ensures the try-catch in ParseDocument works regardless of how +// ryml was compiled (with or without RYML_DEFAULT_CALLBACK_USES_EXCEPTIONS). +void RymlDocument::OnError( const char *msg, size_t msg_len, ryml::Location location, void * /*user_data*/) { std::string error_msg(msg, msg_len); if (location.line != ryml::npos) { - error_msg += - " at line " + std::to_string(location.line + 1) + " col " + std::to_string(location.col + 1); + error_msg += " at line " + std::to_string(location.line + 1) + " col " + + std::to_string(location.col + 1); } throw std::runtime_error(error_msg); } -} // namespace - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace sdk -{ -namespace configuration -{ - ryml::Callbacks RymlDocument::MakeCallbacks() { ryml::Callbacks cb = ryml::get_callbacks(); - cb.m_error = &on_ryml_error; + cb.m_error = &RymlDocument::OnError; return cb; } From 7778527bb1746bc0eadd42e9111d529596343752 Mon Sep 17 00:00:00 2001 From: Harish <140232061+perhapsmaple@users.noreply.github.com> Date: Tue, 10 Feb 2026 22:15:23 +0530 Subject: [PATCH 3/6] Add malformed_yaml test Signed-off-by: Harish <140232061+perhapsmaple@users.noreply.github.com> --- sdk/test/configuration/yaml_test.cc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/sdk/test/configuration/yaml_test.cc b/sdk/test/configuration/yaml_test.cc index 9b8f2212f9..3979fb3803 100644 --- a/sdk/test/configuration/yaml_test.cc +++ b/sdk/test/configuration/yaml_test.cc @@ -717,3 +717,25 @@ file_format: "1.0" auto config = DoParse(yaml); ASSERT_EQ(config, nullptr); } + +TEST(Yaml, malformed_yaml) +{ + std::string yaml = R"( +file_format: "1.0" +tracer_provider: + processors: + - simple: + exporter: + otlp_http: + endpoint: http://localhost:4318/v1/traces + certificate: /app/cert.pem + client_key: /app/cert.pem + client_certificate: /app/cert.pem + headers: + - name: header_name + value: header_value +)"; + + auto config = DoParse(yaml); + ASSERT_EQ(config, nullptr); +} From bd4a2c9cc115aa5a38a9a878c072d9a96eb2dd2f Mon Sep 17 00:00:00 2001 From: Harish <140232061+perhapsmaple@users.noreply.github.com> Date: Tue, 10 Feb 2026 22:21:25 +0530 Subject: [PATCH 4/6] Fix formatting Signed-off-by: Harish <140232061+perhapsmaple@users.noreply.github.com> --- sdk/include/opentelemetry/sdk/configuration/ryml_document.h | 6 ++++-- sdk/src/configuration/ryml_document.cc | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/configuration/ryml_document.h b/sdk/include/opentelemetry/sdk/configuration/ryml_document.h index 0f727155c9..7f22660902 100644 --- a/sdk/include/opentelemetry/sdk/configuration/ryml_document.h +++ b/sdk/include/opentelemetry/sdk/configuration/ryml_document.h @@ -37,8 +37,10 @@ class RymlDocument : public Document private: static ryml::Callbacks MakeCallbacks(); - [[noreturn]] static void OnError( - const char *msg, size_t msg_len, ryml::Location location, void *user_data); + [[noreturn]] static void OnError(const char *msg, + size_t msg_len, + ryml::Location location, + void *user_data); ryml::ParserOptions opts_; ryml::Parser::handler_type event_handler_; diff --git a/sdk/src/configuration/ryml_document.cc b/sdk/src/configuration/ryml_document.cc index e39847b872..a41385c751 100644 --- a/sdk/src/configuration/ryml_document.cc +++ b/sdk/src/configuration/ryml_document.cc @@ -25,8 +25,10 @@ namespace configuration // Custom ryml error callback that throws instead of calling abort(). // This ensures the try-catch in ParseDocument works regardless of how // ryml was compiled (with or without RYML_DEFAULT_CALLBACK_USES_EXCEPTIONS). -void RymlDocument::OnError( - const char *msg, size_t msg_len, ryml::Location location, void * /*user_data*/) +void RymlDocument::OnError(const char *msg, + size_t msg_len, + ryml::Location location, + void * /*user_data*/) { std::string error_msg(msg, msg_len); if (location.line != ryml::npos) From 516cf3a6eedc6641654ea29b462b8fcba8a09412 Mon Sep 17 00:00:00 2001 From: Harish <140232061+perhapsmaple@users.noreply.github.com> Date: Wed, 11 Feb 2026 19:42:50 +0530 Subject: [PATCH 5/6] Address review comments Signed-off-by: Harish <140232061+perhapsmaple@users.noreply.github.com> --- sdk/src/configuration/ryml_document.cc | 16 +++++++++------- sdk/test/configuration/yaml_test.cc | 1 + 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/sdk/src/configuration/ryml_document.cc b/sdk/src/configuration/ryml_document.cc index a41385c751..959e15bd57 100644 --- a/sdk/src/configuration/ryml_document.cc +++ b/sdk/src/configuration/ryml_document.cc @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#include #include #include #include @@ -12,6 +13,7 @@ #include "opentelemetry/sdk/common/global_log_handler.h" #include "opentelemetry/sdk/configuration/document.h" #include "opentelemetry/sdk/configuration/document_node.h" +#include "opentelemetry/sdk/configuration/invalid_schema_exception.h" #include "opentelemetry/sdk/configuration/ryml_document.h" #include "opentelemetry/sdk/configuration/ryml_document_node.h" #include "opentelemetry/version.h" @@ -30,13 +32,13 @@ void RymlDocument::OnError(const char *msg, ryml::Location location, void * /*user_data*/) { - std::string error_msg(msg, msg_len); - if (location.line != ryml::npos) - { - error_msg += " at line " + std::to_string(location.line + 1) + " col " + - std::to_string(location.col + 1); - } - throw std::runtime_error(error_msg); + DocumentNodeLocation loc; + loc.offset = location.offset; + loc.line = location.line; + loc.col = location.col; + loc.filename = std::string(location.name.str, location.name.len); + + throw InvalidSchemaException(loc, std::string(msg, msg_len)); } ryml::Callbacks RymlDocument::MakeCallbacks() diff --git a/sdk/test/configuration/yaml_test.cc b/sdk/test/configuration/yaml_test.cc index 3979fb3803..180dbe1b6e 100644 --- a/sdk/test/configuration/yaml_test.cc +++ b/sdk/test/configuration/yaml_test.cc @@ -720,6 +720,7 @@ file_format: "1.0" TEST(Yaml, malformed_yaml) { + // "headers" is indented under "client_certificate" instead of "otlp_http" std::string yaml = R"( file_format: "1.0" tracer_provider: From 0f9892162fcc20bd1bc7e043988e1356fe15dd24 Mon Sep 17 00:00:00 2001 From: Harish <140232061+perhapsmaple@users.noreply.github.com> Date: Wed, 11 Feb 2026 20:32:50 +0530 Subject: [PATCH 6/6] Fix iwyu CI Signed-off-by: Harish <140232061+perhapsmaple@users.noreply.github.com> --- sdk/src/configuration/ryml_document.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/sdk/src/configuration/ryml_document.cc b/sdk/src/configuration/ryml_document.cc index 959e15bd57..ac0e051c2e 100644 --- a/sdk/src/configuration/ryml_document.cc +++ b/sdk/src/configuration/ryml_document.cc @@ -7,7 +7,6 @@ #include #include #include -#include #include #include "opentelemetry/sdk/common/global_log_handler.h"