diff options
| author | Anand Avati <avati@redhat.com> | 2013-03-06 01:11:59 -0800 | 
|---|---|---|
| committer | Anand Avati <avati@redhat.com> | 2013-09-03 11:25:33 -0700 | 
| commit | 0d60175bd684cf6a14f750579d82dbd1ba97fcbc (patch) | |
| tree | 1571f530548196006526442f3fc027cb623bb6fa /contrib/qemu/qobject/json-streamer.c | |
| parent | 7dbfbfd3694e02b90e8f3ce509f5279da1523a02 (diff) | |
contrib/qemu: Import qemu block source code
This qemu block format source code and its minimal
dependency files will be used in the next patch to implement
a qemu-block format translator.
Change-Id: Ic87638972f7ea9b3df84d7a0539512a250c11c1c
BUG: 986775
Signed-off-by: Anand Avati <avati@redhat.com>
Reviewed-on: http://review.gluster.org/5366
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Diffstat (limited to 'contrib/qemu/qobject/json-streamer.c')
| -rw-r--r-- | contrib/qemu/qobject/json-streamer.c | 122 | 
1 files changed, 122 insertions, 0 deletions
diff --git a/contrib/qemu/qobject/json-streamer.c b/contrib/qemu/qobject/json-streamer.c new file mode 100644 index 00000000000..1b2f9b1d107 --- /dev/null +++ b/contrib/qemu/qobject/json-streamer.c @@ -0,0 +1,122 @@ +/* + * 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. + * + */ + +#include "qapi/qmp/qlist.h" +#include "qapi/qmp/qint.h" +#include "qapi/qmp/qdict.h" +#include "qemu-common.h" +#include "qapi/qmp/json-lexer.h" +#include "qapi/qmp/json-streamer.h" + +#define MAX_TOKEN_SIZE (64ULL << 20) +#define MAX_NESTING (1ULL << 10) + +static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTokenType type, int x, int y) +{ +    JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer); +    QDict *dict; + +    if (type == JSON_OPERATOR) { +        switch (qstring_get_str(token)[0]) { +        case '{': +            parser->brace_count++; +            break; +        case '}': +            parser->brace_count--; +            break; +        case '[': +            parser->bracket_count++; +            break; +        case ']': +            parser->bracket_count--; +            break; +        default: +            break; +        } +    } + +    dict = qdict_new(); +    qdict_put(dict, "type", qint_from_int(type)); +    QINCREF(token); +    qdict_put(dict, "token", token); +    qdict_put(dict, "x", qint_from_int(x)); +    qdict_put(dict, "y", qint_from_int(y)); + +    parser->token_size += token->length; + +    qlist_append(parser->tokens, dict); + +    if (type == JSON_ERROR) { +        goto out_emit_bad; +    } else if (parser->brace_count < 0 || +        parser->bracket_count < 0 || +        (parser->brace_count == 0 && +         parser->bracket_count == 0)) { +        goto out_emit; +    } else if (parser->token_size > MAX_TOKEN_SIZE || +               parser->bracket_count > MAX_NESTING || +               parser->brace_count > MAX_NESTING) { +        /* Security consideration, we limit total memory allocated per object +         * and the maximum recursion depth that a message can force. +         */ +        goto out_emit; +    } + +    return; + +out_emit_bad: +    /* clear out token list and tell the parser to emit and error +     * indication by passing it a NULL list +     */ +    QDECREF(parser->tokens); +    parser->tokens = NULL; +out_emit: +    /* send current list of tokens to parser and reset tokenizer */ +    parser->brace_count = 0; +    parser->bracket_count = 0; +    parser->emit(parser, parser->tokens); +    if (parser->tokens) { +        QDECREF(parser->tokens); +    } +    parser->tokens = qlist_new(); +    parser->token_size = 0; +} + +void json_message_parser_init(JSONMessageParser *parser, +                              void (*func)(JSONMessageParser *, QList *)) +{ +    parser->emit = func; +    parser->brace_count = 0; +    parser->bracket_count = 0; +    parser->tokens = qlist_new(); +    parser->token_size = 0; + +    json_lexer_init(&parser->lexer, json_message_process_token); +} + +int json_message_parser_feed(JSONMessageParser *parser, +                             const char *buffer, size_t size) +{ +    return json_lexer_feed(&parser->lexer, buffer, size); +} + +int json_message_parser_flush(JSONMessageParser *parser) +{ +    return json_lexer_flush(&parser->lexer); +} + +void json_message_parser_destroy(JSONMessageParser *parser) +{ +    json_lexer_destroy(&parser->lexer); +    QDECREF(parser->tokens); +}  | 
