2
0

json-streamer.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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. #include "qapi/qmp/qlist.h"
  14. #include "qapi/qmp/qint.h"
  15. #include "qapi/qmp/qdict.h"
  16. #include "qemu-common.h"
  17. #include "qapi/qmp/json-lexer.h"
  18. #include "qapi/qmp/json-streamer.h"
  19. #define MAX_TOKEN_SIZE (64ULL << 20)
  20. #define MAX_NESTING (1ULL << 10)
  21. static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTokenType type, int x, int y)
  22. {
  23. JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);
  24. QDict *dict;
  25. if (type == JSON_OPERATOR) {
  26. switch (qstring_get_str(token)[0]) {
  27. case '{':
  28. parser->brace_count++;
  29. break;
  30. case '}':
  31. parser->brace_count--;
  32. break;
  33. case '[':
  34. parser->bracket_count++;
  35. break;
  36. case ']':
  37. parser->bracket_count--;
  38. break;
  39. default:
  40. break;
  41. }
  42. }
  43. dict = qdict_new();
  44. qdict_put(dict, "type", qint_from_int(type));
  45. QINCREF(token);
  46. qdict_put(dict, "token", token);
  47. qdict_put(dict, "x", qint_from_int(x));
  48. qdict_put(dict, "y", qint_from_int(y));
  49. parser->token_size += token->length;
  50. qlist_append(parser->tokens, dict);
  51. if (type == JSON_ERROR) {
  52. goto out_emit_bad;
  53. } else if (parser->brace_count < 0 ||
  54. parser->bracket_count < 0 ||
  55. (parser->brace_count == 0 &&
  56. parser->bracket_count == 0)) {
  57. goto out_emit;
  58. } else if (parser->token_size > MAX_TOKEN_SIZE ||
  59. parser->bracket_count > MAX_NESTING ||
  60. parser->brace_count > MAX_NESTING) {
  61. /* Security consideration, we limit total memory allocated per object
  62. * and the maximum recursion depth that a message can force.
  63. */
  64. goto out_emit;
  65. }
  66. return;
  67. out_emit_bad:
  68. /* clear out token list and tell the parser to emit and error
  69. * indication by passing it a NULL list
  70. */
  71. QDECREF(parser->tokens);
  72. parser->tokens = NULL;
  73. out_emit:
  74. /* send current list of tokens to parser and reset tokenizer */
  75. parser->brace_count = 0;
  76. parser->bracket_count = 0;
  77. parser->emit(parser, parser->tokens);
  78. if (parser->tokens) {
  79. QDECREF(parser->tokens);
  80. }
  81. parser->tokens = qlist_new();
  82. parser->token_size = 0;
  83. }
  84. void json_message_parser_init(JSONMessageParser *parser,
  85. void (*func)(JSONMessageParser *, QList *))
  86. {
  87. parser->emit = func;
  88. parser->brace_count = 0;
  89. parser->bracket_count = 0;
  90. parser->tokens = qlist_new();
  91. parser->token_size = 0;
  92. json_lexer_init(&parser->lexer, json_message_process_token);
  93. }
  94. int json_message_parser_feed(JSONMessageParser *parser,
  95. const char *buffer, size_t size)
  96. {
  97. return json_lexer_feed(&parser->lexer, buffer, size);
  98. }
  99. int json_message_parser_flush(JSONMessageParser *parser)
  100. {
  101. return json_lexer_flush(&parser->lexer);
  102. }
  103. void json_message_parser_destroy(JSONMessageParser *parser)
  104. {
  105. json_lexer_destroy(&parser->lexer);
  106. QDECREF(parser->tokens);
  107. }