mirror of
https://github.com/openappsec/openappsec.git
synced 2025-06-28 16:41:02 +03:00
188 lines
5.5 KiB
C++
188 lines
5.5 KiB
C++
#include "ParserScreenedJson.h"
|
|
#include "debug.h"
|
|
|
|
USE_DEBUG_FLAG(D_WAAP_PARSER_SCREENED_JSON);
|
|
|
|
const std::string ParserScreenedJson::m_parserName = "ParserScreenedJson";
|
|
|
|
ParserScreenedJson::ParserScreenedJson(IParserStreamReceiver &receiver, size_t parser_depth) :
|
|
m_receiver(receiver),
|
|
m_state(s_start),
|
|
m_unscreenedLen(0),
|
|
m_leftoverLen(0),
|
|
m_parser_depth(parser_depth)
|
|
{
|
|
dbgTrace(D_WAAP_PARSER_SCREENED_JSON)
|
|
<< "parser_depth="
|
|
<< parser_depth;
|
|
|
|
memset(m_unscreened, 0, sizeof(m_unscreened));
|
|
}
|
|
|
|
ParserScreenedJson::~ParserScreenedJson()
|
|
{}
|
|
|
|
size_t
|
|
ParserScreenedJson::push(const char *buf, size_t len)
|
|
{
|
|
size_t i = 0;
|
|
char c;
|
|
|
|
dbgTrace(D_WAAP_PARSER_SCREENED_JSON) << "ParserScreenedJson::push(): starting (len=" << len << ")";
|
|
|
|
if (len == 0) {
|
|
dbgTrace(D_WAAP_PARSER_SCREENED_JSON) << "ParserScreenedJson::push(): end of data signal! m_state=" << m_state;
|
|
// flush unescaped data collected (if any)
|
|
if (m_leftoverLen > 0) {
|
|
// No need any processing for leftover data - last char must be doublequote, else - error
|
|
m_state = s_error;
|
|
dbgTrace(D_WAAP_PARSER_SCREENED_JSON)
|
|
<< "ParserScreenedJson::push(): end of data and leftover detected m_state="
|
|
<< m_state;
|
|
return i;
|
|
}
|
|
dbgTrace(D_WAAP_PARSER_SCREENED_JSON)
|
|
<< "ParserScreenedJson::push(): s_value, pushing m_unscreened = "
|
|
<< m_unscreened
|
|
<< ", m_leftoverLen = "
|
|
<< m_leftoverLen
|
|
<< ", m_unscreenedLen = "
|
|
<< m_unscreenedLen;
|
|
|
|
if (m_receiver.onKey("json_unscreened", 15) != 0) {
|
|
m_state = s_error;
|
|
return i;
|
|
}
|
|
|
|
if (m_receiver.onValue(m_unscreened, m_unscreenedLen) != 0) {
|
|
m_state = s_error;
|
|
return i;
|
|
}
|
|
|
|
if (m_receiver.onKvDone() != 0)
|
|
{
|
|
m_state = s_error;
|
|
return i;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
while (i < len)
|
|
{
|
|
c = buf[i];
|
|
|
|
dbgTrace(D_WAAP_PARSER_SCREENED_JSON)
|
|
<< "ParserScreenedJson::push(): state="
|
|
<< m_state
|
|
<< "; c='"
|
|
<< c
|
|
<< "'"
|
|
<< "; i="
|
|
<< i
|
|
<< ", m_leftoverLen = "
|
|
<< m_leftoverLen
|
|
<< ", m_unscreenedLen = "
|
|
<< m_unscreenedLen
|
|
<< ", m_unscreened = "
|
|
<< m_unscreened;
|
|
|
|
switch (m_state)
|
|
{
|
|
case s_start:
|
|
{
|
|
dbgTrace(D_WAAP_PARSER_SCREENED_JSON)
|
|
<< "ParserScreenedJson::push(): s_start";
|
|
m_state = s_value;
|
|
|
|
// fallthrough not required, removing 1st doublequote, it denoted by regex //
|
|
//CP_FALL_THROUGH;
|
|
break;
|
|
}
|
|
case s_value:
|
|
{
|
|
if (c == '\\') {
|
|
if (m_leftoverLen > 0) {
|
|
m_unscreened[m_unscreenedLen] = '\\';
|
|
m_leftoverLen = 0;
|
|
m_unscreenedLen++;
|
|
} else {
|
|
m_leftoverLen++;
|
|
}
|
|
} else if (c =='\"') {
|
|
if (m_leftoverLen > 0) {
|
|
m_unscreened[m_unscreenedLen] = '\"';
|
|
m_unscreenedLen++;
|
|
if (m_leftoverLen > 0) {
|
|
m_leftoverLen = 0;
|
|
}
|
|
}
|
|
} else {
|
|
if (m_leftoverLen > 0) {
|
|
m_unscreened[m_unscreenedLen] = '\\';
|
|
m_unscreenedLen++;
|
|
m_leftoverLen = 0;
|
|
}
|
|
m_unscreened[m_unscreenedLen] = c;
|
|
m_unscreenedLen++;
|
|
}
|
|
if (m_unscreenedLen >= MAX_UNSCREENED_JSON_SIZE) {
|
|
if (m_receiver.onKey("json_unscreened", 15) != 0) {
|
|
m_state = s_error;
|
|
return i;
|
|
}
|
|
dbgTrace(D_WAAP_PARSER_SCREENED_JSON)
|
|
<< "ParserScreenedJson::push(): s_value, pushing m_unscreened = "
|
|
<< m_unscreened
|
|
<< ", m_leftoverLen = "
|
|
<< m_leftoverLen
|
|
<< ", m_unscreenedLen = "
|
|
<< m_unscreenedLen;
|
|
if (m_receiver.onValue(m_unscreened, m_unscreenedLen) != 0) {
|
|
m_state = s_error;
|
|
return i;
|
|
}
|
|
m_unscreenedLen = 0;
|
|
}
|
|
break;
|
|
}
|
|
case s_error:
|
|
{
|
|
dbgTrace(D_WAAP_PARSER_SCREENED_JSON)
|
|
<< "ParserScreenedJson::push(): s_error";
|
|
return 0;
|
|
}
|
|
default:
|
|
{
|
|
dbgTrace(D_WAAP_PARSER_SCREENED_JSON)
|
|
<< "ParserScreenedJson::push(): JSON parser unrecoverable error";
|
|
m_state = s_error;
|
|
return 0;
|
|
}
|
|
}
|
|
++i;
|
|
}
|
|
|
|
dbgTrace(D_WAAP_PARSER_SCREENED_JSON)
|
|
<< "ParserScreenedJson::push(): finished: len="
|
|
<< len;
|
|
return len;
|
|
}
|
|
|
|
void
|
|
ParserScreenedJson::finish()
|
|
{
|
|
push(NULL, 0);
|
|
}
|
|
|
|
const std::string &
|
|
ParserScreenedJson::name() const
|
|
{
|
|
return m_parserName;
|
|
}
|
|
|
|
bool
|
|
ParserScreenedJson::error() const
|
|
{
|
|
return m_state == s_error;
|
|
}
|