File:  [Qemu by Fabrice Bellard] / qemu / json-streamer.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:56:39 2018 UTC (2 years, 1 month ago) by root
Branches: qemu, MAIN
CVS tags: qemu1101, qemu1001, qemu1000, qemu0151, HEAD
qemu 0.15.1

    1: /*
    2:  * JSON streaming support
    3:  *
    4:  * Copyright IBM, Corp. 2009
    5:  *
    6:  * Authors:
    7:  *  Anthony Liguori   <aliguori@us.ibm.com>
    8:  *
    9:  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
   10:  * See the COPYING.LIB file in the top-level directory.
   11:  *
   12:  */
   13: 
   14: #include "qlist.h"
   15: #include "qint.h"
   16: #include "qdict.h"
   17: #include "qemu-common.h"
   18: #include "json-lexer.h"
   19: #include "json-streamer.h"
   20: 
   21: #define MAX_TOKEN_SIZE (64ULL << 20)
   22: #define MAX_NESTING (1ULL << 10)
   23: 
   24: static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTokenType type, int x, int y)
   25: {
   26:     JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);
   27:     QDict *dict;
   28: 
   29:     if (type == JSON_OPERATOR) {
   30:         switch (qstring_get_str(token)[0]) {
   31:         case '{':
   32:             parser->brace_count++;
   33:             break;
   34:         case '}':
   35:             parser->brace_count--;
   36:             break;
   37:         case '[':
   38:             parser->bracket_count++;
   39:             break;
   40:         case ']':
   41:             parser->bracket_count--;
   42:             break;
   43:         default:
   44:             break;
   45:         }
   46:     }
   47: 
   48:     dict = qdict_new();
   49:     qdict_put(dict, "type", qint_from_int(type));
   50:     QINCREF(token);
   51:     qdict_put(dict, "token", token);
   52:     qdict_put(dict, "x", qint_from_int(x));
   53:     qdict_put(dict, "y", qint_from_int(y));
   54: 
   55:     parser->token_size += token->length;
   56: 
   57:     qlist_append(parser->tokens, dict);
   58: 
   59:     if (type == JSON_ERROR) {
   60:         goto out_emit_bad;
   61:     } else if (parser->brace_count < 0 ||
   62:         parser->bracket_count < 0 ||
   63:         (parser->brace_count == 0 &&
   64:          parser->bracket_count == 0)) {
   65:         goto out_emit;
   66:     } else if (parser->token_size > MAX_TOKEN_SIZE ||
   67:                parser->bracket_count > MAX_NESTING ||
   68:                parser->brace_count > MAX_NESTING) {
   69:         /* Security consideration, we limit total memory allocated per object
   70:          * and the maximum recursion depth that a message can force.
   71:          */
   72:         goto out_emit;
   73:     }
   74: 
   75:     return;
   76: 
   77: out_emit_bad:
   78:     /* clear out token list and tell the parser to emit and error
   79:      * indication by passing it a NULL list
   80:      */
   81:     QDECREF(parser->tokens);
   82:     parser->tokens = NULL;
   83: out_emit:
   84:     /* send current list of tokens to parser and reset tokenizer */
   85:     parser->brace_count = 0;
   86:     parser->bracket_count = 0;
   87:     parser->emit(parser, parser->tokens);
   88:     if (parser->tokens) {
   89:         QDECREF(parser->tokens);
   90:     }
   91:     parser->tokens = qlist_new();
   92:     parser->token_size = 0;
   93: }
   94: 
   95: void json_message_parser_init(JSONMessageParser *parser,
   96:                               void (*func)(JSONMessageParser *, QList *))
   97: {
   98:     parser->emit = func;
   99:     parser->brace_count = 0;
  100:     parser->bracket_count = 0;
  101:     parser->tokens = qlist_new();
  102:     parser->token_size = 0;
  103: 
  104:     json_lexer_init(&parser->lexer, json_message_process_token);
  105: }
  106: 
  107: int json_message_parser_feed(JSONMessageParser *parser,
  108:                              const char *buffer, size_t size)
  109: {
  110:     return json_lexer_feed(&parser->lexer, buffer, size);
  111: }
  112: 
  113: int json_message_parser_flush(JSONMessageParser *parser)
  114: {
  115:     return json_lexer_flush(&parser->lexer);
  116: }
  117: 
  118: void json_message_parser_destroy(JSONMessageParser *parser)
  119: {
  120:     json_lexer_destroy(&parser->lexer);
  121:     QDECREF(parser->tokens);
  122: }

unix.superglobalmegacorp.com