From a7fd654572fd2358fca0f868fe03c6de3b104236 Mon Sep 17 00:00:00 2001 From: Brian Olsen Date: Fri, 1 May 2026 12:54:55 -0600 Subject: [PATCH] slice: fix stpcpy off-by-one for header value extraction The off by one wastes a single character, it doesn't overrun. --- plugins/slice/HttpHeader.cc | 26 ++++++++++++++------------ plugins/slice/HttpHeader.h | 4 +++- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/plugins/slice/HttpHeader.cc b/plugins/slice/HttpHeader.cc index bfaa2253bc1..9cc0bb7f30c 100644 --- a/plugins/slice/HttpHeader.cc +++ b/plugins/slice/HttpHeader.cc @@ -168,33 +168,35 @@ HttpHeader::removeKey(char const *const keystr, int const keylen) bool HttpHeader::valueForKey(char const *const keystr, int const keylen, char *const valstr, int *const vallen, int const index) const { - if (!isValid()) { + if (nullptr == valstr || nullptr == vallen) { + return false; + } + if (!isValid() || index < -1) { *vallen = 0; return false; } bool status = false; + int const valcap = *vallen; + *vallen = 0; + valstr[0] = 0; + TSMLoc const locfield = TSMimeHdrFieldFind(m_buffer, m_lochdr, keystr, keylen); if (nullptr != locfield) { int getlen = 0; char const *const getstr = TSMimeHdrFieldValueStringGet(m_buffer, m_lochdr, locfield, index, &getlen); - - int const valcap = *vallen; - if (nullptr != getstr && 0 < getlen && getlen < (valcap - 1)) { + if (nullptr != getstr && 0 < getlen && getlen < valcap) { char *const endp = stpncpy(valstr, getstr, getlen); - - *vallen = endp - valstr; - status = (*vallen < valcap); - - if (status) { - *endp = '\0'; + int const len = endp - valstr; + if (len < valcap) { + *endp = '\0'; + *vallen = len; + status = true; } } TSHandleMLocRelease(m_buffer, m_lochdr, locfield); - } else { - *vallen = 0; } return status; diff --git a/plugins/slice/HttpHeader.h b/plugins/slice/HttpHeader.h index 0c99df1921d..c52738e5d18 100644 --- a/plugins/slice/HttpHeader.h +++ b/plugins/slice/HttpHeader.h @@ -114,7 +114,9 @@ struct HttpHeader { // returns false if header invalid or something went wrong with removal. bool removeKey(char const *const key, int const keylen); - // retrieves header value as a char* + // retrieves header value as a null terminated char* in valstr. + // caller must ensure the valstr buffer has sufficient capacity. + // null termination only guaranteed on success. bool valueForKey(char const *const keystr, int const keylen, char *const valstr, // <-- return string value int *const vallen, // <-- pass in capacity, returns len of string