From 5e266e0e046f175cb6762f1899ffaeb13cc1f411 Mon Sep 17 00:00:00 2001 From: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:29:39 +0100 Subject: [PATCH] fix(telemetry): Do not build a string_view from a null attribute pointer The C-string overload of setAttribute handed its pointer straight to std::string_view, whose pointer constructor reads the pointer to find the length. A null one is undefined behaviour. A null pointer carries no text, and an empty value already means something on this class, so nothing is recorded rather than an empty string. The overload itself has to stay. Without it a string literal would bind to the bool overload, because pointer-to-bool is a standard conversion and beats the string_view one, so every string attribute would silently record true. The header now records that. --- include/xrpl/telemetry/SpanGuard.h | 18 ++++++++++++++++-- src/libxrpl/telemetry/SpanGuard.cpp | 6 +++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/include/xrpl/telemetry/SpanGuard.h b/include/xrpl/telemetry/SpanGuard.h index 46f1dcb63b..bdf8a4779e 100644 --- a/include/xrpl/telemetry/SpanGuard.h +++ b/include/xrpl/telemetry/SpanGuard.h @@ -447,7 +447,14 @@ public: setAttribute(std::string_view key, std::string_view value) noexcept; /** - * Set a string attribute (C-string overload). No-op on a null guard. + * Set a string attribute from a C string. No-op on a null guard. + * + * @param key Attribute key. + * @param value Null-terminated text. A null pointer records nothing, since + * an empty value is already a meaningful value here. + * @note This overload is required, not a convenience. Without it a string + * literal binds to the bool overload, because pointer-to-bool is a standard + * conversion and beats the std::string_view one. */ void setAttribute(std::string_view key, char const* value) noexcept; @@ -739,7 +746,14 @@ public: setAttribute(std::string_view key, std::string_view value) noexcept; /** - * Set a string attribute (C-string overload). No-op on a null guard. + * Set a string attribute from a C string. No-op on a null guard. + * + * @param key Attribute key. + * @param value Null-terminated text. A null pointer records nothing, since + * an empty value is already a meaningful value here. + * @note This overload is required, not a convenience. Without it a string + * literal binds to the bool overload, because pointer-to-bool is a standard + * conversion and beats the std::string_view one. */ void setAttribute(std::string_view key, char const* value) noexcept; diff --git a/src/libxrpl/telemetry/SpanGuard.cpp b/src/libxrpl/telemetry/SpanGuard.cpp index 28d1572531..0069c3e464 100644 --- a/src/libxrpl/telemetry/SpanGuard.cpp +++ b/src/libxrpl/telemetry/SpanGuard.cpp @@ -408,7 +408,11 @@ SpanGuard::setAttribute(std::string_view key, std::string_view value) noexcept void SpanGuard::setAttribute(std::string_view key, char const* value) noexcept { - setAttribute(key, std::string_view(value)); + // A std::string_view built from a pointer reads that pointer to find its + // length, so a null one is undefined behaviour. A null pointer carries no + // text, and an empty value already means something here, so record nothing. + if (value != nullptr) + setAttribute(key, std::string_view(value)); } void