mirror of
https://github.com/openappsec/openappsec.git
synced 2025-10-01 12:07:43 +03:00
Nov_12_2023-Dev
This commit is contained in:
@@ -20,17 +20,21 @@
|
||||
#include <assert.h>
|
||||
|
||||
USE_DEBUG_FLAG(D_WAAP_PARSER_JSON);
|
||||
USE_DEBUG_FLAG(D_OA_SCHEMA_UPDATER);
|
||||
|
||||
const std::string ParserJson::m_parserName = "jsonParser";
|
||||
|
||||
int ParserJson::cb_null() {
|
||||
int
|
||||
ParserJson::cb_null()
|
||||
{
|
||||
dbgTrace(D_WAAP_PARSER_JSON) << "ParserJson::cb_null():";
|
||||
|
||||
|
||||
if (m_receiver2) {
|
||||
m_receiver2->onKvt(m_key.c_str(), m_key.size(), "null", 4, DataType::EMPTY);
|
||||
}
|
||||
|
||||
if (m_receiver.onKv(m_key.c_str(), m_key.size(), "null", 4, BUFFERED_RECEIVER_F_BOTH)) {
|
||||
if (m_receiver.onKv(m_key.c_str(), m_key.size(), "null", 4, BUFFERED_RECEIVER_F_BOTH, m_parser_depth)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -41,20 +45,22 @@ int ParserJson::cb_null() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ParserJson::cb_boolean(int boolean) {
|
||||
int
|
||||
ParserJson::cb_boolean(int boolean)
|
||||
{
|
||||
dbgTrace(D_WAAP_PARSER_JSON) << "ParserJson::cb_boolean(): " << boolean;
|
||||
|
||||
|
||||
if (m_receiver2) {
|
||||
m_receiver2->onKvt(m_key.c_str(), m_key.size(), NULL, boolean, DataType::BOOLEAN);
|
||||
}
|
||||
|
||||
if (boolean) {
|
||||
if (m_receiver.onKv(m_key.c_str(), m_key.size(), "true", 4, BUFFERED_RECEIVER_F_BOTH)) {
|
||||
if (m_receiver.onKv(m_key.c_str(), m_key.size(), "true", 4, BUFFERED_RECEIVER_F_BOTH, m_parser_depth)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (m_receiver.onKv(m_key.c_str(), m_key.size(), "false", 5, BUFFERED_RECEIVER_F_BOTH)) {
|
||||
} else {
|
||||
if (m_receiver.onKv(m_key.c_str(), m_key.size(), "false", 5, BUFFERED_RECEIVER_F_BOTH, m_parser_depth)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -65,14 +71,16 @@ int ParserJson::cb_boolean(int boolean) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ParserJson::cb_number(const char* s, yajl_size_t slen) {
|
||||
int
|
||||
ParserJson::cb_number(const char *s, yajl_size_t slen)
|
||||
{
|
||||
dbgTrace(D_WAAP_PARSER_JSON) << "ParserJson::cb_number(): '" << std::string(s, slen) << "'";
|
||||
|
||||
if (m_receiver2) {
|
||||
m_receiver2->onKvt(m_key.c_str(), m_key.size(), s, slen, DataType::NUMBER);
|
||||
}
|
||||
|
||||
if (m_receiver.onKv(m_key.c_str(), m_key.size(), s, slen, BUFFERED_RECEIVER_F_BOTH)) {
|
||||
if (m_receiver.onKv(m_key.c_str(), m_key.size(), s, slen, BUFFERED_RECEIVER_F_BOTH, m_parser_depth)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -82,14 +90,19 @@ int ParserJson::cb_number(const char* s, yajl_size_t slen) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ParserJson::cb_string(const unsigned char* s, yajl_size_t slen) {
|
||||
dbgTrace(D_WAAP_PARSER_JSON) << "ParserJson::cb_string(): '" << std::string((const char*)s, slen) << "'";
|
||||
int
|
||||
ParserJson::cb_string(const unsigned char *s, yajl_size_t slen)
|
||||
{
|
||||
dbgTrace(D_WAAP_PARSER_JSON) << "ParserJson::cb_string(): '" << std::string((const char *)s, slen) << "'";
|
||||
|
||||
if (m_receiver2) {
|
||||
m_receiver2->onKvt(m_key.c_str(), m_key.size(), (const char*)s, slen, DataType::STRING);
|
||||
}
|
||||
|
||||
if (m_receiver.onKv(m_key.c_str(), m_key.size(), (const char*)s, slen, BUFFERED_RECEIVER_F_BOTH)) {
|
||||
|
||||
if (m_receiver.onKv(
|
||||
m_key.c_str(), m_key.size(), (const char *)s, slen, BUFFERED_RECEIVER_F_BOTH, m_parser_depth
|
||||
)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -99,8 +112,10 @@ int ParserJson::cb_string(const unsigned char* s, yajl_size_t slen) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ParserJson::cb_map_key(const unsigned char* s, yajl_size_t slen) {
|
||||
dbgTrace(D_WAAP_PARSER_JSON) << "ParserJson::cb_map_key(): '" << std::string((const char*)s, slen) << "'";
|
||||
int
|
||||
ParserJson::cb_map_key(const unsigned char *s, yajl_size_t slen)
|
||||
{
|
||||
dbgTrace(D_WAAP_PARSER_JSON) << "ParserJson::cb_map_key(): '" << std::string((const char *)s, slen) << "'";
|
||||
|
||||
m_key.push((char*)s, slen);
|
||||
|
||||
@@ -111,7 +126,9 @@ int ParserJson::cb_map_key(const unsigned char* s, yajl_size_t slen) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ParserJson::cb_start_map() {
|
||||
int
|
||||
ParserJson::cb_start_map()
|
||||
{
|
||||
dbgTrace(D_WAAP_PARSER_JSON) << "ParserJson::cb_start_map():";
|
||||
|
||||
if (m_receiver2) {
|
||||
@@ -122,7 +139,9 @@ int ParserJson::cb_start_map() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ParserJson::cb_end_map() {
|
||||
int
|
||||
ParserJson::cb_end_map()
|
||||
{
|
||||
dbgTrace(D_WAAP_PARSER_JSON) << "ParserJson::cb_end_map():";
|
||||
|
||||
if (m_receiver2) {
|
||||
@@ -140,7 +159,9 @@ int ParserJson::cb_end_map() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ParserJson::cb_start_array() {
|
||||
int
|
||||
ParserJson::cb_start_array()
|
||||
{
|
||||
dbgTrace(D_WAAP_PARSER_JSON) << "ParserJson::cb_start_array():";
|
||||
|
||||
if (m_receiver2) {
|
||||
@@ -151,7 +172,9 @@ int ParserJson::cb_start_array() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ParserJson::cb_end_array() {
|
||||
int
|
||||
ParserJson::cb_end_array()
|
||||
{
|
||||
dbgTrace(D_WAAP_PARSER_JSON) << "ParserJson::cb_end_array():";
|
||||
|
||||
if (m_receiver2) {
|
||||
@@ -162,6 +185,7 @@ int ParserJson::cb_end_array() {
|
||||
m_depthStack.pop_back();
|
||||
}
|
||||
|
||||
|
||||
if (!m_depthStack.empty() && m_depthStack.back() == js_map) {
|
||||
m_key.pop("json end array");
|
||||
}
|
||||
@@ -169,51 +193,78 @@ int ParserJson::cb_end_array() {
|
||||
}
|
||||
|
||||
// Static functions to be called from C and forward the calls to respective class cb_* methods
|
||||
int ParserJson::p_null(void* ctx)
|
||||
int
|
||||
ParserJson::p_null(void *ctx)
|
||||
{
|
||||
return ((ParserJson*)ctx)->cb_null();
|
||||
}
|
||||
int ParserJson::p_boolean(void* ctx, int boolean)
|
||||
|
||||
int
|
||||
ParserJson::p_boolean(void *ctx, int boolean)
|
||||
{
|
||||
return ((ParserJson*)ctx)->cb_boolean(boolean);
|
||||
}
|
||||
int ParserJson::p_number(void* ctx, const char* s, yajl_size_t slen)
|
||||
|
||||
int
|
||||
ParserJson::p_number(void *ctx, const char *s, yajl_size_t slen)
|
||||
{
|
||||
return ((ParserJson*)ctx)->cb_number(s, slen);
|
||||
}
|
||||
int ParserJson::p_string(void* ctx, const unsigned char* s, yajl_size_t slen)
|
||||
|
||||
int
|
||||
ParserJson::p_string(void *ctx, const unsigned char *s, yajl_size_t slen)
|
||||
{
|
||||
return ((ParserJson*)ctx)->cb_string(s, slen);
|
||||
}
|
||||
int ParserJson::p_map_key(void* ctx, const unsigned char* s, yajl_size_t slen)
|
||||
|
||||
int
|
||||
ParserJson::p_map_key(void *ctx, const unsigned char *s, yajl_size_t slen)
|
||||
{
|
||||
return ((ParserJson*)ctx)->cb_map_key(s, slen);
|
||||
}
|
||||
int ParserJson::p_start_map(void* ctx)
|
||||
|
||||
int
|
||||
ParserJson::p_start_map(void *ctx)
|
||||
{
|
||||
return ((ParserJson*)ctx)->cb_start_map();
|
||||
}
|
||||
int ParserJson::p_end_map(void* ctx)
|
||||
|
||||
int
|
||||
ParserJson::p_end_map(void *ctx)
|
||||
{
|
||||
return ((ParserJson*)ctx)->cb_end_map();
|
||||
}
|
||||
int ParserJson::p_start_array(void* ctx)
|
||||
|
||||
int
|
||||
ParserJson::p_start_array(void *ctx)
|
||||
{
|
||||
return ((ParserJson*)ctx)->cb_start_array();
|
||||
}
|
||||
int ParserJson::p_end_array(void* ctx)
|
||||
|
||||
int
|
||||
ParserJson::p_end_array(void *ctx)
|
||||
{
|
||||
return ((ParserJson*)ctx)->cb_end_array();
|
||||
}
|
||||
|
||||
ParserJson::ParserJson(IParserReceiver& receiver, IParserReceiver2* receiver2) :
|
||||
ParserJson::ParserJson(
|
||||
IParserReceiver &receiver,
|
||||
bool should_collect_oas,
|
||||
size_t parser_depth,
|
||||
IParserReceiver2 *receiver2)
|
||||
:
|
||||
m_receiver(receiver),
|
||||
m_receiver2(receiver2),
|
||||
m_state(s_start),
|
||||
m_bufLen(0),
|
||||
m_key("json_parser"),
|
||||
m_jsonHandler(NULL)
|
||||
m_jsonHandler(NULL),
|
||||
is_map_empty(false),
|
||||
should_collect_for_oa_schema_updater(should_collect_oas),
|
||||
m_parser_depth(parser_depth)
|
||||
{
|
||||
dbgTrace(D_WAAP_PARSER_JSON) << "parser_depth= " << parser_depth;
|
||||
|
||||
// TODO:: do we really want to clear this?
|
||||
memset(m_buf, 0, sizeof(m_buf));
|
||||
|
||||
@@ -232,7 +283,7 @@ ParserJson::ParserJson(IParserReceiver& receiver, IParserReceiver2* receiver2) :
|
||||
};
|
||||
|
||||
m_jsonHandler = yajl_alloc(&callbacks, NULL, this);
|
||||
|
||||
|
||||
if (m_jsonHandler == NULL) {
|
||||
dbgTrace(D_WAAP_PARSER_JSON) << "ParserJson::ParserJson(): yajl_alloc() failed. Switching to s_error state.";
|
||||
m_state = s_error;
|
||||
@@ -249,7 +300,8 @@ ParserJson::ParserJson(IParserReceiver& receiver, IParserReceiver2* receiver2) :
|
||||
m_key.push("json", 4);
|
||||
}
|
||||
|
||||
ParserJson::~ParserJson() {
|
||||
ParserJson::~ParserJson()
|
||||
{
|
||||
// Cleanup JSON
|
||||
dbgTrace(D_WAAP_PARSER_JSON) << "ParserJson::~ParserJson():";
|
||||
|
||||
@@ -258,7 +310,9 @@ ParserJson::~ParserJson() {
|
||||
}
|
||||
}
|
||||
|
||||
size_t ParserJson::push(const char* buf, size_t len) {
|
||||
size_t
|
||||
ParserJson::push(const char *buf, size_t len)
|
||||
{
|
||||
size_t i = 0;
|
||||
char c;
|
||||
|
||||
@@ -280,6 +334,7 @@ size_t ParserJson::push(const char* buf, size_t len) {
|
||||
while (i < len) {
|
||||
c = buf[i];
|
||||
|
||||
|
||||
switch (m_state) {
|
||||
case s_start:
|
||||
dbgTrace(D_WAAP_PARSER_JSON) << "ParserJson::push(): s_start";
|
||||
@@ -288,8 +343,12 @@ size_t ParserJson::push(const char* buf, size_t len) {
|
||||
// fallthrough //
|
||||
CP_FALL_THROUGH;
|
||||
case s_accumulate_first_bytes:
|
||||
dbgTrace(D_WAAP_PARSER_JSON) << "ParserJson::push(): s_accumulate_first_bytes. i=" << i <<
|
||||
" c='" << buf[i] << "'";
|
||||
dbgTrace(D_WAAP_PARSER_JSON)
|
||||
<< "ParserJson::push(): s_accumulate_first_bytes. i="
|
||||
<< i
|
||||
<< " c='"
|
||||
<< buf[i]
|
||||
<< "'";
|
||||
m_buf[m_bufLen] = c;
|
||||
m_bufLen++;
|
||||
if (m_bufLen == FIRST_JSON_BUFFER_SIZE) {
|
||||
@@ -298,15 +357,23 @@ size_t ParserJson::push(const char* buf, size_t len) {
|
||||
break;
|
||||
|
||||
case s_start_parsing:
|
||||
dbgTrace(D_WAAP_PARSER_JSON) << "ParserJson::push(): s_start_parsing. sending len=" <<
|
||||
(int)m_bufLen << ": '" << std::string(m_buf, m_bufLen) << "'";
|
||||
dbgTrace(D_WAAP_PARSER_JSON)
|
||||
<< "ParserJson::push(): s_start_parsing. sending len="
|
||||
<< (int)m_bufLen
|
||||
<< ": '"
|
||||
<< std::string(m_buf, m_bufLen)
|
||||
<< "'";
|
||||
m_state = s_parsing;
|
||||
|
||||
// fallthrough //
|
||||
CP_FALL_THROUGH;
|
||||
case s_parsing:
|
||||
dbgTrace(D_WAAP_PARSER_JSON) << "ParserJson::push(): s_parsing. sending len=" << (int)(len - i) << ": '" <<
|
||||
std::string(buf + i, len - i) << "'";
|
||||
dbgTrace(D_WAAP_PARSER_JSON)
|
||||
<< "ParserJson::push(): s_parsing. sending len="
|
||||
<< (int)(len - i)
|
||||
<< ": '"
|
||||
<< std::string(buf + i, len - i)
|
||||
<< "'";
|
||||
if (m_bufLen > 0) {
|
||||
// Send accumulated bytes (if any)
|
||||
if (yajl_parse(m_jsonHandler, (unsigned char*)m_buf, m_bufLen) != yajl_status_ok) {
|
||||
@@ -333,15 +400,20 @@ size_t ParserJson::push(const char* buf, size_t len) {
|
||||
return len;
|
||||
}
|
||||
|
||||
void ParserJson::finish() {
|
||||
void
|
||||
ParserJson::finish()
|
||||
{
|
||||
push(NULL, 0);
|
||||
}
|
||||
|
||||
const std::string &
|
||||
ParserJson::name() const {
|
||||
ParserJson::name() const
|
||||
{
|
||||
return m_parserName;
|
||||
}
|
||||
|
||||
bool ParserJson::error() const {
|
||||
bool
|
||||
ParserJson::error() const
|
||||
{
|
||||
return m_state == s_error;
|
||||
}
|
||||
|
Reference in New Issue
Block a user