From b14752d4e86611748e40b7274e98a49dd74ed2d0 Mon Sep 17 00:00:00 2001 From: Masakazu Kitajo Date: Fri, 5 Jun 2026 19:38:22 -0600 Subject: [PATCH] Emit type-default for custom log fields with no transaction When a log entry has no backing HttpSM (e.g. a malformed H2/H3 request rejected before transaction creation), passing nullptr to a TSLogFieldRegister'd callback dereferences null inside the plugin. Skip the callback in that case and emit the type-appropriate default the way built-in fields do: 0 for ints, "-" for strings, AF_UNSPEC for IPs. --- include/proxy/logging/LogAccess.h | 2 +- src/proxy/logging/LogAccess.cc | 26 ++++++++++++++++++++++++-- src/proxy/logging/LogField.cc | 4 ++-- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/include/proxy/logging/LogAccess.h b/include/proxy/logging/LogAccess.h index 12e353483a2..c4a58a888aa 100644 --- a/include/proxy/logging/LogAccess.h +++ b/include/proxy/logging/LogAccess.h @@ -328,7 +328,7 @@ class LogAccess void set_http_header_field(LogField::Container container, char *field, char *buf, int len); // Plugin - int marshal_custom_field(char *buf, const LogField::CustomMarshalFunc &plugin_marshal_func); + int marshal_custom_field(char *buf, LogField::Type type, const LogField::CustomMarshalFunc &plugin_marshal_func); // // unmarshalling routines diff --git a/src/proxy/logging/LogAccess.cc b/src/proxy/logging/LogAccess.cc index 7dc136c147c..1de1217bfac 100644 --- a/src/proxy/logging/LogAccess.cc +++ b/src/proxy/logging/LogAccess.cc @@ -465,9 +465,31 @@ LogAccess::marshal_ip(char *dest, sockaddr const *ip) } int -LogAccess::marshal_custom_field(char *buf, const LogField::CustomMarshalFunc &plugin_marshal_func) +LogAccess::marshal_custom_field(char *buf, LogField::Type type, const LogField::CustomMarshalFunc &plugin_marshal_func) { - int len = plugin_marshal_func(m_data->http_sm_for_plugins(), buf); + void *sm = m_data->http_sm_for_plugins(); + if (sm == nullptr) { + switch (type) { + case LogField::sINT: + case LogField::dINT: + if (buf) { + marshal_int(buf, 0); + } + return INK_MIN_ALIGN; + case LogField::STRING: { + int len = LogAccess::padded_strlen(nullptr); + if (buf) { + marshal_str(buf, nullptr, len); + } + return len; + } + case LogField::IP: + return marshal_ip(buf, nullptr); + case LogField::N_TYPES: + break; + } + } + int len = plugin_marshal_func(sm, buf); return LogAccess::padded_length(len); } diff --git a/src/proxy/logging/LogField.cc b/src/proxy/logging/LogField.cc index f1397865542..f68fc259adf 100644 --- a/src/proxy/logging/LogField.cc +++ b/src/proxy/logging/LogField.cc @@ -524,7 +524,7 @@ LogField::marshal_len(LogAccess *lad) if (!m_custom_marshal_func) { return (lad->*m_marshal_func)(nullptr); } else { - return lad->marshal_custom_field(nullptr, m_custom_marshal_func); + return lad->marshal_custom_field(nullptr, m_type, m_custom_marshal_func); } } @@ -633,7 +633,7 @@ LogField::marshal(LogAccess *lad, char *buf) if (!m_custom_marshal_func) { return (lad->*m_marshal_func)(buf); } else { - return lad->marshal_custom_field(buf, m_custom_marshal_func); + return lad->marshal_custom_field(buf, m_type, m_custom_marshal_func); } }