Annotation of qemu/json-streamer.c, revision 1.1.1.3

1.1       root        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: 
1.1.1.3 ! root       21: #define MAX_TOKEN_SIZE (64ULL << 20)
        !            22: #define MAX_NESTING (1ULL << 10)
        !            23: 
1.1       root       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();
1.1.1.2   root       49:     qdict_put(dict, "type", qint_from_int(type));
1.1       root       50:     QINCREF(token);
1.1.1.2   root       51:     qdict_put(dict, "token", token);
                     52:     qdict_put(dict, "x", qint_from_int(x));
                     53:     qdict_put(dict, "y", qint_from_int(y));
1.1       root       54: 
1.1.1.3 ! root       55:     parser->token_size += token->length;
        !            56: 
1.1       root       57:     qlist_append(parser->tokens, dict);
                     58: 
1.1.1.3 ! root       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) {
1.1       root       89:         QDECREF(parser->tokens);
                     90:     }
1.1.1.3 ! root       91:     parser->tokens = qlist_new();
        !            92:     parser->token_size = 0;
1.1       root       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();
1.1.1.3 ! root      102:     parser->token_size = 0;
1.1       root      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