From a520369da025fe203c9302e643374eb5e76e0718 Mon Sep 17 00:00:00 2001 From: Eduardo Arias Date: Mon, 19 Aug 2024 08:28:04 -0700 Subject: [PATCH] Perform EscapeSeqDecode transformation in-place - Removed ansi_c_sequences_decode_inplace helper function from the class, as it's only referenced by the implementation. --- .../transformations/escape_seq_decode.cc | 41 +++++++------------ .../transformations/escape_seq_decode.h | 1 - 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/src/actions/transformations/escape_seq_decode.cc b/src/actions/transformations/escape_seq_decode.cc index a0dccb53..29006144 100644 --- a/src/actions/transformations/escape_seq_decode.cc +++ b/src/actions/transformations/escape_seq_decode.cc @@ -26,12 +26,13 @@ EscapeSeqDecode::EscapeSeqDecode(const std::string &action) } -int EscapeSeqDecode::ansi_c_sequences_decode_inplace(unsigned char *input, - int input_len) { - unsigned char *d = input; - int i, count; +static inline int ansi_c_sequences_decode_inplace(std::string &value) { + auto d = reinterpret_cast(value.data()); + const unsigned char* input = d; + const auto input_len = value.length(); - i = count = 0; + bool changed = false; + std::string::size_type i = 0; while (i < input_len) { if ((input[i] == '\\') && (i + 1 < input_len)) { int c = -1; @@ -109,43 +110,29 @@ int EscapeSeqDecode::ansi_c_sequences_decode_inplace(unsigned char *input, if (c == -1) { /* Didn't recognise encoding, copy raw bytes. */ *d++ = input[i + 1]; - count++; i += 2; } else { /* Converted the encoding. */ *d++ = c; - count++; } + + changed = true; } else { /* Input character not a backslash, copy it. */ *d++ = input[i++]; - count++; } } *d = '\0'; - return count; -} - - -bool EscapeSeqDecode::transform(std::string &value, const Transaction *trans) const { - - unsigned char *tmp = (unsigned char *) malloc(sizeof(char) - * value.size() + 1); - memcpy(tmp, value.c_str(), value.size() + 1); - tmp[value.size()] = '\0'; - - int size = ansi_c_sequences_decode_inplace(tmp, value.size()); - - std::string ret(""); - ret.assign(reinterpret_cast(tmp), size); - free(tmp); - - const auto changed = ret != value; - value = ret; + value.resize(d - input); return changed; } +bool EscapeSeqDecode::transform(std::string &value, const Transaction *trans) const { + return ansi_c_sequences_decode_inplace(value); +} + + } // namespace modsecurity::actions::transformations diff --git a/src/actions/transformations/escape_seq_decode.h b/src/actions/transformations/escape_seq_decode.h index ab66464d..6a240715 100644 --- a/src/actions/transformations/escape_seq_decode.h +++ b/src/actions/transformations/escape_seq_decode.h @@ -25,7 +25,6 @@ class EscapeSeqDecode : public Transformation { explicit EscapeSeqDecode(const std::string &action); bool transform(std::string &value, const Transaction *trans) const override; - static int ansi_c_sequences_decode_inplace(unsigned char *input, int input_len); }; } // namespace modsecurity::actions::transformations