2009-11-11 19:38:59 +03:00
/*
* JSON streaming support
*
* Copyright IBM , Corp . 2009
*
* Authors :
* Anthony Liguori < aliguori @ us . ibm . com >
*
* This work is licensed under the terms of the GNU LGPL , version 2.1 or later .
* See the COPYING . LIB file in the top - level directory .
*
*/
2016-01-29 20:50:01 +03:00
# include "qemu/osdep.h"
2018-08-23 19:40:06 +03:00
# include "qapi/error.h"
2018-08-23 19:40:20 +03:00
# include "json-parser-int.h"
2009-11-11 19:38:59 +03:00
2011-06-01 21:14:53 +04:00
# define MAX_TOKEN_SIZE (64ULL << 20)
2015-11-26 00:23:33 +03:00
# define MAX_TOKEN_COUNT (2ULL << 20)
2018-08-23 19:40:15 +03:00
# define MAX_NESTING (1 << 10)
2011-06-01 21:14:53 +04:00
2015-11-26 00:23:31 +03:00
static void json_message_free_tokens ( JSONMessageParser * parser )
{
2018-08-23 19:40:17 +03:00
JSONToken * token ;
while ( ( token = g_queue_pop_head ( & parser - > tokens ) ) ) {
g_free ( token ) ;
2015-11-26 00:23:31 +03:00
}
}
2018-08-23 19:40:00 +03:00
void json_message_process_token ( JSONLexer * lexer , GString * input ,
JSONTokenType type , int x , int y )
2009-11-11 19:38:59 +03:00
{
JSONMessageParser * parser = container_of ( lexer , JSONMessageParser , lexer ) ;
2018-08-23 19:40:02 +03:00
QObject * json = NULL ;
2018-08-23 19:40:01 +03:00
Error * err = NULL ;
2015-11-26 00:23:32 +03:00
JSONToken * token ;
2009-11-11 19:38:59 +03:00
2015-11-26 00:23:26 +03:00
switch ( type ) {
case JSON_LCURLY :
parser - > brace_count + + ;
break ;
case JSON_RCURLY :
parser - > brace_count - - ;
break ;
case JSON_LSQUARE :
parser - > bracket_count + + ;
break ;
case JSON_RSQUARE :
parser - > bracket_count - - ;
break ;
2018-08-23 19:40:03 +03:00
case JSON_ERROR :
2018-08-23 19:40:06 +03:00
error_setg ( & err , " JSON parse error, stray '%s' " , input - > str ) ;
2018-08-23 19:40:03 +03:00
goto out_emit ;
2018-08-23 19:40:12 +03:00
case JSON_END_OF_INPUT :
2018-08-23 19:40:17 +03:00
if ( g_queue_is_empty ( & parser - > tokens ) ) {
2018-08-23 19:40:12 +03:00
return ;
}
2018-08-23 19:40:17 +03:00
json = json_parser_parse ( & parser - > tokens , parser - > ap , & err ) ;
2018-08-23 19:40:12 +03:00
goto out_emit ;
2015-11-26 00:23:26 +03:00
default :
break ;
2009-11-11 19:38:59 +03:00
}
2018-08-23 19:40:15 +03:00
/*
* Security consideration , we limit total memory allocated per object
* and the maximum recursion depth that a message can force .
*/
if ( parser - > token_size + input - > len + 1 > MAX_TOKEN_SIZE ) {
error_setg ( & err , " JSON token size limit exceeded " ) ;
goto out_emit ;
}
2018-08-23 19:40:17 +03:00
if ( g_queue_get_length ( & parser - > tokens ) + 1 > MAX_TOKEN_COUNT ) {
2018-08-23 19:40:15 +03:00
error_setg ( & err , " JSON token count limit exceeded " ) ;
goto out_emit ;
}
if ( parser - > bracket_count + parser - > brace_count > MAX_NESTING ) {
error_setg ( & err , " JSON nesting depth limit exceeded " ) ;
goto out_emit ;
}
2018-08-23 19:40:18 +03:00
token = json_token ( type , x , y , input ) ;
2015-11-26 00:23:29 +03:00
parser - > token_size + = input - > len ;
2011-06-01 21:14:53 +04:00
2018-08-23 19:40:17 +03:00
g_queue_push_tail ( & parser - > tokens , token ) ;
2009-11-11 19:38:59 +03:00
2018-08-23 19:40:16 +03:00
if ( ( parser - > brace_count > 0 | | parser - > bracket_count > 0 )
2020-04-02 21:28:48 +03:00
& & parser - > brace_count > = 0 & & parser - > bracket_count > = 0 ) {
2018-08-23 19:40:16 +03:00
return ;
2018-08-23 19:40:02 +03:00
}
2018-08-23 19:40:17 +03:00
json = json_parser_parse ( & parser - > tokens , parser - > ap , & err ) ;
2011-06-01 21:14:59 +04:00
out_emit :
parser - > brace_count = 0 ;
parser - > bracket_count = 0 ;
2018-08-23 19:40:02 +03:00
json_message_free_tokens ( parser ) ;
2011-06-01 21:14:59 +04:00
parser - > token_size = 0 ;
2018-08-23 19:40:01 +03:00
parser - > emit ( parser - > opaque , json , err ) ;
2009-11-11 19:38:59 +03:00
}
void json_message_parser_init ( JSONMessageParser * parser ,
2018-08-23 19:40:01 +03:00
void ( * emit ) ( void * opaque , QObject * json ,
Error * err ) ,
void * opaque , va_list * ap )
2009-11-11 19:38:59 +03:00
{
2018-08-23 19:40:01 +03:00
parser - > emit = emit ;
parser - > opaque = opaque ;
parser - > ap = ap ;
2009-11-11 19:38:59 +03:00
parser - > brace_count = 0 ;
parser - > bracket_count = 0 ;
2018-08-23 19:40:17 +03:00
g_queue_init ( & parser - > tokens ) ;
2011-06-01 21:14:53 +04:00
parser - > token_size = 0 ;
2009-11-11 19:38:59 +03:00
2018-08-23 19:40:05 +03:00
json_lexer_init ( & parser - > lexer , ! ! ap ) ;
2009-11-11 19:38:59 +03:00
}
2018-08-23 19:39:58 +03:00
void json_message_parser_feed ( JSONMessageParser * parser ,
2009-11-11 19:38:59 +03:00
const char * buffer , size_t size )
{
2018-08-23 19:39:58 +03:00
json_lexer_feed ( & parser - > lexer , buffer , size ) ;
2009-11-11 19:38:59 +03:00
}
2018-08-23 19:39:58 +03:00
void json_message_parser_flush ( JSONMessageParser * parser )
2009-11-11 19:38:59 +03:00
{
2018-08-23 19:39:58 +03:00
json_lexer_flush ( & parser - > lexer ) ;
2018-08-23 19:40:17 +03:00
assert ( g_queue_is_empty ( & parser - > tokens ) ) ;
2009-11-11 19:38:59 +03:00
}
void json_message_parser_destroy ( JSONMessageParser * parser )
{
json_lexer_destroy ( & parser - > lexer ) ;
2015-11-26 00:23:31 +03:00
json_message_free_tokens ( parser ) ;
2009-11-11 19:38:59 +03:00
}