]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Drop original JSON parser implementation
authorStephan Bosch <stephan.bosch@open-xchange.com>
Tue, 8 Oct 2019 18:15:14 +0000 (20:15 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Sat, 18 Nov 2023 18:58:04 +0000 (18:58 +0000)
25 files changed:
src/lib-json/Makefile.am
src/lib-json/json-generator.h
src/lib-json/json-istream.h
src/lib-json/json-ostream.h
src/lib-json/json-parser.c [moved from src/lib-json/json-parser.new.c with 99% similarity]
src/lib-json/json-parser.h [moved from src/lib-json/json-parser.new.h with 97% similarity]
src/lib-json/json-text.h
src/lib-json/json-tree-io.h
src/lib-json/json-tree.c [moved from src/lib-json/json-tree.new.c with 99% similarity]
src/lib-json/json-tree.h [moved from src/lib-json/json-tree.new.h with 100% similarity]
src/lib-json/test-json-io.c
src/lib-json/test-json-parser.c
src/lib-json/test-json-tree.c
src/lib-oauth2/oauth2-jwt.c
src/lib/Makefile.am
src/lib/istream-jsonstr.c [deleted file]
src/lib/istream-jsonstr.h [deleted file]
src/lib/json-parser.c [deleted file]
src/lib/json-parser.h [deleted file]
src/lib/json-tree.c [deleted file]
src/lib/json-tree.h [deleted file]
src/lib/test-istream-jsonstr.c [deleted file]
src/lib/test-json-parser.c [deleted file]
src/lib/test-json-tree.c [deleted file]
src/lib/test-lib.inc

index 661a88e74f3a93e41d056c6bf2a1d227a119bb9c..d0c1ce6437c7bf91cded600bfcdf025cbdb3471d 100644 (file)
@@ -7,9 +7,9 @@ AM_CPPFLAGS = \
 libjson_la_SOURCES = \
        json-syntax.c \
        json-types.c \
-       json-tree.new.c \
+       json-tree.c \
        json-tree-io.c \
-       json-parser.new.c \
+       json-parser.c \
        json-generator.c \
        json-istream.c \
        json-ostream.c \
@@ -19,9 +19,9 @@ libjson_la_LIBADD = -lm
 headers = \
        json-syntax.h \
        json-types.h \
-       json-tree.new.h \
+       json-tree.h \
        json-tree-io.h \
-       json-parser.new.h \
+       json-parser.h \
        json-generator.h \
        json-istream.h \
        json-ostream.h \
index 7a833d99d6ca1df060013085956e441cae35a0fd..58db575e424800989f334c9c313214a4f254729e 100644 (file)
@@ -3,9 +3,6 @@
 
 #include "json-types.h"
 
-#define json_append_escaped json_append_escaped_new
-#define json_append_escaped_data json_append_escaped_data_new
-
 // FIXME: add settings for formatting/indenting the output
 
 struct json_generator;
index cf260f6818eaedb49ae9f3f71535a1a8e6f7c7aa..51463df860f61855dc8e4421621a86e900c4772f 100644 (file)
@@ -1,8 +1,8 @@
 #ifndef JSON_ISTREAM_H
 #define JSON_ISTREAM_H
 
-#include "json-tree.new.h"
-#include "json-parser.new.h"
+#include "json-tree.h"
+#include "json-parser.h"
 
 // FIXME: don't bother recording values if we're only validating/skipping
 
index da9d48df180bedc93dc2af4379ae0a88a38f4a85..8f475f1bc4aec233d86ec78df48c38dd2d5229b5 100644 (file)
@@ -4,7 +4,7 @@
 #include "lib.h"
 
 #include "json-types.h"
-#include "json-tree.new.h"
+#include "json-tree.h"
 #include "json-generator.h"
 
 struct json_ostream;
similarity index 99%
rename from src/lib-json/json-parser.new.c
rename to src/lib-json/json-parser.c
index f0f734f93751a0b7725d9605bd8b2bf65483cb7a..5e248132bca905bfb2bcdf5313ddec32b55287b4 100644 (file)
@@ -8,7 +8,7 @@
 #include "istream-private.h"
 
 #include "json-syntax.h"
-#include "json-parser.new.h"
+#include "json-parser.h"
 
 #include <stdlib.h>
 #include <math.h>
similarity index 97%
rename from src/lib-json/json-parser.new.h
rename to src/lib-json/json-parser.h
index 0b5a15c3bcf1f341603ca093cf34456731c385c2..92a8aa1ad97cb1045cd3b8ffa216883b19b0713a 100644 (file)
@@ -3,9 +3,6 @@
 
 #include "json-types.h"
 
-#define json_parser_init json_parser_new_init
-#define json_parser_deinit json_parser_new_deinit
-
 // FIXME: don't bother recording values if we're only validating.
 
 /*
index 644cc1ae164eeb08cc71f9f79d75769dc2ff9f25..754c5957c657a235c1f40e464430707da11bf12b 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef JSON_TEXT_H
 #define JSON_TEXT_H
 
-#include "json-parser.new.h"
+#include "json-parser.h"
 #include "json-generator.h"
 
 int json_text_format_data(const void *data, size_t size,
index dad89915f57fe01662653eaf9bfb7309036d3dab..7909baa9c3756496f99d23f9712861e5198f0f44 100644 (file)
@@ -1,8 +1,8 @@
 #ifndef JSON_TREE_IO_H
 #define JSON_TREE_IO_H
 
-#include "json-tree.new.h"
-#include "json-parser.new.h"
+#include "json-tree.h"
+#include "json-parser.h"
 #include "json-generator.h"
 
 /*
similarity index 99%
rename from src/lib-json/json-tree.new.c
rename to src/lib-json/json-tree.c
index 2728232a54687e06018d95cda9808d571e24a744..4d4689a82c6ed780feed02a854b5d492846de582 100644 (file)
@@ -5,7 +5,7 @@
 #include "array.h"
 #include "istream.h"
 
-#include "json-tree.new.h"
+#include "json-tree.h"
 
 struct json_tree_node_list {
        struct json_tree_node *head, *tail;
index ccbefc94e9c32deedb77cca463828e162cc2b739..b98fca80f52cb3d4c32000d9733ca8a314bc9f58 100644 (file)
@@ -9,7 +9,7 @@
 #include "iostream-pump.h"
 #include "test-common.h"
 
-#include "json-parser.new.h"
+#include "json-parser.h"
 #include "json-generator.h"
 #include "json-istream.h"
 #include "json-ostream.h"
index fdbd7ca3a44fabe1232aff193c88bf59b11c59ad..5cb8c1e74d2879d7ea7e1d763a81cf9a9e09bed3 100644 (file)
@@ -7,7 +7,7 @@
 #include "istream-base64.h"
 #include "test-common.h"
 
-#include "json-parser.new.h"
+#include "json-parser.h"
 
 #include <unistd.h>
 
index 63c6ccd358d6f822b93069e0909c0280bbcb8005..b5fa84bbbb1842b776ebee87dba0b6fa77bb5e87 100644 (file)
@@ -6,7 +6,7 @@
 #include "ostream.h"
 #include "test-common.h"
 
-#include "json-tree.new.h"
+#include "json-tree.h"
 
 #include <unistd.h>
 
index 21c807a90c990722eab26927da8ea05a751e33f9..73df41fcf0042344fc78234b92d52eb0aea8f210 100644 (file)
@@ -9,7 +9,7 @@
 #include "hash-method.h"
 #include "istream.h"
 #include "iso8601-date.h"
-#include "json-tree.new.h"
+#include "json-tree.h"
 #include "array.h"
 #include "base64.h"
 #include "str-sanitize.h"
index 6b7996b3d107c14c962cb0c3e4dfeb9faba410df..94f751288fd79501fbe570e8697c63bae06ff755 100644 (file)
@@ -101,7 +101,6 @@ liblib_la_SOURCES = \
        istream-failure-at.c \
        istream-file.c \
        istream-hash.c \
-       istream-jsonstr.c \
        istream-limit.c \
        istream-multiplex.c \
        istream-nonuls.c \
@@ -123,8 +122,6 @@ liblib_la_SOURCES = \
        ioloop-select.c \
        ioloop-epoll.c \
        ioloop-kqueue.c \
-       json-parser.c \
-       json-tree.c \
        lib.c \
        lib-event.c \
        lib-signals.c \
@@ -270,7 +267,6 @@ headers = \
        istream-failure-at.h \
        istream-file-private.h \
        istream-hash.h \
-       istream-jsonstr.h \
        istream-multiplex.h \
        istream-nonuls.h \
        istream-private.h \
@@ -285,8 +281,6 @@ headers = \
        ioloop-iolist.h \
        ioloop-private.h \
        ioloop-notify-fd.h \
-       json-parser.h \
-       json-tree.h \
        lib.h \
        lib-event.h \
        lib-event-private.h \
@@ -419,7 +413,6 @@ test_lib_SOURCES = \
        test-istream-concat.c \
        test-istream-crlf.c \
        test-istream-failure-at.c \
-       test-istream-jsonstr.c \
        test-istream-multiplex.c \
        test-istream-noop.c \
        test-istream-seekable.c \
@@ -427,8 +420,6 @@ test_lib_SOURCES = \
        test-istream-tee.c \
        test-istream-try.c \
        test-istream-unix.c \
-       test-json-parser.c \
-       test-json-tree.c \
        test-lib-event.c \
        test-lib-signals.c \
        test-llist.c \
diff --git a/src/lib/istream-jsonstr.c b/src/lib/istream-jsonstr.c
deleted file mode 100644 (file)
index 727f21c..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "buffer.h"
-#include "hex-dec.h"
-#include "unichar.h"
-#include "istream-private.h"
-#include "istream-jsonstr.h"
-
-#define MAX_UTF8_LEN 6
-
-struct jsonstr_istream {
-       struct istream_private istream;
-
-       /* The end '"' was found */
-       bool str_end:1;
-};
-
-static int
-i_stream_jsonstr_read_parent(struct jsonstr_istream *jstream,
-                            unsigned int min_bytes)
-{
-       struct istream_private *stream = &jstream->istream;
-       size_t size, avail;
-       ssize_t ret;
-
-       size = i_stream_get_data_size(stream->parent);
-       while (size < min_bytes) {
-               ret = i_stream_read_memarea(stream->parent);
-               if (ret <= 0) {
-                       if (ret == -2) {
-                               /* tiny parent buffer size - shouldn't happen */
-                               return -2;
-                       }
-                       stream->istream.stream_errno =
-                               stream->parent->stream_errno;
-                       stream->istream.eof = stream->parent->eof;
-                       if (ret == -1 && stream->istream.stream_errno == 0) {
-                               io_stream_set_error(&stream->iostream,
-                                       "EOF before trailing <\"> was seen");
-                               stream->istream.stream_errno = EPIPE;
-                       }
-                       return ret;
-               }
-               size = i_stream_get_data_size(stream->parent);
-       }
-
-       if (!i_stream_try_alloc(stream, size, &avail))
-               return -2;
-       return 1;
-}
-
-static int
-i_stream_json_unescape(const unsigned char *src, size_t len,
-                      unsigned char *dest,
-                      unsigned int *src_size_r, unsigned int *dest_size_r)
-{
-       switch (*src) {
-       case '"':
-       case '\\':
-       case '/':
-               *dest = *src;
-               break;
-       case 'b':
-               *dest = '\b';
-               break;
-       case 'f':
-               *dest = '\f';
-               break;
-       case 'n':
-               *dest = '\n';
-               break;
-       case 'r':
-               *dest = '\r';
-               break;
-       case 't':
-               *dest = '\t';
-               break;
-       case 'u': {
-               char chbuf[5] = {0};
-               unichar_t chr,chr2 = 0;
-               buffer_t buf;
-               if (len < 5)
-                       return 5;
-               buffer_create_from_data(&buf, dest, MAX_UTF8_LEN);
-               memcpy(chbuf, src+1, 4);
-               if (str_to_uint32_hex(chbuf, &chr)<0)
-                       return -1;
-               if (UTF16_VALID_LOW_SURROGATE(chr))
-                       return -1;
-               /* if we encounter surrogate, we need another \\uxxxx */
-               if (UTF16_VALID_HIGH_SURROGATE(chr)) {
-                       if (len < 5+2+4)
-                               return 5+2+4;
-                       if (src[5] != '\\' && src[6] != 'u')
-                               return -1;
-                       memcpy(chbuf, src+7, 4);
-                       if (str_to_uint32_hex(chbuf, &chr2)<0)
-                               return -1;
-                       if (!UTF16_VALID_LOW_SURROGATE(chr2))
-                               return -1;
-                       chr = uni_join_surrogate(chr, chr2);
-               }
-               if (!uni_is_valid_ucs4(chr))
-                       return -1;
-               uni_ucs4_to_utf8_c(chr, &buf);
-               *src_size_r = 5 + (chr2>0?6:0);
-               *dest_size_r = buf.used;
-               return 0;
-       }
-       default:
-               return -1;
-       }
-       *src_size_r = 1;
-       *dest_size_r = 1;
-       return 0;
-}
-
-static ssize_t i_stream_jsonstr_read(struct istream_private *stream)
-{
-       struct jsonstr_istream *jstream =
-               container_of(stream, struct jsonstr_istream, istream);
-       const unsigned char *data;
-       unsigned int srcskip, destskip, extra;
-       size_t i, dest, size;
-       ssize_t ret, ret2;
-
-       if (jstream->str_end) {
-               stream->istream.eof = TRUE;
-               return -1;
-       }
-
-       ret = i_stream_jsonstr_read_parent(jstream, 1);
-       if (ret <= 0)
-               return ret;
-
-       /* @UNSAFE */
-       dest = stream->pos;
-       extra = 0;
-
-       data = i_stream_get_data(stream->parent, &size);
-       for (i = 0; i < size && dest < stream->buffer_size; ) {
-               if (data[i] == '"') {
-                       jstream->str_end = TRUE;
-                       if (dest == stream->pos) {
-                               stream->istream.eof = TRUE;
-                               return -1;
-                       }
-                       break;
-               } else if (data[i] == '\\') {
-                       if (i+1 == size) {
-                               /* not enough input for \x */
-                               extra = 1;
-                               break;
-                       }
-                       if (data[i+1] == 'u' && stream->buffer_size - dest < MAX_UTF8_LEN) {
-                               /* UTF8 output is max. 6 chars */
-                               if (dest == stream->pos)
-                                       return -2;
-                               break;
-                       }
-                       i++;
-                       if ((ret2 = i_stream_json_unescape(data + i, size - i,
-                                                          stream->w_buffer + dest,
-                                                          &srcskip, &destskip)) < 0) {
-                               /* invalid string */
-                               io_stream_set_error(&stream->iostream,
-                                                   "Invalid JSON string");
-                               stream->istream.stream_errno = EINVAL;
-                               return -1;
-                       } else if (ret2 > 0) {
-                               /* we need to get more bytes, do not consume
-                                  escape slash */
-                               i--;
-                               extra = ret2;
-                               break;
-                       }
-                       i += srcskip;
-                       i_assert(i <= size);
-                       dest += destskip;
-                       i_assert(dest <= stream->buffer_size);
-               } else {
-                       stream->w_buffer[dest++] = data[i];
-                       i++;
-               }
-       }
-       i_stream_skip(stream->parent, i);
-
-       ret = dest - stream->pos;
-       if (ret == 0) {
-               /* not enough input */
-               i_assert(i == 0);
-               i_assert(extra > 0);
-               ret = i_stream_jsonstr_read_parent(jstream, extra+1);
-               if (ret <= 0)
-                       return ret;
-               return i_stream_jsonstr_read(stream);
-       }
-       i_assert(ret > 0);
-       stream->pos = dest;
-       return ret;
-}
-
-struct istream *i_stream_create_jsonstr(struct istream *input)
-{
-       struct jsonstr_istream *dstream;
-
-       dstream = i_new(struct jsonstr_istream, 1);
-       dstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
-       dstream->istream.read = i_stream_jsonstr_read;
-
-       dstream->istream.istream.readable_fd = FALSE;
-       dstream->istream.istream.blocking = input->blocking;
-       dstream->istream.istream.seekable = FALSE;
-       return i_stream_create(&dstream->istream, input,
-                              i_stream_get_fd(input), 0);
-}
diff --git a/src/lib/istream-jsonstr.h b/src/lib/istream-jsonstr.h
deleted file mode 100644 (file)
index 255eccd..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef ISTREAM_JSONSTR_H
-#define ISTREAM_JSONSTR_H
-
-/* Parse input until '"' is reached. Unescape JSON \x codes. */
-struct istream *i_stream_create_jsonstr(struct istream *input);
-
-#endif
diff --git a/src/lib/json-parser.c b/src/lib/json-parser.c
deleted file mode 100644 (file)
index 459833c..0000000
+++ /dev/null
@@ -1,849 +0,0 @@
-/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "array.h"
-#include "str.h"
-#include "istream.h"
-#include "hex-dec.h"
-#include "unichar.h"
-#include "istream-jsonstr.h"
-#include "json-parser.h"
-
-enum json_state {
-       JSON_STATE_ROOT = 0,
-       JSON_STATE_OBJECT_OPEN,
-       JSON_STATE_OBJECT_KEY,
-       JSON_STATE_OBJECT_COLON,
-       JSON_STATE_OBJECT_VALUE,
-       JSON_STATE_OBJECT_SKIP_STRING,
-       JSON_STATE_OBJECT_NEXT,
-       JSON_STATE_ARRAY_OPEN,
-       JSON_STATE_ARRAY_VALUE,
-       JSON_STATE_ARRAY_SKIP_STRING,
-       JSON_STATE_ARRAY_NEXT,
-       JSON_STATE_ARRAY_NEXT_SKIP,
-       JSON_STATE_VALUE,
-       JSON_STATE_DONE
-};
-
-struct json_parser {
-       pool_t pool;
-       struct istream *input;
-       uoff_t highwater_offset;
-       enum json_parser_flags flags;
-
-       const unsigned char *start, *end, *data;
-       const char *error;
-       string_t *value;
-       struct istream *strinput;
-
-       enum json_state state;
-       ARRAY(enum json_state) nesting;
-       unsigned int nested_skip_count;
-
-       bool skipping;
-       bool seen_eof;
-};
-
-static int json_parser_read_more(struct json_parser *parser)
-{
-       uoff_t cur_highwater = parser->input->v_offset +
-               i_stream_get_data_size(parser->input);
-       size_t size;
-       ssize_t ret;
-
-       i_assert(parser->highwater_offset <= cur_highwater);
-
-       if (parser->error != NULL)
-               return -1;
-
-       if (parser->highwater_offset == cur_highwater) {
-               ret = i_stream_read(parser->input);
-               if (ret == -2) {
-                       parser->error = "Token too large";
-                       return -1;
-               }
-               if (ret < 0 && !parser->seen_eof &&
-                   i_stream_get_data_size(parser->input) > 0 &&
-                   parser->input->stream_errno == 0) {
-                       /* call it once more to finish any pending number */
-                       parser->seen_eof = TRUE;
-               } else if (ret <= 0) {
-                       return ret;
-               } else {
-                       cur_highwater = parser->input->v_offset +
-                               i_stream_get_data_size(parser->input);
-                       i_assert(parser->highwater_offset < cur_highwater);
-                       parser->highwater_offset = cur_highwater;
-               }
-       }
-
-       parser->start = parser->data = i_stream_get_data(parser->input, &size);
-       parser->end = parser->start + size;
-       i_assert(size > 0);
-       return 1;
-}
-
-static void json_parser_update_input_pos(struct json_parser *parser)
-{
-       size_t size;
-
-       if (parser->data == parser->start)
-               return;
-
-       i_stream_skip(parser->input, parser->data - parser->start);
-       parser->start = parser->data = i_stream_get_data(parser->input, &size);
-       parser->end = parser->start + size;
-       if (size > 0) {
-               /* we skipped over some data and there's still data left.
-                  no need to read() the next time. */
-               parser->highwater_offset = 0;
-       } else {
-               parser->highwater_offset = parser->input->v_offset;
-       }
-}
-
-struct json_parser *json_parser_init(struct istream *input)
-{
-       return json_parser_init_flags(input, 0);
-}
-
-struct json_parser *json_parser_init_flags(struct istream *input,
-                                          enum json_parser_flags flags)
-{
-       struct json_parser *parser;
-       pool_t pool = pool_alloconly_create("json parser",
-                                           sizeof(struct json_parser)+64);
-
-       parser = p_new(pool, struct json_parser, 1);
-       parser->pool = pool;
-       parser->input = input;
-       parser->flags = flags;
-       parser->value = str_new(default_pool, 128);
-       i_array_init(&parser->nesting, 8);
-       i_stream_ref(input);
-
-       if ((flags & JSON_PARSER_NO_ROOT_OBJECT) != 0)
-               parser->state = JSON_STATE_VALUE;
-       return parser;
-}
-
-int json_parser_deinit(struct json_parser **_parser, const char **error_r)
-{
-       struct json_parser *parser = *_parser;
-
-       *_parser = NULL;
-
-       if (parser->error != NULL) {
-               /* actual parser error */
-               *error_r = t_strdup(parser->error);
-       } else if (parser->input->stream_errno != 0) {
-               *error_r = t_strdup_printf("read(%s) failed: %s",
-                                          i_stream_get_name(parser->input),
-                                          i_stream_get_error(parser->input));
-       } else if (parser->data == parser->end &&
-                  parser->state != JSON_STATE_DONE) {
-               *error_r = "Missing '}'";
-       } else {
-               *error_r = NULL;
-       }
-
-       i_stream_unref(&parser->input);
-       array_free(&parser->nesting);
-       str_free(&parser->value);
-       pool_unref(&parser->pool);
-       return *error_r != NULL ? -1 : 0;
-}
-
-static bool json_parse_whitespace(struct json_parser *parser)
-{
-       for (; parser->data != parser->end; parser->data++) {
-               switch (*parser->data) {
-               case ' ':
-               case '\t':
-               case '\r':
-               case '\n':
-                       break;
-               default:
-                       json_parser_update_input_pos(parser);
-                       return TRUE;
-               }
-       }
-       json_parser_update_input_pos(parser);
-       return FALSE;
-}
-
-static int json_skip_string(struct json_parser *parser)
-{
-       for (; parser->data != parser->end; parser->data++) {
-               if (*parser->data == '"') {
-                       parser->data++;
-                       json_parser_update_input_pos(parser);
-                       return 1;
-               }
-               if (*parser->data == '\\') {
-                       parser->data++;
-                       if (parser->data == parser->end)
-                               break;
-                       switch (*parser->data) {
-                       case '"':
-                       case '\\':
-                       case '/':
-                       case 'b':
-                       case 'f':
-                       case 'n':
-                       case 'r':
-                       case 't':
-                               break;
-                       case 'u':
-                               if (parser->end - parser->data < 4) {
-                                       parser->data = parser->end;
-                                       return -1;
-                               }
-                               parser->data += 3;
-                               break;
-                       default:
-                               parser->error = "Invalid escape string";
-                               return -1;
-                       }
-               }
-       }
-       json_parser_update_input_pos(parser);
-       return 0;
-}
-
-static int json_parse_unicode_escape(struct json_parser *parser)
-{
-       char chbuf[5] = {0};
-       unichar_t chr, hi_surg;
-
-       parser->data++;
-       if (parser->end - parser->data < 4) {
-               /* wait for more data */
-               parser->data = parser->end;
-               return 0;
-       }
-       memcpy(chbuf, parser->data, 4);
-       if (str_to_uint32_hex(chbuf, &chr) < 0) {
-               parser->error = "Invalid unicode escape seen";
-               return -1;
-       }
-       if (UTF16_VALID_HIGH_SURROGATE(chr)) {
-               /* possible surrogate pair */
-               hi_surg = chr;
-               chr = 0;
-               parser->data += 4;
-               if (parser->data >= parser->end) {
-                       /* wait for more data */
-                       parser->data = parser->end;
-                       return 0;
-               }
-               if ((parser->end - parser->data) < 2) {
-                       if (parser->data[0] == '\\') {
-                               /* wait for more data */
-                               parser->data = parser->end;
-                               return 0;
-                       }
-                       /* error */
-               }
-               if ((parser->end - parser->data) < 6) {
-                       if (parser->data[0] == '\\' &&
-                           parser->data[1] == 'u') {
-                               /* wait for more data */
-                               parser->data = parser->end;
-                               return 0;
-                       }
-                       /* error */
-               } else {
-                       memcpy(chbuf, &parser->data[2], 4);
-                       if (str_to_uint32_hex(chbuf, &chr) < 0) {
-                               parser->error = "Invalid unicode escape seen";
-                               return -1;
-                       }
-               }
-               if (parser->data[0] != '\\' || parser->data[1] != 'u' ||
-                   !UTF16_VALID_LOW_SURROGATE(chr)) {
-                       parser->error = p_strdup_printf(parser->pool,
-                               "High surrogate 0x%04x seen, "
-                               "but not followed by low surrogate", hi_surg);
-                       return -1;
-               }
-               chr = uni_join_surrogate(hi_surg, chr);
-               parser->data += 2;
-       }
-
-       if (!uni_is_valid_ucs4(chr)) {
-               parser->error = p_strdup_printf(parser->pool,
-                       "Invalid unicode character U+%04x", chr);
-               return -1;
-       }
-       if (chr == 0) {
-               parser->error = "\\u0000 not supported in strings";
-               return -1;
-       }
-       uni_ucs4_to_utf8_c(chr, parser->value);
-       parser->data += 3;
-       return 1;
-}
-
-static int json_parse_string(struct json_parser *parser, bool allow_skip,
-                            const char **value_r)
-{
-       int ret;
-
-       if (*parser->data != '"')
-               return -1;
-       parser->data++;
-
-       if (parser->skipping && allow_skip) {
-               *value_r = NULL;
-               return json_skip_string(parser);
-       }
-
-       str_truncate(parser->value, 0);
-       for (; parser->data != parser->end; parser->data++) {
-               if (*parser->data == '"') {
-                       parser->data++;
-                       *value_r = str_c(parser->value);
-                       return 1;
-               }
-               switch (*parser->data) {
-               case '\\':
-                       if (++parser->data == parser->end)
-                               return 0;
-                       switch (*parser->data) {
-                       case '"':
-                       case '\\':
-                       case '/':
-                               str_append_c(parser->value, *parser->data);
-                               break;
-                       case 'b':
-                               str_append_c(parser->value, '\b');
-                               break;
-                       case 'f':
-                               str_append_c(parser->value, '\f');
-                               break;
-                       case 'n':
-                               str_append_c(parser->value, '\n');
-                               break;
-                       case 'r':
-                               str_append_c(parser->value, '\r');
-                               break;
-                       case 't':
-                               str_append_c(parser->value, '\t');
-                               break;
-                       case 'u':
-                               if ((ret=json_parse_unicode_escape(parser)) <= 0)
-                                       return ret;
-                               break;
-                       default:
-                               parser->error = "Invalid escape string";
-                               return -1;
-                       }
-                       break;
-               case '\0':
-                       parser->error = "NULs not supported in strings";
-                       return -1;
-               default:
-                       str_append_c(parser->value, *parser->data);
-                       break;
-               }
-       }
-       return 0;
-}
-
-static int
-json_parse_digits(struct json_parser *parser)
-{
-       if (parser->data == parser->end)
-               return 0;
-       if (*parser->data < '0' || *parser->data > '9')
-               return -1;
-
-       while (parser->data != parser->end &&
-              *parser->data >= '0' && *parser->data <= '9')
-               str_append_c(parser->value, *parser->data++);
-       return 1;
-}
-
-static int json_parse_int(struct json_parser *parser)
-{
-       int ret;
-
-       if (*parser->data == '-') {
-               str_append_c(parser->value, *parser->data++);
-               if (parser->data == parser->end)
-                       return 0;
-       }
-       if (*parser->data == '0')
-               str_append_c(parser->value, *parser->data++);
-       else {
-               if ((ret = json_parse_digits(parser)) <= 0)
-                       return ret;
-       }
-       return 1;
-}
-
-static int json_parse_number(struct json_parser *parser, const char **value_r)
-{
-       int ret;
-
-       str_truncate(parser->value, 0);
-       if ((ret = json_parse_int(parser)) <= 0)
-               return ret;
-       if (parser->data != parser->end && *parser->data == '.') {
-               /* frac */
-               str_append_c(parser->value, *parser->data++);
-               if ((ret = json_parse_digits(parser)) <= 0)
-                       return ret;
-       }
-       if (parser->data != parser->end &&
-           (*parser->data == 'e' || *parser->data == 'E')) {
-               /* exp */
-               str_append_c(parser->value, *parser->data++);
-               if (parser->data == parser->end)
-                       return 0;
-               if (*parser->data == '+' || *parser->data == '-')
-                       str_append_c(parser->value, *parser->data++);
-               if ((ret = json_parse_digits(parser)) <= 0)
-                       return ret;
-       }
-       if (parser->data == parser->end && !parser->input->eof)
-               return 0;
-       *value_r = str_c(parser->value);
-       return 1;
-}
-
-static int json_parse_atom(struct json_parser *parser, const char *atom)
-{
-       size_t avail, len = strlen(atom);
-
-       avail = parser->end - parser->data;
-       if (avail < len) {
-               if (memcmp(parser->data, atom, avail) != 0)
-                       return -1;
-
-               /* everything matches so far, but we need more data */
-               parser->data += avail;
-               return 0;
-       }
-       if (memcmp(parser->data, atom, len) != 0)
-               return -1;
-       parser->data += len;
-       return 1;
-}
-
-static int json_parse_denest(struct json_parser *parser)
-{
-       const enum json_state *nested_states;
-       unsigned int count;
-
-       parser->data++;
-       json_parser_update_input_pos(parser);
-
-       nested_states = array_get(&parser->nesting, &count);
-       i_assert(count > 0);
-       if (count == 1) {
-               /* closing root */
-               parser->state = JSON_STATE_DONE;
-               if ((parser->flags & JSON_PARSER_NO_ROOT_OBJECT) == 0)
-                       return 0;
-               /* we want to return the ending "]" or "}" to caller */
-               return 1;
-       }
-
-       /* closing a nested object */
-       parser->state = nested_states[count-2] == JSON_STATE_OBJECT_OPEN ?
-               JSON_STATE_OBJECT_NEXT : JSON_STATE_ARRAY_NEXT;
-       array_delete(&parser->nesting, count-1, 1);
-
-       if (parser->nested_skip_count > 0) {
-               parser->nested_skip_count--;
-               return 0;
-       }
-       return 1;
-}
-
-static int
-json_parse_close_object(struct json_parser *parser, enum json_type *type_r)
-{
-       if (json_parse_denest(parser) == 0)
-               return 0;
-       *type_r = JSON_TYPE_OBJECT_END;
-       return 1;
-}
-
-static int
-json_parse_close_array(struct json_parser *parser, enum json_type *type_r)
-{
-       if (json_parse_denest(parser) == 0)
-               return 0;
-       *type_r = JSON_TYPE_ARRAY_END;
-       return 1;
-}
-
-static void json_parser_object_open(struct json_parser *parser)
-{
-       parser->data++;
-       parser->state = JSON_STATE_OBJECT_OPEN;
-       array_push_back(&parser->nesting, &parser->state);
-       json_parser_update_input_pos(parser);
-}
-
-static int
-json_try_parse_next(struct json_parser *parser, enum json_type *type_r,
-                   const char **value_r)
-{
-       bool skipping = parser->skipping;
-       int ret;
-
-       if (!json_parse_whitespace(parser))
-               return -1;
-
-       switch (parser->state) {
-       case JSON_STATE_ROOT:
-               if (*parser->data != '{') {
-                       parser->error = "Object doesn't begin with '{'";
-                       return -1;
-               }
-               json_parser_object_open(parser);
-               return 0;
-       case JSON_STATE_OBJECT_VALUE:
-       case JSON_STATE_ARRAY_VALUE:
-       case JSON_STATE_VALUE:
-               if (*parser->data == '{') {
-                       json_parser_object_open(parser);
-
-                       if (parser->skipping) {
-                               parser->nested_skip_count++;
-                               return 0;
-                       }
-                       *type_r = JSON_TYPE_OBJECT;
-                       return 1;
-               } else if (*parser->data == '[') {
-                       parser->data++;
-                       parser->state = JSON_STATE_ARRAY_OPEN;
-                       array_push_back(&parser->nesting, &parser->state);
-                       json_parser_update_input_pos(parser);
-
-                       if (parser->skipping) {
-                               parser->nested_skip_count++;
-                               return 0;
-                       }
-                       *type_r = JSON_TYPE_ARRAY;
-                       return 1;
-               }
-
-               if ((ret = json_parse_string(parser, TRUE, value_r)) >= 0) {
-                       *type_r = JSON_TYPE_STRING;
-               } else if ((ret = json_parse_number(parser, value_r)) >= 0) {
-                       *type_r = JSON_TYPE_NUMBER;
-               } else if ((ret = json_parse_atom(parser, "true")) >= 0) {
-                       *type_r = JSON_TYPE_TRUE;
-                       *value_r = "true";
-               } else if ((ret = json_parse_atom(parser, "false")) >= 0) {
-                       *type_r = JSON_TYPE_FALSE;
-                       *value_r = "false";
-               } else if ((ret = json_parse_atom(parser, "null")) >= 0) {
-                       *type_r = JSON_TYPE_NULL;
-                       *value_r = NULL;
-               } else {
-                       if (parser->error == NULL)
-                               parser->error = "Invalid data as value";
-                       return -1;
-               }
-               if (ret == 0) {
-                       i_assert(parser->data == parser->end);
-                       if (parser->skipping && *type_r == JSON_TYPE_STRING) {
-                               /* a large string that we want to skip over. */
-                               json_parser_update_input_pos(parser);
-                               parser->state = parser->state == JSON_STATE_OBJECT_VALUE ?
-                                       JSON_STATE_OBJECT_SKIP_STRING :
-                                       JSON_STATE_ARRAY_SKIP_STRING;
-                               return 0;
-                       }
-                       return -1;
-               }
-               switch (parser->state) {
-               case JSON_STATE_OBJECT_VALUE:
-                       parser->state = JSON_STATE_OBJECT_NEXT;
-                       break;
-               case JSON_STATE_ARRAY_VALUE:
-                       parser->state = JSON_STATE_ARRAY_NEXT;
-                       break;
-               case JSON_STATE_VALUE:
-                       parser->state = JSON_STATE_DONE;
-                       break;
-               default:
-                       i_unreached();
-               }
-               break;
-       case JSON_STATE_OBJECT_OPEN:
-               if (*parser->data == '}')
-                       return json_parse_close_object(parser, type_r);
-               parser->state = JSON_STATE_OBJECT_KEY;
-               /* fall through */
-       case JSON_STATE_OBJECT_KEY:
-               if (json_parse_string(parser, FALSE, value_r) <= 0) {
-                       parser->error = "Expected string as object key";
-                       return -1;
-               }
-               *type_r = JSON_TYPE_OBJECT_KEY;
-               parser->state = JSON_STATE_OBJECT_COLON;
-               break;
-       case JSON_STATE_OBJECT_COLON:
-               if (*parser->data != ':') {
-                       parser->error = "Expected ':' after key";
-                       return -1;
-               }
-               parser->data++;
-               parser->state = JSON_STATE_OBJECT_VALUE;
-               json_parser_update_input_pos(parser);
-               return 0;
-       case JSON_STATE_OBJECT_NEXT:
-               if (parser->skipping && parser->nested_skip_count == 0) {
-                       /* we skipped over the previous value */
-                       parser->skipping = FALSE;
-               }
-               if (*parser->data == '}')
-                       return json_parse_close_object(parser, type_r);
-               if (*parser->data != ',') {
-                       parser->error = "Expected ',' or '}' after object value";
-                       return -1;
-               }
-               parser->state = JSON_STATE_OBJECT_KEY;
-               parser->data++;
-               json_parser_update_input_pos(parser);
-               return 0;
-       case JSON_STATE_ARRAY_OPEN:
-               if (*parser->data == ']')
-                       return json_parse_close_array(parser, type_r);
-               parser->state = JSON_STATE_ARRAY_VALUE;
-               return 0;
-       case JSON_STATE_ARRAY_NEXT:
-               if (parser->skipping && parser->nested_skip_count == 0) {
-                       /* we skipped over the previous value */
-                       parser->skipping = FALSE;
-               }
-               /* fall through */
-       case JSON_STATE_ARRAY_NEXT_SKIP:
-               if (*parser->data == ']')
-                       return json_parse_close_array(parser, type_r);
-               if (*parser->data != ',') {
-                       parser->error = "Expected ',' or '}' after array value";
-                       return -1;
-               }
-               parser->state = JSON_STATE_ARRAY_VALUE;
-               parser->data++;
-               json_parser_update_input_pos(parser);
-               return 0;
-       case JSON_STATE_OBJECT_SKIP_STRING:
-       case JSON_STATE_ARRAY_SKIP_STRING:
-               if (json_skip_string(parser) <= 0)
-                       return -1;
-               parser->state = parser->state == JSON_STATE_OBJECT_SKIP_STRING ?
-                       JSON_STATE_OBJECT_NEXT : JSON_STATE_ARRAY_NEXT;
-               return 0;
-       case JSON_STATE_DONE:
-               parser->error = "Unexpected data at the end";
-               return -1;
-       }
-       json_parser_update_input_pos(parser);
-       return skipping ? 0 : 1;
-}
-
-int json_parse_next(struct json_parser *parser, enum json_type *type_r,
-                   const char **value_r)
-{
-       int ret;
-
-       i_assert(parser->strinput == NULL);
-
-       *value_r = NULL;
-
-       while ((ret = json_parser_read_more(parser)) > 0) {
-               while ((ret = json_try_parse_next(parser, type_r, value_r)) == 0)
-                       ;
-               if (ret > 0)
-                       break;
-               if (parser->data != parser->end)
-                       return -1;
-               /* parsing probably failed because there wasn't enough input.
-                  reset the error and try reading more. */
-               parser->error = NULL;
-               parser->highwater_offset = parser->input->v_offset +
-                       i_stream_get_data_size(parser->input);
-       }
-       return ret;
-}
-
-void json_parse_skip_next(struct json_parser *parser)
-{
-       i_assert(!parser->skipping);
-       i_assert(parser->strinput == NULL);
-       i_assert(parser->state == JSON_STATE_OBJECT_COLON ||
-                parser->state == JSON_STATE_OBJECT_VALUE ||
-                parser->state == JSON_STATE_ARRAY_VALUE ||
-                parser->state == JSON_STATE_ARRAY_NEXT);
-
-       parser->skipping = TRUE;
-       if (parser->state == JSON_STATE_ARRAY_NEXT)
-               parser->state = JSON_STATE_ARRAY_NEXT_SKIP;
-}
-
-void json_parse_skip(struct json_parser *parser)
-{
-       i_assert(!parser->skipping);
-       i_assert(parser->strinput == NULL);
-       i_assert(parser->state == JSON_STATE_OBJECT_NEXT ||
-                parser->state == JSON_STATE_OBJECT_OPEN ||
-                parser->state == JSON_STATE_ARRAY_NEXT ||
-                parser->state == JSON_STATE_ARRAY_OPEN);
-
-       if (parser->state == JSON_STATE_OBJECT_OPEN ||
-           parser->state == JSON_STATE_ARRAY_OPEN)
-               parser->nested_skip_count++;
-
-       parser->skipping = TRUE;
-       if (parser->state == JSON_STATE_ARRAY_NEXT)
-               parser->state = JSON_STATE_ARRAY_NEXT_SKIP;
-}
-
-static void json_strinput_destroyed(struct json_parser *parser)
-{
-       i_assert(parser->strinput != NULL);
-
-       parser->strinput = NULL;
-}
-
-static int
-json_try_parse_stream_start(struct json_parser *parser,
-                           struct istream **input_r)
-{
-       if (!json_parse_whitespace(parser))
-               return -1;
-
-       if (parser->state == JSON_STATE_OBJECT_COLON) {
-               if (*parser->data != ':') {
-                       parser->error = "Expected ':' after key";
-                       return -1;
-               }
-               parser->data++;
-               parser->state = JSON_STATE_OBJECT_VALUE;
-               if (!json_parse_whitespace(parser))
-                       return -1;
-       }
-
-       if (*parser->data != '"')
-               return -1;
-       parser->data++;
-       json_parser_update_input_pos(parser);
-
-       parser->state = parser->state == JSON_STATE_OBJECT_VALUE ?
-               JSON_STATE_OBJECT_SKIP_STRING : JSON_STATE_ARRAY_SKIP_STRING;
-       parser->strinput = i_stream_create_jsonstr(parser->input);
-       i_stream_add_destroy_callback(parser->strinput,
-                                     json_strinput_destroyed, parser);
-
-       *input_r = parser->strinput;
-       return 0;
-}
-
-int json_parse_next_stream(struct json_parser *parser,
-                          struct istream **input_r)
-{
-       int ret;
-
-       i_assert(!parser->skipping);
-       i_assert(parser->strinput == NULL);
-       i_assert(parser->state == JSON_STATE_OBJECT_COLON ||
-                parser->state == JSON_STATE_OBJECT_VALUE ||
-                parser->state == JSON_STATE_ARRAY_VALUE);
-
-       *input_r = NULL;
-
-       while ((ret = json_parser_read_more(parser)) > 0) {
-               if (json_try_parse_stream_start(parser, input_r) == 0)
-                       break;
-               if (parser->data != parser->end)
-                       return -1;
-               /* parsing probably failed because there wasn't enough input.
-                  reset the error and try reading more. */
-               parser->error = NULL;
-               parser->highwater_offset = parser->input->v_offset +
-                       i_stream_get_data_size(parser->input);
-       }
-       return ret;
-}
-
-static void json_append_escaped_char(string_t *dest, unsigned char src)
-{
-       switch (src) {
-       case '\b':
-               str_append(dest, "\\b");
-               break;
-       case '\f':
-               str_append(dest, "\\f");
-               break;
-       case '\n':
-               str_append(dest, "\\n");
-               break;
-       case '\r':
-               str_append(dest, "\\r");
-               break;
-       case '\t':
-               str_append(dest, "\\t");
-               break;
-       case '"':
-               str_append(dest, "\\\"");
-               break;
-       case '\\':
-               str_append(dest, "\\\\");
-               break;
-       default:
-               if (src < 0x20 || src >= 0x80)
-                       str_printfa(dest, "\\u%04x", src);
-               else
-                       str_append_c(dest, src);
-               break;
-       }
-}
-
-void json_append_escaped_ucs4(string_t *dest, unichar_t chr)
-{
-       if (chr < 0x80)
-               json_append_escaped_char(dest, (unsigned char)chr);
-       else if (chr == 0x2028 || chr == 0x2029)
-               str_printfa(dest, "\\u%04x", chr);
-       else
-               uni_ucs4_to_utf8_c(chr, dest);
-}
-
-void ostream_escaped_json_format(string_t *dest, unsigned char src)
-{
-       json_append_escaped_char(dest, src);
-}
-
-void json_append_escaped(string_t *dest, const char *src)
-{
-       json_append_escaped_data(dest, (const unsigned char*)src, strlen(src));
-}
-
-void json_append_escaped_data(string_t *dest, const unsigned char *src, size_t size)
-{
-       size_t i;
-       int bytes = 0;
-       unichar_t chr;
-
-       for (i = 0; i < size;) {
-               bytes = uni_utf8_get_char_n(src+i, size-i, &chr);
-               if (bytes > 0 && uni_is_valid_ucs4(chr)) {
-                       json_append_escaped_ucs4(dest, chr);
-                       i += bytes;
-               } else {
-                       str_append_data(dest, UNICODE_REPLACEMENT_CHAR_UTF8,
-                                             UTF8_REPLACEMENT_CHAR_LEN);
-                       i++;
-               }
-       }
-}
diff --git a/src/lib/json-parser.h b/src/lib/json-parser.h
deleted file mode 100644 (file)
index 745f4a7..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef JSON_PARSER_H
-#define JSON_PARSER_H
-
-#include "unichar.h"
-
-enum json_type {
-       /* { key: */
-       JSON_TYPE_OBJECT_KEY,
-       /* : { new object */
-       JSON_TYPE_OBJECT,
-       /* } (not returned for the root object) */
-       JSON_TYPE_OBJECT_END,
-
-       JSON_TYPE_ARRAY,
-       JSON_TYPE_ARRAY_END,
-
-       JSON_TYPE_STRING,
-       JSON_TYPE_NUMBER,
-       JSON_TYPE_TRUE,
-       JSON_TYPE_FALSE,
-       JSON_TYPE_NULL
-};
-
-enum json_parser_flags {
-       /* By default we assume that the input is an object and parsing skips
-          the root level "{" and "}". If this flag is set, it's possible to
-          parse any other type of JSON values directly. */
-       JSON_PARSER_NO_ROOT_OBJECT      = 0x01
-};
-
-/* Parse JSON tokens from the input stream. */
-struct json_parser *json_parser_init(struct istream *input);
-struct json_parser *json_parser_init_flags(struct istream *input,
-                                          enum json_parser_flags flags);
-
-int json_parser_deinit(struct json_parser **parser, const char **error_r);
-
-/* Parse the next token. Returns 1 if found, 0 if more input stream is
-   non-blocking and needs more input, -1 if input stream is at EOF. */
-int json_parse_next(struct json_parser *parser, enum json_type *type_r,
-                   const char **value_r);
-/* Skip the next object value. If it's an object, its members are also
-   skipped. */
-void json_parse_skip_next(struct json_parser *parser);
-/* Skip the remainder of the value parsed earlier by json_parse_next(). */
-void json_parse_skip(struct json_parser *parser);
-/* Return the following string as input stream. Returns 1 if ok, 0 if
-   input stream is non-blocking and needs more input, -1 if the next token
-   isn't a string (call json_parse_next()). */
-int json_parse_next_stream(struct json_parser *parser,
-                          struct istream **input_r);
-
-/* Append UCS4 to already opened JSON string. */
-void json_append_escaped_ucs4(string_t *dest, unichar_t chr);
-/* Append data to already opened JSON string. src should be valid UTF-8 data. */
-void json_append_escaped(string_t *dest, const char *src);
-/* Same as json_append_escaped(), but append non-\0 terminated input. */
-void json_append_escaped_data(string_t *dest, const unsigned char *src, size_t size);
-void ostream_escaped_json_format(string_t *dest, unsigned char src);
-
-#endif
diff --git a/src/lib/json-tree.c b/src/lib/json-tree.c
deleted file mode 100644 (file)
index cb721c2..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/* Copyright (c) 2015-2018 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "json-tree.h"
-
-struct json_tree {
-       pool_t pool;
-       struct json_tree_node *root, *cur, *cur_child;
-};
-
-struct json_tree *
-json_tree_init_type(enum json_type container)
-{
-       struct json_tree *tree;
-       pool_t pool;
-
-       pool = pool_alloconly_create("json tree", 1024);
-       tree = p_new(pool, struct json_tree, 1);
-       tree->pool = pool;
-       tree->root = tree->cur = p_new(tree->pool, struct json_tree_node, 1);
-       tree->cur->value_type = container == JSON_TYPE_ARRAY ? container : JSON_TYPE_OBJECT;
-       return tree;
-}
-
-void json_tree_deinit(struct json_tree **_tree)
-{
-       struct json_tree *tree = *_tree;
-
-       *_tree = NULL;
-       pool_unref(&tree->pool);
-}
-
-static void
-json_tree_append_child(struct json_tree *tree, enum json_type type,
-                      const char *value)
-{
-       struct json_tree_node *node;
-
-       node = p_new(tree->pool, struct json_tree_node, 1);
-       node->parent = tree->cur;
-       node->value_type = type;
-       node->value.str = p_strdup(tree->pool, value);
-
-       if (tree->cur_child == NULL)
-               tree->cur->value.child = node;
-       else
-               tree->cur_child->next = node;
-       tree->cur_child = node;
-}
-
-static void
-json_tree_set_cur(struct json_tree *tree, struct json_tree_node *node)
-{
-       tree->cur = node;
-       tree->cur_child = tree->cur->value.child;
-       if (tree->cur_child != NULL) {
-               while (tree->cur_child->next != NULL)
-                       tree->cur_child = tree->cur_child->next;
-       }
-}
-
-static int
-json_tree_append_value(struct json_tree *tree, enum json_type type,
-                      const char *value)
-{
-       switch (tree->cur->value_type) {
-       case JSON_TYPE_OBJECT_KEY:
-               /* "key": value - we already added the node and set its key,
-                  so now just set the value */
-               tree->cur->value_type = type;
-               tree->cur->value.str = p_strdup(tree->pool, value);
-               json_tree_set_cur(tree, tree->cur->parent);
-               break;
-       case JSON_TYPE_ARRAY:
-               /* element in array - add a new node */
-               json_tree_append_child(tree, type, value);
-               break;
-       default:
-               return -1;
-       }
-       return 0;
-}
-
-int json_tree_append(struct json_tree *tree, enum json_type type,
-                    const char *value)
-{
-       switch (type) {
-       case JSON_TYPE_OBJECT_KEY:
-               if (tree->cur->value_type != JSON_TYPE_OBJECT)
-                       return -1;
-               json_tree_append_child(tree, type, NULL);
-               json_tree_set_cur(tree, tree->cur_child);
-               tree->cur->key = p_strdup(tree->pool, value);
-               break;
-       case JSON_TYPE_ARRAY:
-               if (json_tree_append_value(tree, type, NULL) < 0)
-                       return -1;
-               json_tree_set_cur(tree, tree->cur_child);
-               break;
-       case JSON_TYPE_OBJECT:
-               if (tree->cur->value_type == JSON_TYPE_OBJECT_KEY)
-                       tree->cur->value_type = JSON_TYPE_OBJECT;
-               else if (tree->cur->value_type == JSON_TYPE_ARRAY) {
-                       json_tree_append_child(tree, type, NULL);
-                       json_tree_set_cur(tree, tree->cur_child);
-               } else {
-                       return -1;
-               }
-               break;
-       case JSON_TYPE_OBJECT_END:
-               if (tree->cur->parent == NULL ||
-                   tree->cur->value_type != JSON_TYPE_OBJECT)
-                       return -1;
-               json_tree_set_cur(tree, tree->cur->parent);
-               break;
-       case JSON_TYPE_ARRAY_END:
-               if (tree->cur->parent == NULL ||
-                   tree->cur->value_type != JSON_TYPE_ARRAY)
-                       return -1;
-               json_tree_set_cur(tree, tree->cur->parent);
-               break;
-       case JSON_TYPE_STRING:
-       case JSON_TYPE_NUMBER:
-       case JSON_TYPE_TRUE:
-       case JSON_TYPE_FALSE:
-       case JSON_TYPE_NULL:
-               if (json_tree_append_value(tree, type, value) < 0)
-                       return -1;
-               break;
-       }
-       return 0;
-}
-
-const struct json_tree_node *
-json_tree_root(const struct json_tree *tree)
-{
-       return tree->root;
-}
-
-const struct json_tree_node *
-json_tree_find_key(const struct json_tree_node *node, const char *key)
-{
-       i_assert(node->value_type == JSON_TYPE_OBJECT);
-
-       node = json_tree_get_child(node);
-       for (; node != NULL; node = node->next) {
-               if (node->key != NULL && strcmp(node->key, key) == 0)
-                       return node;
-       }
-       return NULL;
-}
-
-const struct json_tree_node *
-json_tree_find_child_with(const struct json_tree_node *node,
-                         const char *key, const char *value)
-{
-       const struct json_tree_node *child;
-
-       i_assert(node->value_type == JSON_TYPE_OBJECT ||
-                node->value_type == JSON_TYPE_ARRAY);
-
-       for (node = json_tree_get_child(node); node != NULL; node = node->next) {
-               if (node->value_type != JSON_TYPE_OBJECT)
-                       continue;
-
-               child = json_tree_find_key(node, key);
-               if (child != NULL &&
-                   json_tree_get_value_str(child) != NULL &&
-                   strcmp(json_tree_get_value_str(child), value) == 0)
-                       return node;
-       }
-       return NULL;
-}
diff --git a/src/lib/json-tree.h b/src/lib/json-tree.h
deleted file mode 100644 (file)
index a995c75..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef JSON_TREE_H
-#define JSON_TREE_H
-
-#include "json-parser.h"
-
-/* Direct access to this structure is not encouraged, use the inline
-   function accessors where possible, so that the implementation
-   details can remain fluid, or, even better, hidden. */
-struct json_tree_node {
-       /* object key, or NULL if we're in a list */
-       const char *key;
-       struct json_tree_node *parent, *next;
-
-       enum json_type value_type;
-       struct {
-               /* for JSON_TYPE_OBJECT and JSON_TYPE_ARRAY */
-               struct json_tree_node *child;
-               /* for other types */
-               const char *str;
-       } value;
-};
-static inline ATTR_PURE const struct json_tree_node *json_tree_get_child(const struct json_tree_node *node)
-{
-       return node->value.child;
-}
-static inline ATTR_PURE const char *json_tree_get_value_str(const struct json_tree_node *node)
-{
-       return node->value.str;
-}
-
-/* You can build a list or an object, nothing else. */
-struct json_tree *json_tree_init_type(enum json_type container);
-static inline struct json_tree *json_tree_init(void)
-{
-       return json_tree_init_type(JSON_TYPE_OBJECT);
-}
-static inline struct json_tree *json_tree_init_array(void)
-{
-       return json_tree_init_type(JSON_TYPE_ARRAY);
-}
-
-void json_tree_deinit(struct json_tree **tree);
-
-/* Append data to a tree. The type/value should normally come from json-parser.
-   Returns 0 on success, -1 if the input was invalid (which should never happen
-   if it's coming from json-parser). */
-int json_tree_append(struct json_tree *tree, enum json_type type,
-                    const char *value);
-
-/* Return the root node. */
-const struct json_tree_node *
-json_tree_root(const struct json_tree *tree);
-/* Find a node with the specified key from an OBJECT node */
-const struct json_tree_node *
-json_tree_find_key(const struct json_tree_node *node, const char *key);
-/* Find an object node (from an array), which contains the specified key=value
-   in its values. */
-const struct json_tree_node *
-json_tree_find_child_with(const struct json_tree_node *node,
-                         const char *key, const char *value);
-
-#endif
diff --git a/src/lib/test-istream-jsonstr.c b/src/lib/test-istream-jsonstr.c
deleted file mode 100644 (file)
index 7b432e8..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING file */
-
-#include "test-lib.h"
-#include "str.h"
-#include "istream-private.h"
-#include "istream-jsonstr.h"
-
-static const struct {
-       const char *input;
-       const char *output;
-       int stream_errno;
-} tests[] = {
-       { "foo\\\\\\\"\\b\\f\\n\\r\\t\\u0001\\uffff\"",
-         "foo\\\"\b\f\n\r\t\001\xEF\xBF\xBF", 0 },
-       { "\\ud801\\udc37\"", "\xf0\x90\x90\xb7", 0 }, /* valid codepoint */
-       { "\"", "", 0 },
-       { "foo\\?\"", "foo", EINVAL },
-       { "foo\\?\"", "foo", EINVAL },
-       { "", "", EPIPE },
-       { "\\\"", "\"", EPIPE },
-       { "foo", "foo", EPIPE },
-       { "\\ud801", "", EPIPE }, /* high surrogate alone */
-       { "\\udced\\udc37\"", "", EINVAL }, /* low surrogate before high */
-       { "\\ud8011\\udc37\"", "", EINVAL }, /* has extra 1 in middle */
-       { "hello \\udc37\"", "hello ", EINVAL }, /* low surrogate before high with valid prefix*/
-       { "hello \\ud801", "hello ", EPIPE }, /* high surrogate alone with valid prefix */
-       { "\\uabcg", "", EINVAL }, /* invalid hex value */
-};
-
-static void
-run_test_buffer(const char *json_input, const char *output, int stream_errno,
-               unsigned int skip_count)
-{
-       size_t json_input_len = strlen(json_input);
-       struct istream *input_data, *input;
-       const unsigned char *data;
-       size_t i, size;
-       ssize_t ret = 0;
-
-       input_data = test_istream_create_data(json_input, json_input_len);
-       test_istream_set_allow_eof(input_data, FALSE);
-       input = i_stream_create_jsonstr(input_data);
-
-       for (i = 1; i < json_input_len;) {
-               test_istream_set_size(input_data, i);
-               while ((ret = i_stream_read(input)) > 0) ;
-               if (ret == -1 && stream_errno != 0)
-                       break;
-               test_assert_idx(ret == 0, i);
-               if (i + skip_count < json_input_len)
-                       i += skip_count;
-               else
-                       i++;
-       }
-       test_istream_set_allow_eof(input_data, TRUE);
-       test_istream_set_size(input_data, json_input_len);
-       ret = i_stream_read(input);
-       while (ret > 0 && stream_errno != 0)
-               ret = i_stream_read(input);
-       test_assert(ret == -1);
-       test_assert(input->stream_errno == stream_errno);
-
-       if (stream_errno == 0) {
-               data = i_stream_get_data(input, &size);
-               test_assert(size == strlen(output));
-               if (size > 0)
-                       test_assert(memcmp(data, output, size) == 0);
-       }
-       i_stream_unref(&input);
-       i_stream_unref(&input_data);
-}
-
-static void
-run_test(const char *json_input, const char *output, int stream_errno)
-{
-       for (unsigned int i = 1; i <= 5; i++)
-               run_test_buffer(json_input, output, stream_errno, i);
-}
-
-static void test_istream_jsonstr_autoretry(void)
-{
-       const char *json_input = "\\u0001\"";
-       const size_t json_input_len = strlen(json_input);
-       struct istream *input_data, *input;
-
-       test_begin("istream-jsonstr autoretry");
-       input_data = test_istream_create_data(json_input, json_input_len);
-       input = i_stream_create_jsonstr(input_data);
-
-       test_istream_set_size(input_data, 2);
-       test_assert(i_stream_read(input_data) == 2);
-       test_istream_set_size(input_data, json_input_len);
-       test_assert(i_stream_read(input) == 1);
-       test_assert(i_stream_read(input) == -1);
-
-       i_stream_unref(&input);
-       i_stream_unref(&input_data);
-       test_end();
-}
-
-static void test_istream_jsonstr_partial(void)
-{
-       size_t len = 0;
-       const char *json_input = "hello\\u0060x\"";
-       const char *output = "hello`x";
-       const size_t json_input_len = strlen(json_input);
-       struct istream *input_data, *input;
-
-       test_begin("istream-jsonstr partial");
-
-       input_data = test_istream_create_data(json_input, json_input_len);
-       input = i_stream_create_jsonstr(input_data);
-       test_istream_set_size(input_data, 9);
-       test_assert(i_stream_read(input) == 5);
-       test_istream_set_size(input_data, json_input_len);
-       test_assert(i_stream_read(input) == 2);
-       test_assert(i_stream_read(input) == -1);
-
-       const unsigned char *data = i_stream_get_data(input, &len);
-       test_assert_cmp(len, ==, strlen(output));
-       test_assert_strcmp((const char*) data, output);
-
-       i_stream_unref(&input);
-       i_stream_unref(&input_data);
-
-       test_end();
-}
-
-void test_istream_jsonstr(void)
-{
-       unsigned int i;
-
-       for (i = 0; i < N_ELEMENTS(tests); i++) {
-               test_begin(t_strdup_printf("istream-jsonstr %u", i+1));
-               run_test(tests[i].input, tests[i].output, tests[i].stream_errno);
-               test_end();
-       }
-       test_istream_jsonstr_autoretry();
-       test_istream_jsonstr_partial();
-}
diff --git a/src/lib/test-json-parser.c b/src/lib/test-json-parser.c
deleted file mode 100644 (file)
index 92aa425..0000000
+++ /dev/null
@@ -1,440 +0,0 @@
-/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
-
-#include "test-lib.h"
-#include "str.h"
-#include "istream-private.h"
-#include "json-parser.h"
-
-#define TYPE_SKIP 100
-#define TYPE_STREAM 101
-
-static const char json_input[] =
-       "{\n"
-       "\t\"key\"\t:\t\t\"string\","
-       " \"key2\"  :  1234,  \n"
-       "\"key3\":true,"
-       "\"key4\":false,"
-       "\"skip1\": \"jsifjaisfjiasji\","
-       "\"skip2\": { \"x\":{ \"y\":123}, \"z\":[5,[6],{\"k\":0},3]},"
-       "\"key5\":null,"
-       "\"key6\": {},"
-       "\"key7\": {"
-       "  \"sub1\":\"value\""
-       "},"
-       "\"key8\": {"
-       "  \"sub2\":-12.456,\n"
-       "  \"sub3\":12.456e9,\n"
-       "  \"sub4\":0.456e-789"
-       "},"
-       "\"key9\": \"foo\\\\\\\"\\b\\f\\n\\r\\t\\u0001\\u10ff\","
-       "\"key10\": \"foo\\\\\\\"\\b\\f\\n\\r\\t\\u0001\\u10ff\","
-       "\"key11\": [],"
-       "\"key12\": [ \"foo\" , 5.24,[true],{\"aobj\":[]}],"
-       "\"key13\": \"\\ud801\\udc37\","
-       "\"key14\": \"\xd8\xb3\xd9\x84\xd8\xa7\xd9\x85\","
-       "\"key15\": \"\\u10000\""
-       "}\n";
-
-static const struct {
-       enum json_type type;
-       const char *value;
-} json_output[] = {
-       { JSON_TYPE_OBJECT_KEY, "key" },
-       { JSON_TYPE_STRING, "string" },
-       { JSON_TYPE_OBJECT_KEY, "key2" },
-       { JSON_TYPE_NUMBER, "1234" },
-       { JSON_TYPE_OBJECT_KEY, "key3" },
-       { JSON_TYPE_TRUE, "true" },
-       { JSON_TYPE_OBJECT_KEY, "key4" },
-       { JSON_TYPE_FALSE, "false" },
-       { JSON_TYPE_OBJECT_KEY, "skip1" },
-       { TYPE_SKIP, NULL },
-       { JSON_TYPE_OBJECT_KEY, "skip2" },
-       { TYPE_SKIP, NULL },
-       { JSON_TYPE_OBJECT_KEY, "key5" },
-       { JSON_TYPE_NULL, NULL },
-       { JSON_TYPE_OBJECT_KEY, "key6" },
-       { JSON_TYPE_OBJECT, NULL },
-       { JSON_TYPE_OBJECT_END, NULL },
-       { JSON_TYPE_OBJECT_KEY, "key7" },
-       { JSON_TYPE_OBJECT, NULL },
-       { JSON_TYPE_OBJECT_KEY, "sub1" },
-       { JSON_TYPE_STRING, "value" },
-       { JSON_TYPE_OBJECT_END, NULL },
-       { JSON_TYPE_OBJECT_KEY, "key8" },
-       { JSON_TYPE_OBJECT, NULL },
-       { JSON_TYPE_OBJECT_KEY, "sub2" },
-       { JSON_TYPE_NUMBER, "-12.456" },
-       { JSON_TYPE_OBJECT_KEY, "sub3" },
-       { JSON_TYPE_NUMBER, "12.456e9" },
-       { JSON_TYPE_OBJECT_KEY, "sub4" },
-       { JSON_TYPE_NUMBER, "0.456e-789" },
-       { JSON_TYPE_OBJECT_END, NULL },
-       { JSON_TYPE_OBJECT_KEY, "key9" },
-       { JSON_TYPE_STRING, "foo\\\"\b\f\n\r\t\001\xe1\x83\xbf" },
-       { JSON_TYPE_OBJECT_KEY, "key10" },
-       { TYPE_STREAM, "foo\\\"\b\f\n\r\t\001\xe1\x83\xbf" },
-       { JSON_TYPE_OBJECT_KEY, "key11" },
-       { JSON_TYPE_ARRAY, NULL },
-       { JSON_TYPE_ARRAY_END, NULL },
-       { JSON_TYPE_OBJECT_KEY, "key12" },
-       { JSON_TYPE_ARRAY, NULL },
-       { JSON_TYPE_STRING, "foo" },
-       { JSON_TYPE_NUMBER, "5.24" },
-       { JSON_TYPE_ARRAY, NULL },
-       { JSON_TYPE_TRUE, "true" },
-       { JSON_TYPE_ARRAY_END, NULL },
-       { JSON_TYPE_OBJECT, NULL },
-       { JSON_TYPE_OBJECT_KEY, "aobj" },
-       { JSON_TYPE_ARRAY, NULL },
-       { JSON_TYPE_ARRAY_END, NULL },
-       { JSON_TYPE_OBJECT_END, NULL },
-       { JSON_TYPE_ARRAY_END, NULL },
-       { JSON_TYPE_OBJECT_KEY, "key13" },
-       { JSON_TYPE_STRING, "\xf0\x90\x90\xb7" },
-       { JSON_TYPE_OBJECT_KEY, "key14" },
-       { JSON_TYPE_STRING, "\xd8\xb3\xd9\x84\xd8\xa7\xd9\x85" },
-       { JSON_TYPE_OBJECT_KEY, "key15" },
-       { JSON_TYPE_STRING, "\xe1\x80\x80""0" },
-};
-
-static int
-stream_read_value(struct istream **input, const char **value_r)
-{
-       const unsigned char *data;
-       size_t size;
-       ssize_t ret;
-
-       while ((ret = i_stream_read(*input)) > 0) ;
-       if (ret == 0)
-               return 0;
-       i_assert(ret == -1);
-       if ((*input)->stream_errno != 0)
-               return -1;
-
-       data = i_stream_get_data(*input, &size);
-       *value_r = t_strndup(data, size);
-       i_stream_unref(input);
-       return 1;
-}
-
-static void test_json_parser_success(bool full_size)
-{
-       struct json_parser *parser;
-       struct istream *input, *jsoninput = NULL;
-       enum json_type type;
-       const char *value, *error;
-       unsigned int i, pos, json_input_len = strlen(json_input);
-       int ret = 0;
-
-       test_begin(full_size ? "json parser" : "json parser (nonblocking)");
-       input = test_istream_create_data(json_input, json_input_len);
-       test_istream_set_allow_eof(input, FALSE);
-       parser = json_parser_init(input);
-
-       i = full_size ? json_input_len : 0;
-       for (pos = 0; i <= json_input_len; i++) {
-               test_istream_set_size(input, i);
-
-               for (;;) {
-                       value = NULL;
-                       if (pos < N_ELEMENTS(json_output) &&
-                           json_output[pos].type == (enum json_type)TYPE_SKIP) {
-                               json_parse_skip_next(parser);
-                               pos++;
-                               continue;
-                       } else if (pos == N_ELEMENTS(json_output) ||
-                                  json_output[pos].type != (enum json_type)TYPE_STREAM) {
-                               ret = json_parse_next(parser, &type, &value);
-                       } else {
-                               ret = jsoninput != NULL ? 1 :
-                                       json_parse_next_stream(parser, &jsoninput);
-                               if (ret > 0 && jsoninput != NULL)
-                                       ret = stream_read_value(&jsoninput, &value);
-                               type = TYPE_STREAM;
-                       }
-                       if (ret <= 0)
-                               break;
-
-                       i_assert(pos < N_ELEMENTS(json_output));
-                       test_assert_idx(json_output[pos].type == type, pos);
-                       test_assert_idx(null_strcmp(json_output[pos].value, value) == 0, pos);
-
-                       pos++;
-               }
-               test_assert_idx(ret == 0, pos);
-       }
-       test_assert(pos == N_ELEMENTS(json_output));
-       test_istream_set_allow_eof(input, TRUE);
-       test_assert(json_parse_next(parser, &type, &value) == -1);
-
-       i_stream_unref(&input);
-       test_assert(json_parser_deinit(&parser, &error) == 0);
-       test_end();
-}
-
-static void test_json_parser_skip_array(void)
-{
-       static const char *test_input =
-               "[ 1, {\"foo\": 1 }, 2, \"bar\", 3, 1.234, 4, [], 5, [[]], 6, true ]";
-       struct json_parser *parser;
-       struct istream *input;
-       enum json_type type;
-       const char *value, *error;
-       int i;
-
-       test_begin("json parser skip array");
-
-       input = test_istream_create_data(test_input, strlen(test_input));
-       parser = json_parser_init_flags(input, JSON_PARSER_NO_ROOT_OBJECT);
-       test_assert(json_parse_next(parser, &type, &value) > 0 &&
-                   type == JSON_TYPE_ARRAY);
-       for (i = 1; i <= 6; i++) {
-               test_assert(json_parse_next(parser, &type, &value) > 0 &&
-                           type == JSON_TYPE_NUMBER && atoi(value) == i);
-               json_parse_skip_next(parser);
-       }
-       test_assert(json_parse_next(parser, &type, &value) > 0 &&
-                   type == JSON_TYPE_ARRAY_END);
-       test_assert(json_parser_deinit(&parser, &error) == 0);
-       i_stream_unref(&input);
-       test_end();
-}
-
-static void test_json_parser_skip_object_fields(void)
-{
-       static const char *test_input =
-               "{\"access_token\":\"9a2dea3c-f8be-4271-b9c8-5b37da4f2f7e\","
-                "\"grant_type\":\"authorization_code\","
-                "\"openid\":\"\","
-                "\"scope\":[\"openid\",\"profile\",\"email\"],"
-                "\"profile\":\"\","
-                "\"realm\":\"/employees\","
-                "\"token_type\":\"Bearer\","
-                "\"expires_in\":2377,"
-                "\"client_i\\u0064\":\"mosaic\\u0064\","
-                "\"email\":\"\","
-                "\"extensions\":"
-                "{\"algorithm\":\"cuttlefish\","
-                 "\"tentacles\":8"
-                "}"
-               "}";
-       static const char *const keys[] = {
-               "access_token", "grant_type", "openid", "scope", "profile",
-               "realm", "token_type", "expires_in", "client_id", "email",
-               "extensions"
-       };
-       static const unsigned int keys_count = N_ELEMENTS(keys);
-       struct json_parser *parser;
-       struct istream *input;
-       enum json_type type;
-       const char *value, *error;
-       unsigned int i;
-       size_t pos;
-       int ret;
-
-       test_begin("json parser skip object fields (by key)");
-       input = test_istream_create_data(test_input, strlen(test_input));
-       parser = json_parser_init(input);
-       for (i = 0; i < keys_count; i++) {
-               ret = json_parse_next(parser, &type, &value);
-               if (ret < 0)
-                       break;
-               test_assert(ret > 0 && type == JSON_TYPE_OBJECT_KEY);
-               test_assert(strcmp(value, keys[i]) == 0);
-               json_parse_skip_next(parser);
-       }
-       test_assert(i == keys_count);
-       test_assert(json_parser_deinit(&parser, &error) == 0);
-       i_stream_unref(&input);
-
-       i = 0;
-       input = test_istream_create_data(test_input, strlen(test_input));
-       parser = json_parser_init(input);
-       for (pos = 0; pos <= strlen(test_input)*2; pos++) {
-               test_istream_set_size(input, pos/2);
-               ret = json_parse_next(parser, &type, &value);
-               if (ret == 0)
-                       continue;
-               if (ret < 0)
-                       break;
-               i_assert(i < keys_count);
-               test_assert(ret > 0 && type == JSON_TYPE_OBJECT_KEY);
-               test_assert(strcmp(value, keys[i]) == 0);
-               json_parse_skip_next(parser);
-               i++;
-       }
-       test_assert(i == keys_count);
-       test_assert(json_parser_deinit(&parser, &error) == 0);
-       i_stream_unref(&input);
-       test_end();
-
-       test_begin("json parser skip object fields (by value type)");
-       input = test_istream_create_data(test_input, strlen(test_input));
-       parser = json_parser_init(input);
-       for (i = 0; i < keys_count; i++) {
-               ret = json_parse_next(parser, &type, &value);
-               if (ret < 0)
-                       break;
-               test_assert(ret > 0 && type == JSON_TYPE_OBJECT_KEY);
-               test_assert(strcmp(value, keys[i]) == 0);
-               ret = json_parse_next(parser, &type, &value);
-               test_assert(ret > 0 && type != JSON_TYPE_OBJECT_KEY);
-               json_parse_skip(parser);
-       }
-       test_assert(i == keys_count);
-       test_assert(json_parser_deinit(&parser, &error) == 0);
-       i_stream_unref(&input);
-
-       i = 0;
-       input = test_istream_create_data(test_input, strlen(test_input));
-       parser = json_parser_init(input);
-       for (pos = 0; pos <= strlen(test_input)*2; pos++) {
-               test_istream_set_size(input, pos/2);
-               ret = json_parse_next(parser, &type, &value);
-               if (ret < 0)
-                       break;
-               if (ret == 0)
-                       continue;
-               test_assert(ret > 0);
-               if (type == JSON_TYPE_OBJECT_KEY) {
-                       i_assert(i < keys_count);
-                       test_assert(strcmp(value, keys[i]) == 0);
-                       i++;
-               } else {
-                       json_parse_skip(parser);
-               }
-       }
-       test_assert(i == keys_count);
-       test_assert(json_parser_deinit(&parser, &error) == 0);
-       i_stream_unref(&input);
-
-       test_end();
-}
-
-static int
-test_json_parse_input(const void *test_input, size_t test_input_size,
-                     enum json_parser_flags flags)
-{
-       struct json_parser *parser;
-       struct istream *input;
-       enum json_type type;
-       const char *value, *error;
-       int ret = 0;
-
-       input = test_istream_create_data(test_input, test_input_size);
-       parser = json_parser_init_flags(input, flags);
-       while (json_parse_next(parser, &type, &value) > 0)
-               ret++;
-       if (json_parser_deinit(&parser, &error) < 0)
-               ret = -1;
-       i_stream_unref(&input);
-       return ret;
-}
-
-static void test_json_parser_primitive_values(void)
-{
-       static const struct {
-               const char *str;
-               int ret;
-       } test_inputs[] = {
-               { "\"hello\"", 1 },
-               { "null", 1 },
-               { "1234", 1 },
-               { "1234.1234", 1 },
-               { "{}", 2 },
-               { "[]", 2 },
-               { "true", 1 },
-               { "false", 1 }
-       };
-       unsigned int i;
-
-       test_begin("json_parser (primitives)");
-       for (i = 0; i < N_ELEMENTS(test_inputs); i++)
-               test_assert_idx(test_json_parse_input(test_inputs[i].str,
-                                                     strlen(test_inputs[i].str),
-                                                     JSON_PARSER_NO_ROOT_OBJECT) == test_inputs[i].ret, i);
-       test_end();
-}
-
-static void test_json_parser_errors(void)
-{
-       static const char *test_inputs[] = {
-               "{",
-               "{:}",
-               "{\"foo\":}",
-               "{\"foo\" []}",
-               "{\"foo\": [1}",
-               "{\"foo\": [1,]}",
-               "{\"foo\": [1,]}",
-               "{\"foo\": 1,}",
-               "{\"foo\": 1.}}",
-               "{\"foo\": 1},{}",
-               "{\"foo\": \"\\ud808\"}",
-               "{\"foo\": \"\\udfff\"}",
-               "{\"foo\": \"\\uyyyy\"}",
-               "{\"a\":\"",
-               "{\"a\":nul",
-               "{\"a\":fals",
-               "{\"a\":tru",
-       };
-       unsigned int i;
-
-       test_begin("json parser error handling");
-       for (i = 0; i < N_ELEMENTS(test_inputs); i++)
-               test_assert_idx(test_json_parse_input(test_inputs[i],
-                                                     strlen(test_inputs[i]),
-                                                     0) < 0, i);
-       test_end();
-}
-
-static void test_json_parser_nuls_in_string(void)
-{
-       static const unsigned char test_input[] =
-       { '{', '"', 'k', '"', ':', '"', '\0', '"', '}' };
-       static const unsigned char test_input2[] =
-       { '{', '"', 'k', '"', ':', '"', '\\', '\0', '"', '}' };
-       static const unsigned char test_input3[] =
-       { '{', '"', 'k', '"', ':', '"', '\\', 'u', '0', '0', '0', '0', '"', '}' };
-
-       test_begin("json parser nuls in string");
-       test_assert(test_json_parse_input(test_input, sizeof(test_input), 0) < 0);
-       test_assert(test_json_parse_input(test_input2, sizeof(test_input2), 0) < 0);
-       test_assert(test_json_parse_input(test_input3, sizeof(test_input3), 0) < 0);
-       test_end();
-}
-
-static void test_json_append_escaped(void)
-{
-       string_t *str = t_str_new(32);
-
-       test_begin("json_append_escaped()");
-       json_append_escaped(str, "\b\f\r\n\t\"\\\001\002-\xC3\xA4\xf0\x90\x90\xb7\xe2\x80\xa8\xe2\x80\xa9\xff");
-       test_assert(strcmp(str_c(str), "\\b\\f\\r\\n\\t\\\"\\\\\\u0001\\u0002-\xC3\xA4\xf0\x90\x90\xb7\\u2028\\u2029" UNICODE_REPLACEMENT_CHAR_UTF8) == 0);
-       test_end();
-}
-
-static void test_json_append_escaped_data(void)
-{
-       static const unsigned char test_input[] =
-               "\b\f\r\n\t\"\\\000\001\002-\xC3\xA4\xf0\x90\x90\xb7\xe2\x80\xa8\xe2\x80\xa9\xff";
-       string_t *str = t_str_new(32);
-
-       test_begin("json_append_escaped_data()");
-       json_append_escaped_data(str, test_input, sizeof(test_input)-1);
-       test_assert(strcmp(str_c(str), "\\b\\f\\r\\n\\t\\\"\\\\\\u0000\\u0001\\u0002-\xC3\xA4\xf0\x90\x90\xb7\\u2028\\u2029" UNICODE_REPLACEMENT_CHAR_UTF8) == 0);
-       test_end();
-}
-
-void test_json_parser(void)
-{
-       test_json_parser_success(TRUE);
-       test_json_parser_success(FALSE);
-       test_json_parser_skip_array();
-       test_json_parser_skip_object_fields();
-       test_json_parser_primitive_values();
-       test_json_parser_errors();
-       test_json_parser_nuls_in_string();
-       test_json_append_escaped();
-       test_json_append_escaped_data();
-}
diff --git a/src/lib/test-json-tree.c b/src/lib/test-json-tree.c
deleted file mode 100644 (file)
index 40eff8c..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/* Copyright (c) 2015-2018 Dovecot authors, see the included COPYING file */
-
-#include "test-lib.h"
-#include "json-tree.h"
-
-struct {
-       enum json_type type;
-       const char *value;
-} test_input[] = {
-       { JSON_TYPE_OBJECT_KEY, "key-str" },
-       { JSON_TYPE_STRING, "string" },
-       { JSON_TYPE_OBJECT_KEY, "key-num" },
-       { JSON_TYPE_NUMBER, "1234" },
-       { JSON_TYPE_OBJECT_KEY, "key-true" },
-       { JSON_TYPE_TRUE, "true" },
-       { JSON_TYPE_OBJECT_KEY, "key-false" },
-       { JSON_TYPE_FALSE, "false" },
-       { JSON_TYPE_OBJECT_KEY, "key-null" },
-       { JSON_TYPE_NULL, NULL },
-
-       { JSON_TYPE_OBJECT_KEY, "key-obj-empty" },
-       { JSON_TYPE_OBJECT, NULL },
-       { JSON_TYPE_OBJECT_END, NULL },
-
-       { JSON_TYPE_OBJECT_KEY, "key-obj" },
-       { JSON_TYPE_OBJECT, NULL },
-         { JSON_TYPE_OBJECT_KEY, "sub" },
-         { JSON_TYPE_STRING, "value" },
-       { JSON_TYPE_OBJECT_END, NULL },
-
-       { JSON_TYPE_OBJECT_KEY, "key-arr-empty" },
-       { JSON_TYPE_ARRAY, NULL },
-       { JSON_TYPE_ARRAY_END, NULL },
-
-       { JSON_TYPE_OBJECT_KEY, "key-arr" },
-       { JSON_TYPE_ARRAY, NULL },
-         { JSON_TYPE_STRING, "foo" },
-         { JSON_TYPE_ARRAY, NULL },
-         { JSON_TYPE_TRUE, "true" },
-         { JSON_TYPE_ARRAY_END, NULL },
-         { JSON_TYPE_OBJECT, NULL },
-           { JSON_TYPE_OBJECT_KEY, "aobj" },
-           { JSON_TYPE_ARRAY, NULL },
-           { JSON_TYPE_ARRAY_END, NULL },
-         { JSON_TYPE_OBJECT_END, NULL },
-         { JSON_TYPE_OBJECT, NULL },
-           { JSON_TYPE_OBJECT_KEY, "aobj-key" },
-           { JSON_TYPE_STRING, "value1" },
-         { JSON_TYPE_OBJECT_END, NULL },
-         { JSON_TYPE_OBJECT, NULL },
-           { JSON_TYPE_OBJECT_KEY, "aobj-key" },
-           { JSON_TYPE_STRING, "value2" },
-         { JSON_TYPE_OBJECT_END, NULL },
-       { JSON_TYPE_ARRAY_END, NULL }
-};
-
-void test_json_tree(void)
-{
-       struct json_tree *tree;
-       const struct json_tree_node *root, *node, *node1, *node2;
-       unsigned int i;
-
-       test_begin("json tree");
-       tree = json_tree_init();
-       for (i = 0; i < N_ELEMENTS(test_input); i++) {
-               test_assert_idx(json_tree_append(tree, test_input[i].type,
-                                                test_input[i].value) == 0, i);
-       }
-
-       root = json_tree_root(tree);
-       i_assert(root != NULL);
-       test_assert(root->value_type == JSON_TYPE_OBJECT);
-       i_assert(root != NULL);
-
-       for (i = 0; i < 10+2; i += 2) {
-               node = json_tree_find_key(root, test_input[i].value);
-               test_assert(node != NULL &&
-                           node->value_type == test_input[i+1].type &&
-                           null_strcmp(json_tree_get_value_str(node), test_input[i+1].value) == 0);
-       }
-
-       node = json_tree_find_key(root, "key-obj");
-       test_assert(node != NULL);
-
-       node = json_tree_find_key(root, "key-arr-empty");
-       test_assert(node != NULL && node->value_type == JSON_TYPE_ARRAY &&
-                   json_tree_get_child(node) == NULL);
-
-       node = json_tree_find_key(root, "key-arr");
-       test_assert(node != NULL && node->value_type == JSON_TYPE_ARRAY);
-       node = json_tree_get_child(node);
-       test_assert(node != NULL && node->value_type == JSON_TYPE_STRING &&
-                   strcmp(json_tree_get_value_str(node), "foo") == 0);
-       node = node->next;
-       test_assert(node != NULL && node->value_type == JSON_TYPE_ARRAY &&
-                   json_tree_get_child(node) != NULL &&
-                   json_tree_get_child(node)->next == NULL &&
-                   json_tree_get_child(node)->value_type == JSON_TYPE_TRUE);
-       node = node->next;
-       test_assert(node != NULL && node->value_type == JSON_TYPE_OBJECT &&
-                   json_tree_get_child(node) != NULL &&
-                   json_tree_get_child(node)->next == NULL &&
-                   json_tree_get_child(node)->value_type == JSON_TYPE_ARRAY &&
-                   json_tree_get_child(json_tree_get_child(node)) == NULL);
-
-       node1 = json_tree_find_child_with(node->parent, "aobj-key", "value1");
-       node2 = json_tree_find_child_with(node->parent, "aobj-key", "value2");
-       test_assert(node1 != NULL && node2 != NULL && node1 != node2);
-       test_assert(json_tree_find_child_with(node->parent, "aobj-key", "value3") == NULL);
-
-       json_tree_deinit(&tree);
-       test_end();
-}
index 557d753a4319044da44a150b68255cec98b5c22a..59e70428505ff5eddb9f788e012e82a6259e4d1c 100644 (file)
@@ -54,7 +54,6 @@ TEST(test_istream_chain)
 TEST(test_istream_concat)
 TEST(test_istream_crlf)
 TEST(test_istream_failure_at)
-TEST(test_istream_jsonstr)
 TEST(test_istream_multiplex)
 TEST(test_istream_noop)
 TEST(test_istream_seekable)
@@ -62,8 +61,6 @@ TEST(test_istream_sized)
 TEST(test_istream_tee)
 TEST(test_istream_try)
 TEST(test_istream_unix)
-TEST(test_json_parser)
-TEST(test_json_tree)
 TEST(test_lib_event)
 TEST(test_lib_signals)
 TEST(test_llist)