mirror of
https://github.com/openappsec/openappsec.git
synced 2025-06-28 16:41:02 +03:00
133 lines
4.3 KiB
C++
Executable File
133 lines
4.3 KiB
C++
Executable File
// Copyright (C) 2022 Check Point Software Technologies Ltd. All rights reserved.
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "ParserBase.h"
|
|
#include <string.h>
|
|
#include "debug.h"
|
|
|
|
USE_DEBUG_FLAG(D_WAAP_PARSER);
|
|
|
|
// Max size for key and value that can be stored in memory (per thread)
|
|
#define MAX_KEY_SIZE 64*1024
|
|
#define MAX_VALUE_SIZE 16*1024
|
|
#define MAX_PROCESSING_BUFFER_SIZE 64*1024
|
|
|
|
BufferedReceiver::BufferedReceiver(IParserReceiver &receiver, size_t parser_depth) :
|
|
m_receiver(receiver),
|
|
m_flags(BUFFERED_RECEIVER_F_FIRST),
|
|
m_parser_depth(parser_depth)
|
|
{
|
|
dbgTrace(D_WAAP_PARSER)
|
|
<< "parser_depth="
|
|
<< parser_depth;
|
|
}
|
|
|
|
int BufferedReceiver::onKey(const char *k, size_t k_len)
|
|
{
|
|
dbgTrace(D_WAAP_PARSER)
|
|
<< "Entering BufferedReceiver::onKey with values: \n"
|
|
<< "\tkey = "
|
|
<< k
|
|
<< "\n\tk_len = "
|
|
<< k_len
|
|
<< "\n\tm_key = "
|
|
<< m_key
|
|
<< "\n\t m_key_size = "
|
|
<< m_key.size()
|
|
<< "\n\t parser_depth = "
|
|
<< m_parser_depth;
|
|
if (m_key.size() + k_len < MAX_KEY_SIZE) {
|
|
m_key += std::string(k, k_len);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int BufferedReceiver::onValue(const char *v, size_t v_len)
|
|
{
|
|
int rc = 0;
|
|
dbgTrace(D_WAAP_PARSER)
|
|
<< "Entering BufferedReceiver::onValue with values: \n"
|
|
<< "\tvalue = "
|
|
<< v
|
|
<< "\n\tv_len = "
|
|
<< v_len
|
|
<< "\n\tm_value = "
|
|
<< m_value
|
|
<< "\n\t m_value_size = "
|
|
<< m_value.size()
|
|
<< "\n\t parser_depth = "
|
|
<< m_parser_depth;
|
|
while (v_len > 0) {
|
|
// Move data from buffer v to accumulated m_value string in an attempt to fill m_value to its max size
|
|
size_t bytesToFill = std::min(v_len, MAX_PROCESSING_BUFFER_SIZE - m_value.size());
|
|
m_value += std::string(v, bytesToFill);
|
|
// Update v and v_len (input buffer) to reflect that we already consumed part (or all) of it
|
|
v += bytesToFill;
|
|
v_len -= bytesToFill;
|
|
|
|
// Only push full buffers to the m_receiver
|
|
if (m_value.size() >= MAX_VALUE_SIZE) {
|
|
// The first full-size buffer will be pushed with BUFFERED_RECEIVER_F_FIRST flag
|
|
dbgTrace(D_WAAP_PARSER)
|
|
<< " The first full-size buffer will be pushed with BUFFERED_RECEIVER_F_FIRST flag"
|
|
<< "calling onKv() while m_flags = "
|
|
<< m_flags;
|
|
int tempRc= m_receiver.onKv(
|
|
m_key.data(),
|
|
m_key.size(),
|
|
m_value.data(),
|
|
m_value.size(),
|
|
m_flags,
|
|
m_parser_depth
|
|
);
|
|
if (tempRc != 0) {
|
|
rc = tempRc;
|
|
}
|
|
// Clear accumulted buffer that is already pushed (and processed) by the receiver
|
|
m_value.clear();
|
|
// Clear the "first buffer" flag for all the next buffers
|
|
m_flags &= ~BUFFERED_RECEIVER_F_FIRST;
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
int BufferedReceiver::onKvDone()
|
|
{
|
|
m_flags |= BUFFERED_RECEIVER_F_LAST; // set flag
|
|
// Call onKv on the remainder of the buffer not yet pushed to the receiver
|
|
// This must be called even if m_value is empty in order to signal the BUFFERED_RECEIVER_F_LAST flag to the
|
|
// receiver!
|
|
dbgTrace(D_WAAP_PARSER)
|
|
<< " Call onKv on the remainder of the buffer not yet pushed to the receiver calling onKv()";
|
|
int rc = onKv(m_key.data(), m_key.size(), m_value.data(), m_value.size(), m_flags, m_parser_depth);
|
|
|
|
// Reset the object's state to allow reuse for other parsers
|
|
clear();
|
|
return rc;
|
|
}
|
|
|
|
int BufferedReceiver::onKv(const char *k, size_t k_len, const char *v, size_t v_len, int flags, size_t parser_depth)
|
|
{
|
|
return m_receiver.onKv(k, k_len, v, v_len, flags, parser_depth);
|
|
}
|
|
|
|
void BufferedReceiver::clear()
|
|
{
|
|
m_flags = BUFFERED_RECEIVER_F_FIRST;
|
|
m_key.clear();
|
|
m_value.clear();
|
|
}
|