Coverage Report

Created: 2026-08-31 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dovecot/src/lib-json/json-generator.c
Line
Count
Source
1
/* Copyright (c) Dovecot authors, see top-level COPYING file */
2
3
#include "lib.h"
4
#include "str.h"
5
#include "array.h"
6
#include "hex-dec.h"
7
#include "istream.h"
8
#include "ostream-private.h"
9
10
#include "json-syntax.h"
11
#include "json-generator.h"
12
13
#include <math.h>
14
15
0
#define JSON_STRING_OSTREAM_DEFAULT_BUFFER_SIZE 256
16
17
struct json_string_ostream;
18
19
enum json_generator_state {
20
  JSON_GENERATOR_STATE_VALUE = 0,
21
  JSON_GENERATOR_STATE_VALUE_END,
22
  JSON_GENERATOR_STATE_VALUE_NEXT,
23
  JSON_GENERATOR_STATE_OBJECT_MEMBER,
24
  JSON_GENERATOR_STATE_OBJECT_VALUE,
25
  JSON_GENERATOR_STATE_STRING,
26
  JSON_GENERATOR_STATE_TEXT,
27
  JSON_GENERATOR_STATE_SPACE,
28
  JSON_GENERATOR_STATE_END,
29
};
30
31
enum json_format_state {
32
  JSON_FORMAT_STATE_NONE = 0,
33
  JSON_FORMAT_STATE_INDENT,
34
  JSON_FORMAT_STATE_SPACE,
35
  JSON_FORMAT_STATE_CR,
36
  JSON_FORMAT_STATE_LF,
37
  JSON_FORMAT_STATE_DONE,
38
};
39
40
struct json_generator_level {
41
  bool object:1;
42
};
43
44
struct json_generator {
45
  struct ostream *output;
46
  enum json_generator_flags flags;
47
48
  /* Buffer for elements that the generator has assumed responsibility for
49
     by returning > 0, but could not be written to the output stream right
50
     away. */
51
  string_t *buf;
52
  /* Write position */
53
  size_t buf_pos;
54
55
  /* API state: based on called API functions */
56
  enum json_generator_state state;
57
  /* Write state: based on what is written to the output so far */
58
  enum json_generator_state write_state;
59
60
  /* Stack of syntax levels */
61
  ARRAY(struct json_generator_level) level_stack;
62
  /* API state: stack position of opened syntax levels */
63
  unsigned int level_stack_pos;
64
  /* Write state: stack position of written syntax levels */
65
  unsigned int level_stack_written;
66
67
  /* Formatting state */
68
  struct json_format format;
69
  char *format_indent;
70
  enum json_format_state format_state;
71
  unsigned int indent_pos, indent_count;
72
73
  /* Currently opened string output stream */
74
  struct json_string_ostream *str_stream;
75
  /* Currently pending string input stream */
76
  struct istream *value_input;
77
78
  /* We are in an object */
79
  bool object_level_written:1;  /* write state */
80
  bool object_level:1;          /* API state */
81
  /* We closed an empty string */
82
  bool string_empty:1;          /* API state */
83
  /* We opened an input stream string */
84
  bool string_stream:1;         /* API state */
85
  bool string_stream_written:1; /* write state */
86
  /* We opened an input stream JSON-text */
87
  bool text_stream:1;           /* API state */
88
  /* A json_string_ostream is running the generator */
89
  bool streaming:1;
90
  /* Finish writing formatting whitespace element */
91
  bool format_finish:1;
92
};
93
94
static int json_generator_flush_string_input(struct json_generator *generator);
95
static int json_generator_flush_text_input(struct json_generator *generator);
96
97
static struct json_generator *
98
json_generator_new(enum json_generator_flags flags)
99
816
{
100
816
  struct json_generator *generator;
101
102
816
  generator = i_new(struct json_generator, 1);
103
816
  generator->flags = flags;
104
816
  i_array_init(&generator->level_stack, 16);
105
106
816
  return generator;
107
816
}
108
109
struct json_generator *
110
json_generator_init(struct ostream *output, enum json_generator_flags flags)
111
0
{
112
0
  struct json_generator *generator;
113
114
0
  generator = json_generator_new(flags);
115
0
  generator->buf = str_new(default_pool, 128);
116
0
  generator->output = output;
117
0
  o_stream_ref(output);
118
119
0
  return generator;
120
0
}
121
122
struct json_generator *
123
json_generator_init_str(string_t *buf, enum json_generator_flags flags)
124
816
{
125
816
  struct json_generator *generator;
126
127
816
  generator = json_generator_new(flags);
128
816
  generator->buf = buf;
129
130
816
  return generator;
131
816
}
132
133
void json_generator_deinit(struct json_generator **_generator)
134
816
{
135
816
  struct json_generator *generator = *_generator;
136
137
816
  if (generator == NULL)
138
0
    return;
139
816
  *_generator = NULL;
140
141
816
  i_assert(generator->str_stream == NULL);
142
143
816
  i_stream_unref(&generator->value_input);
144
816
  if (generator->output != NULL) {
145
0
    o_stream_unref(&generator->output);
146
0
    str_free(&generator->buf);
147
0
  }
148
816
  array_free(&generator->level_stack);
149
816
  i_free(generator->format_indent);
150
816
  i_free(generator);
151
816
}
152
153
void json_generator_set_format(struct json_generator *generator,
154
        const struct json_format *format)
155
0
{
156
0
  i_assert(generator->state == JSON_GENERATOR_STATE_VALUE);
157
0
  i_assert(generator->write_state == JSON_GENERATOR_STATE_VALUE);
158
0
  generator->format = *format;
159
160
0
  i_free(generator->format_indent);
161
0
  if (format->indent_chars > 0) {
162
0
    generator->format_indent = i_malloc(format->indent_chars);
163
0
    memset(generator->format_indent,
164
0
           (format->indent_tab ? '\t' : ' '),
165
0
           format->indent_chars);
166
0
  }
167
0
}
168
169
static inline size_t
170
json_generator_bytes_available(struct json_generator *generator)
171
23.9k
{
172
23.9k
  if (generator->output == NULL || generator->output->blocking)
173
23.9k
    return SIZE_MAX;
174
0
  return o_stream_get_buffer_avail_size(generator->output);
175
23.9k
}
176
177
static int
178
json_generator_make_space(struct json_generator *generator, size_t space,
179
        size_t *avail_r)
180
23.9k
{
181
23.9k
  *avail_r = json_generator_bytes_available(generator);
182
23.9k
  if (*avail_r >= space)
183
23.9k
    return 1;
184
0
  if (o_stream_flush(generator->output) < 0)
185
0
    return -1;
186
0
  *avail_r = json_generator_bytes_available(generator);
187
0
  return (*avail_r >= space ? 1 : 0);
188
0
}
189
190
static int
191
json_generator_write(struct json_generator *generator,
192
         const void *data, size_t size)
193
23.9k
{
194
23.9k
  ssize_t ret;
195
196
23.9k
  if (generator->output == NULL) {
197
23.9k
    str_append_data(generator->buf, data, size);
198
23.9k
    return 1;
199
23.9k
  }
200
0
  ret = o_stream_send(generator->output, data, size);
201
0
  if (ret < 0)
202
0
    return -1;
203
0
  i_assert((size_t)ret == size);
204
0
  return 1;
205
0
}
206
207
static inline int
208
json_generator_write_all(struct json_generator *generator,
209
       const void *data, size_t size)
210
12.3k
{
211
12.3k
  size_t avail;
212
12.3k
  int ret;
213
214
12.3k
  ret = json_generator_make_space(generator, size, &avail);
215
12.3k
  if (ret <= 0)
216
0
    return ret;
217
218
12.3k
  return json_generator_write(generator, data, size);
219
12.3k
}
220
221
static int
222
json_generator_write_buffered(struct json_generator *generator,
223
            const void *data, size_t size, bool continued)
224
8.67k
{
225
8.67k
  size_t avail, write;
226
227
8.67k
  if (!continued || generator->output == NULL ||
228
8.67k
      str_len(generator->buf) == 0) {
229
    /* Try to write to output first */
230
8.67k
    if (json_generator_make_space(generator, size, &avail) < 0)
231
0
      return -1;
232
8.67k
    write = (avail < size ? avail : size);
233
8.67k
    if (write > 0) {
234
8.67k
      i_assert(generator->output == NULL ||
235
8.67k
         str_len(generator->buf) == 0);
236
8.67k
      if (json_generator_write(generator, data, write) < 0)
237
0
        return -1;
238
8.67k
      data = PTR_OFFSET(data, write);
239
8.67k
      size -= write;
240
8.67k
    }
241
8.67k
  }
242
243
8.67k
  if (size > 0) {
244
0
    i_assert(generator->output != NULL);
245
    /* Prevent buffer from growing needlessly */
246
0
    if (str_len(generator->buf) + size > 1024 &&
247
0
        generator->buf_pos > 0)
248
0
      str_delete(generator->buf, 0, generator->buf_pos);
249
    /* Append data to buffer */
250
0
    str_append_data(generator->buf, data, size);
251
0
  }
252
8.67k
  return 1;
253
8.67k
}
254
255
static int json_generator_flush_buffer(struct json_generator *generator)
256
14.8k
{
257
14.8k
  const unsigned char *data;
258
14.8k
  size_t size, avail;
259
260
14.8k
  if (generator->output == NULL)
261
14.8k
    return 1;
262
0
  if (str_len(generator->buf) == 0)
263
0
    return 1;
264
265
0
  data = str_data(generator->buf);
266
0
  size = str_len(generator->buf);
267
0
  i_assert(generator->buf_pos < size);
268
269
0
  data += generator->buf_pos;
270
0
  size -= generator->buf_pos;
271
272
0
  if (json_generator_make_space(generator, size, &avail) < 0)
273
0
    return -1;
274
0
  if (avail == 0)
275
0
    return 0;
276
0
  if (avail < size) {
277
0
    if (json_generator_write(generator, data, avail) < 0)
278
0
      return -1;
279
0
    generator->buf_pos += avail;
280
0
    return 0;
281
0
  }
282
0
  if (json_generator_write(generator, data, size) < 0)
283
0
    return -1;
284
0
  generator->buf_pos = 0;
285
0
  str_truncate(generator->buf, 0);
286
0
  return 1;
287
0
}
288
289
static int json_generator_flush_format(struct json_generator *generator)
290
14.8k
{
291
14.8k
  int ret;
292
293
14.8k
  for (;;) switch (generator->format_state) {
294
14.8k
  case JSON_FORMAT_STATE_NONE:
295
14.8k
    return 1;
296
0
  case JSON_FORMAT_STATE_CR:
297
0
    ret = json_generator_write_all(generator, "\r", 1);
298
0
    if (ret <= 0)
299
0
      return ret;
300
0
    generator->format_state = JSON_FORMAT_STATE_LF;
301
    /* fall through */
302
0
  case JSON_FORMAT_STATE_LF:
303
0
    ret = json_generator_write_all(generator, "\n", 1);
304
0
    if (ret <= 0)
305
0
      return ret;
306
0
    if (generator->format.indent_chars == 0) {
307
0
      generator->format_state = JSON_FORMAT_STATE_DONE;
308
0
      break;
309
0
    }
310
0
    generator->format_state = JSON_FORMAT_STATE_INDENT;
311
    /* fall through */
312
0
  case JSON_FORMAT_STATE_INDENT:
313
0
    i_assert(generator->format.indent_chars != 0);
314
0
    while (generator->indent_pos < generator->indent_count) {
315
0
      ret = json_generator_write_buffered(
316
0
        generator, generator->format_indent,
317
0
        generator->format.indent_chars, FALSE);
318
0
      if (ret <= 0)
319
0
        return -1;
320
0
      generator->indent_pos++;
321
0
    }
322
0
    generator->format_state = JSON_FORMAT_STATE_DONE;
323
0
    break;
324
0
  case JSON_FORMAT_STATE_SPACE:
325
0
    ret = json_generator_write_all(generator, " ", 1);
326
0
    if (ret <= 0)
327
0
      return ret;
328
0
    generator->format_state = JSON_FORMAT_STATE_DONE;
329
0
    break;
330
0
  case JSON_FORMAT_STATE_DONE:
331
0
    if (!generator->format_finish)
332
0
      return 1;
333
0
    generator->format_state = JSON_FORMAT_STATE_NONE;
334
0
    break;
335
14.8k
  }
336
14.8k
  i_unreached();
337
14.8k
}
338
339
static int
340
json_generator_write_newline(struct json_generator *generator,
341
            unsigned int indent_count, bool finish)
342
4.52k
{
343
4.52k
  if (generator->format_state == JSON_FORMAT_STATE_DONE)
344
0
    return 1;
345
4.52k
  i_assert(generator->format_state == JSON_FORMAT_STATE_NONE);
346
4.52k
  if (!generator->format.new_line)
347
4.52k
    return 1;
348
0
  if (generator->format.crlf)
349
0
    generator->format_state = JSON_FORMAT_STATE_CR;
350
0
  else
351
0
    generator->format_state = JSON_FORMAT_STATE_LF;
352
0
  generator->indent_pos = 0;
353
0
  generator->indent_count = indent_count;
354
0
  generator->format_finish = finish;
355
0
  return json_generator_flush_format(generator);
356
4.52k
}
357
358
static int
359
json_generator_write_space(struct json_generator *generator,
360
          bool finish)
361
2.89k
{
362
2.89k
  if (generator->format_state == JSON_FORMAT_STATE_DONE)
363
0
    return 1;
364
2.89k
  i_assert(generator->format_state == JSON_FORMAT_STATE_NONE);
365
2.89k
  if (!generator->format.whitespace)
366
2.89k
    return 1;
367
0
  generator->format_state = JSON_FORMAT_STATE_SPACE;
368
0
  generator->format_finish = finish;
369
0
  return json_generator_flush_format(generator);
370
2.89k
}
371
372
static void json_generator_finish_format(struct json_generator *generator)
373
816
{
374
816
  generator->format_state = JSON_FORMAT_STATE_NONE;
375
816
}
376
377
int json_generator_flush(struct json_generator *generator)
378
14.8k
{
379
14.8k
  bool hide_root = HAS_ALL_BITS(generator->flags,
380
14.8k
              JSON_GENERATOR_FLAG_HIDE_ROOT);
381
14.8k
  int ret;
382
383
  /* Flush buffer */
384
14.8k
  ret = json_generator_flush_buffer(generator);
385
14.8k
  if (ret <= 0)
386
0
    return ret;
387
  /* Flush formatting whitespace */
388
14.8k
  ret = json_generator_flush_format(generator);
389
14.8k
  if (ret <= 0)
390
0
    return ret;
391
  /* Flush closing string */
392
14.8k
  if (generator->write_state == JSON_GENERATOR_STATE_STRING &&
393
2.89k
      generator->state != JSON_GENERATOR_STATE_STRING) {
394
2.89k
    ret = json_generator_write_all(generator, "\"", 1);
395
2.89k
    if (ret <= 0)
396
0
      return ret;
397
2.89k
    generator->write_state = JSON_GENERATOR_STATE_VALUE_END;
398
2.89k
  }
399
  /* Flush object member */
400
14.8k
  if (generator->write_state == JSON_GENERATOR_STATE_OBJECT_VALUE) {
401
2.89k
    ret = json_generator_write_all(generator, ":", 1);
402
2.89k
    if (ret <= 0)
403
0
      return ret;
404
2.89k
    generator->write_state = JSON_GENERATOR_STATE_VALUE;
405
2.89k
    ret = json_generator_write_space(generator, TRUE);
406
2.89k
    if (ret <= 0)
407
0
      return ret;
408
2.89k
  }
409
  /* Flush opening objects/arrays */
410
15.6k
  for (;;) {
411
15.6k
    struct json_generator_level *level;
412
413
15.6k
    i_assert(generator->level_stack_written <=
414
15.6k
       generator->level_stack_pos);
415
15.6k
    if (generator->level_stack_written == generator->level_stack_pos)
416
14.8k
      break;
417
418
15.6k
    i_assert(generator->write_state != JSON_GENERATOR_STATE_STRING &&
419
816
       generator->write_state != JSON_GENERATOR_STATE_TEXT &&
420
816
       generator->write_state != JSON_GENERATOR_STATE_SPACE);
421
816
    if (generator->write_state == JSON_GENERATOR_STATE_VALUE_END)
422
0
      generator->write_state = JSON_GENERATOR_STATE_VALUE_NEXT;
423
816
    if (generator->write_state == JSON_GENERATOR_STATE_VALUE_NEXT) {
424
0
      ret = json_generator_write_all(generator, ",", 1);
425
0
      if (ret <= 0)
426
0
        return ret;
427
0
      generator->write_state = JSON_GENERATOR_STATE_VALUE;
428
0
      ret = json_generator_write_newline(
429
0
        generator, generator->level_stack_written,
430
0
        TRUE);
431
0
      if (ret <= 0)
432
0
        return ret;
433
0
    }
434
435
816
    level = array_idx_get_space(&generator->level_stack,
436
816
              generator->level_stack_written);
437
816
    if (level->object) {
438
816
      if (!hide_root || generator->level_stack_written > 0) {
439
816
        ret = json_generator_write_all(generator, "{", 1);
440
816
        if (ret <= 0)
441
0
          return ret;
442
816
      }
443
816
      generator->level_stack_written++;
444
816
      generator->write_state = JSON_GENERATOR_STATE_OBJECT_MEMBER;
445
816
      generator->object_level_written = TRUE;
446
816
    } else {
447
0
      if (!hide_root || generator->level_stack_written > 0) {
448
0
        ret = json_generator_write_all(generator, "[", 1);
449
0
        if (ret <= 0)
450
0
          return ret;
451
0
      }
452
0
      generator->level_stack_written++;
453
0
      generator->object_level_written = FALSE;
454
0
      generator->write_state = JSON_GENERATOR_STATE_VALUE;
455
0
    }
456
816
    ret = json_generator_write_newline(
457
816
      generator, generator->level_stack_written, TRUE);
458
816
    if (ret <= 0)
459
0
      return ret;
460
816
  }
461
  /* Flush separator */
462
14.8k
  switch (generator->write_state) {
463
  /* Flush comma */
464
7.41k
  case JSON_GENERATOR_STATE_VALUE_END:
465
7.41k
    if (generator->level_stack_pos == 0) {
466
816
      generator->write_state = JSON_GENERATOR_STATE_END;
467
816
      ret = json_generator_write_newline(
468
816
        generator, generator->level_stack_written,
469
816
        TRUE);
470
816
      if (ret <= 0)
471
0
        return ret;
472
816
      break;
473
816
    }
474
6.59k
    if (generator->state != JSON_GENERATOR_STATE_STRING &&
475
6.59k
        generator->state != JSON_GENERATOR_STATE_TEXT &&
476
6.59k
        generator->state != JSON_GENERATOR_STATE_SPACE)
477
6.59k
      break;
478
0
    generator->write_state = JSON_GENERATOR_STATE_VALUE_NEXT;
479
    /* Fall through */
480
2.07k
  case JSON_GENERATOR_STATE_VALUE_NEXT:
481
2.07k
    ret = json_generator_write_all(generator, ",", 1);
482
2.07k
    if (ret <= 0)
483
0
      return ret;
484
2.07k
    if (generator->object_level_written) {
485
2.07k
      generator->write_state = JSON_GENERATOR_STATE_OBJECT_MEMBER;
486
2.07k
    } else {
487
0
      generator->write_state = JSON_GENERATOR_STATE_VALUE;
488
0
    }
489
2.07k
    ret = json_generator_write_newline(
490
2.07k
      generator, generator->level_stack_written, TRUE);
491
2.07k
    if (ret <= 0)
492
0
      return ret;
493
2.07k
    break;
494
  /* Flush colon */
495
2.07k
  case JSON_GENERATOR_STATE_OBJECT_VALUE:
496
0
    ret = json_generator_write_all(generator, ":", 1);
497
0
    if (ret <= 0)
498
0
      return ret;
499
0
    generator->write_state = JSON_GENERATOR_STATE_VALUE;
500
0
    ret = json_generator_write_space(generator, TRUE);
501
0
    if (ret <= 0)
502
0
      return ret;
503
0
    break;
504
5.33k
  default:
505
5.33k
    break;
506
14.8k
  }
507
  /* Flush opening empty string */
508
14.8k
  if (generator->string_empty &&
509
0
      generator->write_state != JSON_GENERATOR_STATE_STRING) {
510
0
    i_assert(generator->write_state == JSON_GENERATOR_STATE_VALUE ||
511
0
       generator->write_state == JSON_GENERATOR_STATE_OBJECT_VALUE);
512
0
    ret = json_generator_write_all(generator, "\"", 1);
513
0
    if (ret <= 0)
514
0
      return ret;
515
0
    generator->string_empty = FALSE;
516
0
    ret = json_generator_write_all(generator, "\"", 1);
517
0
    if (ret < 0)
518
0
      return -1;
519
0
    if (ret == 0) {
520
0
      generator->write_state = JSON_GENERATOR_STATE_STRING;
521
0
      return 0;
522
0
    }
523
0
    generator->write_state = JSON_GENERATOR_STATE_VALUE_END;
524
  /* Flush opening string */
525
14.8k
  } else if (generator->state == JSON_GENERATOR_STATE_STRING &&
526
2.89k
       generator->write_state != JSON_GENERATOR_STATE_STRING) {
527
2.89k
    i_assert(generator->write_state == JSON_GENERATOR_STATE_VALUE ||
528
2.89k
       generator->write_state == JSON_GENERATOR_STATE_OBJECT_VALUE);
529
2.89k
    ret = json_generator_write_all(generator, "\"", 1);
530
2.89k
    if (ret <= 0)
531
0
      return ret;
532
2.89k
    generator->write_state = JSON_GENERATOR_STATE_STRING;
533
2.89k
  }
534
  /* Flush opening text */
535
14.8k
  if (generator->state == JSON_GENERATOR_STATE_TEXT &&
536
0
      generator->write_state != JSON_GENERATOR_STATE_TEXT)
537
0
    generator->write_state = JSON_GENERATOR_STATE_TEXT;
538
  /* Flush string stream */
539
14.8k
  if (generator->string_stream) {
540
0
    i_assert(generator->value_input != NULL);
541
0
    if (!generator->string_stream_written) {
542
0
      ret = json_generator_write_all(generator, "\"", 1);
543
0
      if (ret <= 0)
544
0
        return ret;
545
0
      generator->string_stream_written = TRUE;
546
0
    }
547
    /* Flush the stream */
548
0
    ret = json_generator_flush_string_input(generator);
549
0
    if (ret <= 0)
550
0
      return ret;
551
0
    generator->string_stream = FALSE;
552
0
    generator->string_stream_written = FALSE;
553
    /* Close the string */
554
0
    ret = json_generator_write_all(generator, "\"", 1);
555
0
    if (ret < 0)
556
0
      return -1;
557
0
    if (ret == 0) {
558
0
      generator->write_state = JSON_GENERATOR_STATE_STRING;
559
0
      return 0;
560
0
    }
561
0
    generator->write_state = JSON_GENERATOR_STATE_VALUE_END;
562
0
  }
563
  /* flush opening <space> */
564
14.8k
  if (generator->state == JSON_GENERATOR_STATE_SPACE &&
565
0
      generator->write_state != JSON_GENERATOR_STATE_SPACE)
566
0
    generator->write_state = JSON_GENERATOR_STATE_SPACE;
567
  /* flush string stream */
568
14.8k
  if (generator->text_stream) {
569
0
    i_assert(generator->value_input != NULL);
570
    /* flush the stream */
571
0
    ret = json_generator_flush_text_input(generator);
572
0
    if (ret <= 0)
573
0
      return ret;
574
0
    generator->text_stream = FALSE;
575
0
    generator->write_state = JSON_GENERATOR_STATE_VALUE_END;
576
0
  }
577
14.8k
  return 1;
578
14.8k
}
579
580
/*
581
 * value begin/end
582
 */
583
584
static inline void
585
json_generator_value_begin(struct json_generator *generator)
586
3.70k
{
587
3.70k
  i_assert(generator->state == JSON_GENERATOR_STATE_VALUE);
588
3.70k
  i_assert(generator->streaming || generator->str_stream == NULL);
589
3.70k
}
590
591
static inline int
592
json_generator_value_begin_flushed(struct json_generator *generator)
593
0
{
594
0
  int ret;
595
596
0
  json_generator_value_begin(generator);
597
0
  if (generator->write_state == JSON_GENERATOR_STATE_VALUE_END)
598
0
    generator->write_state = JSON_GENERATOR_STATE_VALUE_NEXT;
599
0
  ret = json_generator_flush(generator);
600
0
  if (ret <= 0)
601
0
    return ret;
602
0
  i_assert(generator->write_state == generator->state);
603
0
  return 1;
604
0
}
605
606
static inline void
607
json_generator_value_end(struct json_generator *generator)
608
816
{
609
816
  if (generator->level_stack_pos == 0)
610
816
    generator->state = JSON_GENERATOR_STATE_END;
611
0
  else if (generator->object_level)
612
0
    generator->state = JSON_GENERATOR_STATE_OBJECT_MEMBER;
613
0
  else
614
0
    generator->state = JSON_GENERATOR_STATE_VALUE;
615
816
  generator->write_state = JSON_GENERATOR_STATE_VALUE_END;
616
816
}
617
618
/*
619
 * number
620
 */
621
622
int json_generate_number(struct json_generator *generator, intmax_t number)
623
0
{
624
0
  int ret;
625
626
0
  ret = json_generator_value_begin_flushed(generator);
627
0
  if (ret <= 0)
628
0
    return ret;
629
630
0
  str_printfa(generator->buf, "%"PRIdMAX, number);
631
632
0
  json_generator_value_end(generator);
633
0
  return (json_generator_flush(generator) < 0 ? -1 : 1);
634
0
}
635
636
int json_generate_number_raw(struct json_generator *generator,
637
            const char *number)
638
0
{
639
0
  int ret;
640
641
0
  ret = json_generator_value_begin_flushed(generator);
642
0
  if (ret <= 0)
643
0
    return ret;
644
0
  if (json_generator_write_buffered(generator, number,
645
0
            strlen(number), FALSE) < 0)
646
0
    return -1;
647
0
  json_generator_value_end(generator);
648
0
  return 1;
649
0
}
650
651
/*
652
 * string
653
 */
654
655
void json_generate_string_open(struct json_generator *generator)
656
2.89k
{
657
2.89k
  json_generator_value_begin(generator);
658
2.89k
  generator->state = JSON_GENERATOR_STATE_STRING;
659
2.89k
}
660
661
static ssize_t
662
json_generate_string_write_data(struct json_generator *generator,
663
        const void *data, size_t size,
664
        bool buffered, bool last)
665
5.78k
{
666
5.78k
  const unsigned char *p, *pbegin, *pend;
667
5.78k
  size_t avail;
668
5.78k
  int ret;
669
670
5.78k
  p = pbegin = data;
671
5.78k
  pend = p + size;
672
11.5k
  while (p < pend) {
673
5.78k
    const unsigned char *poffset;
674
5.78k
    unsigned char esc_hex[6];
675
5.78k
    const char *esc = NULL;
676
5.78k
    unsigned int esc_len = 2;
677
5.78k
    int octets = 0;
678
5.78k
    unichar_t ch;
679
680
5.78k
    if (buffered)
681
2.89k
      avail = SIZE_MAX;
682
2.89k
    else {
683
2.89k
      ret = json_generator_make_space(generator, pend - p,
684
2.89k
              &avail);
685
2.89k
      if (ret < 0)
686
0
        return -1;
687
2.89k
    }
688
5.78k
    if (avail == 0)
689
0
      break;
690
691
5.78k
    poffset = p;
692
67.0k
    while (avail > 0 && p < pend && esc == NULL) {
693
61.2k
      octets = uni_utf8_get_char_n(p, (pend - p), &ch);
694
61.2k
      if (octets < 0 || (octets == 0 && last) ||
695
61.2k
          (octets > 0  && !uni_is_valid_ucs4(ch))) {
696
        /* Replace invalid UTF-8/Unicode with the
697
           replacement character. */
698
0
        esc = UNICODE_REPLACEMENT_CHAR_UTF8;
699
0
        esc_len = UTF8_REPLACEMENT_CHAR_LEN;
700
0
        octets = (octets <= 0 ? 1 : octets);
701
0
        break;
702
0
      }
703
61.2k
      if (octets == 0 || (size_t)octets > avail)
704
0
        break;
705
61.2k
      switch (ch) {
706
      /* %x22 /          ; "    quotation mark  U+0022 */
707
0
      case '"':
708
0
        esc = "\\\"";
709
0
        break;
710
      /* %x5C /          ; \    reverse solidus U+005C */
711
0
      case '\\':
712
0
        esc = "\\\\";
713
0
        break;
714
      /* %x62 /          ; b    backspace       U+0008 */
715
0
      case '\b':
716
0
        esc = "\\b";
717
0
        break;
718
      /* %x66 /          ; f    form feed       U+000C */
719
0
      case '\f':
720
0
        esc = "\\f";
721
0
        break;
722
      /* %x6E /          ; n    line feed       U+000A */
723
0
      case '\n':
724
0
        esc = "\\n";
725
0
        break;
726
      /* %x72 /          ; r    carriage return U+000D */
727
0
      case '\r':
728
0
        esc = "\\r";
729
0
        break;
730
      /* %x74 /          ; t    tab             U+0009 */
731
0
      case '\t':
732
0
        esc = "\\t";
733
0
        break;
734
61.2k
      default:
735
61.2k
        if (ch < 0x20 || ch == 0x2028 || ch == 0x2029) {
736
0
          esc_hex[0] = '\\';
737
0
          esc_hex[1] = 'u';
738
0
          dec2hex(&esc_hex[2], (uintmax_t)ch, 4);
739
0
          esc = (const char *)esc_hex;
740
0
          esc_len = sizeof(esc_hex);
741
61.2k
        } else {
742
61.2k
          p += octets;
743
61.2k
          avail -= octets;
744
61.2k
        }
745
61.2k
      }
746
61.2k
    }
747
748
5.78k
    if ((p - poffset) > 0) {
749
5.78k
      if (buffered) {
750
2.89k
        if (json_generator_write_buffered(
751
2.89k
          generator, poffset, p -poffset,
752
2.89k
          TRUE) < 0)
753
0
          return -1;
754
2.89k
      } else {
755
2.89k
        if (json_generator_write(
756
2.89k
          generator, poffset, p - poffset) < 0)
757
0
          return -1;
758
2.89k
      }
759
5.78k
    }
760
5.78k
    if (esc != NULL) {
761
0
      if (esc_len > avail) {
762
0
        break;
763
0
      } else {
764
0
        if (buffered) {
765
0
          if (json_generator_write_buffered(
766
0
            generator, esc, esc_len,
767
0
            TRUE) < 0)
768
0
            return -1;
769
0
        } else {
770
0
          if (json_generator_write(
771
0
            generator, esc, esc_len) < 0)
772
0
            return -1;
773
0
        }
774
0
        p += octets;
775
0
      }
776
0
    }
777
5.78k
    if (octets == 0 || (size_t)octets > avail)
778
0
      break;
779
5.78k
  }
780
781
5.78k
  return (ssize_t)(p - pbegin);
782
5.78k
}
783
784
ssize_t json_generate_string_more(struct json_generator *generator,
785
          const void *data, size_t size, bool last)
786
2.89k
{
787
2.89k
  int ret;
788
789
2.89k
  i_assert(generator->value_input == NULL);
790
2.89k
  i_assert(generator->state == JSON_GENERATOR_STATE_STRING);
791
2.89k
  ret = json_generator_flush(generator);
792
2.89k
  if (ret <= 0)
793
0
    return (ssize_t)ret;
794
2.89k
  i_assert(generator->write_state == JSON_GENERATOR_STATE_STRING);
795
796
2.89k
  return json_generate_string_write_data(generator, data, size,
797
2.89k
                 FALSE, last);
798
2.89k
}
799
800
void json_generate_string_close(struct json_generator *generator)
801
2.89k
{
802
2.89k
  i_assert(generator->streaming || generator->str_stream == NULL);
803
2.89k
  i_assert(generator->value_input == NULL);
804
2.89k
  i_assert(generator->state == JSON_GENERATOR_STATE_STRING);
805
2.89k
  if (generator->write_state != JSON_GENERATOR_STATE_STRING) {
806
    /* Neither this nor the string_open() function flushes
807
       first before changing state. So, we need to remember
808
       closing the empty string, because otherwise nothing will
809
       be emitted. */
810
0
    generator->string_empty = TRUE;
811
0
  }
812
2.89k
  if (generator->level_stack_pos == 0)
813
0
    generator->state = JSON_GENERATOR_STATE_END;
814
2.89k
  else if (generator->object_level)
815
2.89k
    generator->state = JSON_GENERATOR_STATE_OBJECT_MEMBER;
816
0
  else
817
0
    generator->state = JSON_GENERATOR_STATE_VALUE;
818
2.89k
}
819
820
int json_generate_string_write_close(struct json_generator *generator)
821
2.89k
{
822
2.89k
  i_assert(generator->streaming || generator->str_stream == NULL);
823
2.89k
  if (generator->state == JSON_GENERATOR_STATE_STRING)
824
2.89k
    json_generate_string_close(generator);
825
2.89k
  return json_generator_flush(generator);
826
2.89k
}
827
828
int json_generate_string_data(struct json_generator *generator,
829
            const void *data, size_t size)
830
0
{
831
0
  int ret;
832
833
0
  ret = json_generator_value_begin_flushed(generator);
834
0
  if (ret <= 0)
835
0
    return ret;
836
837
0
  if (json_generator_write_buffered(generator, "\"", 1, FALSE) < 0)
838
0
    return -1;
839
0
  if (json_generate_string_write_data(generator, data, size,
840
0
              TRUE, TRUE) < 0)
841
0
    return -1;
842
0
  if (json_generator_write_buffered(generator, "\"", 1, TRUE) < 0)
843
0
    return -1;
844
845
0
  json_generator_value_end(generator);
846
0
  return 1;
847
0
}
848
849
int json_generate_string(struct json_generator *generator, const char *str)
850
0
{
851
0
  return json_generate_string_data(generator,
852
0
           (const unsigned char *)str,
853
0
           strlen(str));
854
0
}
855
856
static int
857
json_generator_flush_string_input(struct json_generator *generator)
858
0
{
859
0
  const unsigned char *data;
860
0
  size_t size;
861
0
  ssize_t sret;
862
0
  int ret;
863
864
0
  while ((ret = i_stream_read_more(generator->value_input,
865
0
           &data, &size)) > 0) {
866
0
    sret = json_generate_string_write_data(
867
0
      generator, data, size, FALSE,
868
0
      generator->value_input->eof);
869
0
    if (sret < 0)
870
0
      return -1;
871
0
    if (sret == 0)
872
0
      return 0;
873
0
    i_stream_skip(generator->value_input, (size_t)sret);
874
0
  }
875
0
  if (ret < 0) {
876
0
    if (generator->value_input->stream_errno != 0)
877
0
      return -1;
878
879
0
    i_assert(!i_stream_have_bytes_left(generator->value_input));
880
0
    i_stream_unref(&generator->value_input);
881
0
    return 1;
882
0
  }
883
0
  return 0;
884
0
}
885
886
int json_generate_string_stream(struct json_generator *generator,
887
        struct istream *input)
888
0
{
889
0
  i_assert(generator->value_input == NULL);
890
0
  json_generator_value_begin(generator);
891
0
  generator->value_input = input;
892
0
  i_stream_ref(input);
893
0
  generator->string_stream = TRUE;
894
0
  if (generator->write_state == JSON_GENERATOR_STATE_VALUE_END)
895
0
    generator->write_state = JSON_GENERATOR_STATE_VALUE_NEXT;
896
0
  if (generator->level_stack_pos == 0)
897
0
    generator->state = JSON_GENERATOR_STATE_END;
898
0
  else if (generator->object_level)
899
0
    generator->state = JSON_GENERATOR_STATE_OBJECT_MEMBER;
900
0
  else
901
0
    generator->state = JSON_GENERATOR_STATE_VALUE;
902
0
  if (json_generator_flush(generator) < 0)
903
0
    return -1;
904
0
  return 1;
905
0
}
906
907
/*
908
 * null, true, false
909
 */
910
911
static int
912
json_generate_literal(struct json_generator *generator, const char *literal)
913
0
{
914
0
  size_t lit_size = strlen(literal);
915
0
  int ret;
916
917
0
  ret = json_generator_value_begin_flushed(generator);
918
0
  if (ret <= 0)
919
0
    return ret;
920
921
0
  ret = json_generator_write_all(generator, literal, lit_size);
922
0
  if (ret <= 0)
923
0
    return ret;
924
925
0
  json_generator_value_end(generator);
926
0
  return ret;
927
0
}
928
929
int json_generate_null(struct json_generator *generator)
930
0
{
931
0
  return json_generate_literal(generator, "null");
932
0
}
933
934
int json_generate_false(struct json_generator *generator)
935
0
{
936
0
  return json_generate_literal(generator, "false");
937
0
}
938
939
int json_generate_true(struct json_generator *generator)
940
0
{
941
0
  return json_generate_literal(generator, "true");
942
0
}
943
944
/*
945
 * stack level
946
 */
947
948
static void
949
json_generator_level_open(struct json_generator *generator, bool object)
950
816
{
951
816
  struct json_generator_level *level;
952
953
816
  level = array_idx_get_space(&generator->level_stack,
954
816
            generator->level_stack_pos++);
955
816
  i_zero(level);
956
816
  level->object = object;
957
816
  generator->object_level = object;
958
816
}
959
960
static void
961
json_generator_level_close(struct json_generator *generator, bool object)
962
816
{
963
816
  struct json_generator_level *level, *under_level;
964
965
816
  i_assert(generator->level_stack_pos > 0);
966
967
816
  i_assert(generator->level_stack_written == generator->level_stack_pos);
968
816
  generator->level_stack_written--;
969
970
816
  if (generator->level_stack_pos < 2) {
971
816
    generator->object_level_written = FALSE;
972
816
    generator->object_level = FALSE;
973
816
  } else {
974
0
    under_level = array_idx_modifiable(
975
0
      &generator->level_stack, generator->level_stack_pos-2);
976
0
    generator->object_level_written = under_level->object;
977
0
    generator->object_level = under_level->object;
978
0
  }
979
816
  level = array_idx_modifiable(&generator->level_stack,
980
816
             --generator->level_stack_pos);
981
816
  i_assert(level->object == object);
982
816
}
983
984
/*
985
 * array
986
 */
987
988
void json_generate_array_open(struct json_generator *generator)
989
0
{
990
0
  json_generator_value_begin(generator);
991
0
  json_generator_level_open(generator, FALSE);
992
0
  generator->state = JSON_GENERATOR_STATE_VALUE;
993
0
}
994
995
int json_generate_array_close(struct json_generator *generator)
996
0
{
997
0
  bool hide_root = HAS_ALL_BITS(generator->flags,
998
0
              JSON_GENERATOR_FLAG_HIDE_ROOT);
999
0
  int ret;
1000
1001
0
  i_assert(generator->str_stream == NULL);
1002
0
  i_assert(generator->state == JSON_GENERATOR_STATE_VALUE);
1003
0
  ret = json_generator_flush(generator);
1004
0
  if (ret <= 0)
1005
0
    return ret;
1006
0
  i_assert(generator->write_state == JSON_GENERATOR_STATE_VALUE ||
1007
0
     generator->write_state == JSON_GENERATOR_STATE_VALUE_END);
1008
1009
0
  i_assert(generator->level_stack_written > 0);
1010
0
  ret = json_generator_write_newline(
1011
0
    generator, generator->level_stack_written - 1, FALSE);
1012
0
  if (ret <= 0)
1013
0
    return ret;
1014
0
  if (!hide_root || generator->level_stack_written > 1) {
1015
0
    ret = json_generator_write_all(generator, "]", 1);
1016
0
    if (ret <= 0)
1017
0
      return ret;
1018
0
  }
1019
0
  json_generator_level_close(generator, FALSE);
1020
0
  json_generator_value_end(generator);
1021
0
  json_generator_finish_format(generator);
1022
0
  return 1;
1023
0
}
1024
1025
/*
1026
 * object
1027
 */
1028
1029
void json_generate_object_open(struct json_generator *generator)
1030
816
{
1031
816
  json_generator_value_begin(generator);
1032
816
  json_generator_level_open(generator, TRUE);
1033
816
  generator->state = JSON_GENERATOR_STATE_OBJECT_MEMBER;
1034
816
}
1035
1036
int json_generate_object_member(struct json_generator *generator,
1037
        const char *name)
1038
2.89k
{
1039
2.89k
  int ret;
1040
1041
2.89k
  i_assert(generator->str_stream == NULL);
1042
2.89k
  i_assert(generator->state == JSON_GENERATOR_STATE_OBJECT_MEMBER);
1043
2.89k
  if (generator->write_state == JSON_GENERATOR_STATE_VALUE_END) {
1044
2.07k
    generator->write_state = JSON_GENERATOR_STATE_VALUE_NEXT;
1045
2.07k
  }
1046
2.89k
  ret = json_generator_flush(generator);
1047
2.89k
  if (ret <= 0)
1048
0
    return ret;
1049
2.89k
  i_assert(generator->write_state == generator->state);
1050
2.89k
  generator->state = JSON_GENERATOR_STATE_VALUE;
1051
1052
2.89k
  if (json_generator_write_buffered(generator, "\"", 1, FALSE) < 0)
1053
0
    return -1;
1054
2.89k
  if (json_generate_string_write_data(
1055
2.89k
    generator, name, strlen(name), TRUE, TRUE) < 0)
1056
0
    return -1;
1057
2.89k
  if (json_generator_write_buffered(generator, "\"", 1, TRUE) < 0)
1058
0
    return -1;
1059
2.89k
  generator->write_state = JSON_GENERATOR_STATE_OBJECT_VALUE;
1060
2.89k
  return 1;
1061
2.89k
}
1062
1063
int json_generate_object_close(struct json_generator *generator)
1064
816
{
1065
816
  bool hide_root = HAS_ALL_BITS(generator->flags,
1066
816
              JSON_GENERATOR_FLAG_HIDE_ROOT);
1067
816
  int ret;
1068
1069
816
  i_assert(generator->str_stream == NULL);
1070
816
  i_assert(generator->state == JSON_GENERATOR_STATE_OBJECT_MEMBER);
1071
816
  ret = json_generator_flush(generator);
1072
816
  if (ret <= 0)
1073
0
    return ret;
1074
816
  i_assert(generator->write_state == JSON_GENERATOR_STATE_OBJECT_MEMBER ||
1075
816
     generator->write_state == JSON_GENERATOR_STATE_VALUE_END);
1076
816
  i_assert(generator->level_stack_written > 0);
1077
816
  ret = json_generator_write_newline(
1078
816
    generator, generator->level_stack_written - 1, FALSE);
1079
816
  if (ret <= 0)
1080
0
    return ret;
1081
816
  if (!hide_root || generator->level_stack_written > 1) {
1082
816
    ret = json_generator_write_all(generator, "}", 1);
1083
816
    if (ret <= 0)
1084
0
      return ret;
1085
816
  }
1086
816
  json_generator_level_close(generator, TRUE);
1087
816
  json_generator_value_end(generator);
1088
816
  json_generator_finish_format(generator);
1089
816
  return 1;
1090
816
}
1091
1092
/*
1093
 * JSON-text
1094
 */
1095
1096
void json_generate_text_open(struct json_generator *generator)
1097
0
{
1098
0
  json_generator_value_begin(generator);
1099
0
  generator->state = JSON_GENERATOR_STATE_TEXT;
1100
0
}
1101
1102
static ssize_t
1103
json_generate_text_write_data(struct json_generator *generator,
1104
            const void *data, size_t size, bool buffered)
1105
0
{
1106
0
  int ret;
1107
1108
0
  if (!buffered) {
1109
0
    size_t avail;
1110
1111
0
    ret = json_generator_make_space(generator, size, &avail);
1112
0
    if (ret < 0)
1113
0
      return -1;
1114
0
    if (avail == 0)
1115
0
      return 0;
1116
0
    if (size > avail)
1117
0
      size = avail;
1118
0
  }
1119
1120
0
  if (buffered) {
1121
0
    if (json_generator_write_buffered(generator, data, size,
1122
0
               FALSE) < 0)
1123
0
      return -1;
1124
0
  } else {
1125
0
    if (json_generator_write(generator, data, size) < 0)
1126
0
      return -1;
1127
0
  }
1128
0
  return (ssize_t)size;
1129
0
}
1130
1131
ssize_t json_generate_text_more(struct json_generator *generator,
1132
        const void *data, size_t size)
1133
0
{
1134
0
  int ret;
1135
1136
0
  i_assert(generator->state == JSON_GENERATOR_STATE_TEXT);
1137
0
  ret = json_generator_flush(generator);
1138
0
  if (ret <= 0)
1139
0
    return (ssize_t)ret;
1140
0
  i_assert(generator->write_state == JSON_GENERATOR_STATE_TEXT);
1141
1142
0
  return json_generate_text_write_data(generator, data, size, FALSE);
1143
0
}
1144
1145
int json_generate_text_close(struct json_generator *generator)
1146
0
{
1147
0
  int ret;
1148
1149
0
  i_assert(generator->state == JSON_GENERATOR_STATE_TEXT);
1150
0
  ret = json_generator_flush(generator);
1151
0
  if (ret <= 0)
1152
0
    return ret;
1153
0
  i_assert(generator->write_state == JSON_GENERATOR_STATE_TEXT);
1154
1155
0
  json_generator_value_end(generator);
1156
0
  return 1;
1157
0
}
1158
1159
int json_generate_text_data(struct json_generator *generator,
1160
          const void *data, size_t size)
1161
0
{
1162
0
  int ret;
1163
1164
0
  ret = json_generator_value_begin_flushed(generator);
1165
0
  if (ret <= 0)
1166
0
    return ret;
1167
1168
0
  if (json_generate_text_write_data(generator, data, size, TRUE) < 0)
1169
0
    return -1;
1170
0
  json_generator_value_end(generator);
1171
0
  return 1;
1172
0
}
1173
1174
int json_generate_text(struct json_generator *generator, const char *str)
1175
0
{
1176
0
  return json_generate_text_data(generator, (const unsigned char *)str,
1177
0
               strlen(str));
1178
0
}
1179
1180
static int
1181
json_generator_flush_text_input(struct json_generator *generator)
1182
0
{
1183
0
  const unsigned char *data;
1184
0
  size_t size;
1185
0
  ssize_t sret;
1186
0
  int ret;
1187
1188
0
  while ((ret = i_stream_read_more(generator->value_input,
1189
0
           &data, &size)) > 0) {
1190
0
    sret = json_generate_text_write_data(generator, data,
1191
0
                 size, FALSE);
1192
0
    if (sret < 0)
1193
0
      return -1;
1194
0
    if (sret == 0)
1195
0
      return 0;
1196
0
    i_stream_skip(generator->value_input, (size_t)sret);
1197
0
  }
1198
0
  if (ret < 0) {
1199
0
    if (generator->value_input->stream_errno != 0)
1200
0
      return -1;
1201
1202
0
    i_assert(!i_stream_have_bytes_left(generator->value_input));
1203
0
    i_stream_unref(&generator->value_input);
1204
0
    return 1;
1205
0
  }
1206
0
  return 0;
1207
0
}
1208
1209
int json_generate_text_stream(struct json_generator *generator,
1210
            struct istream *input)
1211
0
{
1212
0
  i_assert(generator->value_input == NULL);
1213
0
  json_generator_value_begin(generator);
1214
0
  generator->value_input = input;
1215
0
  i_stream_ref(input);
1216
0
  generator->text_stream = TRUE;
1217
0
  if (generator->write_state == JSON_GENERATOR_STATE_VALUE_END)
1218
0
    generator->write_state = JSON_GENERATOR_STATE_VALUE_NEXT;
1219
0
  if (generator->level_stack_pos == 0)
1220
0
    generator->state = JSON_GENERATOR_STATE_END;
1221
0
  else if (generator->object_level)
1222
0
    generator->state = JSON_GENERATOR_STATE_OBJECT_MEMBER;
1223
0
  else
1224
0
    generator->state = JSON_GENERATOR_STATE_VALUE;
1225
0
  if (json_generator_flush(generator) < 0)
1226
0
    return -1;
1227
0
  return 1;
1228
0
}
1229
1230
/*
1231
 * <space>
1232
 */
1233
1234
int json_generate_space_open(struct json_generator *generator)
1235
0
{
1236
0
  int ret;
1237
1238
0
  if (generator->state != JSON_GENERATOR_STATE_SPACE) {
1239
0
    i_assert(generator->state == JSON_GENERATOR_STATE_VALUE ||
1240
0
       generator->state == JSON_GENERATOR_STATE_OBJECT_MEMBER);
1241
0
    generator->state = JSON_GENERATOR_STATE_SPACE;
1242
0
  }
1243
1244
0
  ret = json_generator_flush(generator);
1245
0
  i_assert(ret <= 0 ||
1246
0
     generator->write_state == JSON_GENERATOR_STATE_SPACE);
1247
0
  return ret;
1248
0
}
1249
1250
void json_generate_space_close(struct json_generator *generator)
1251
0
{
1252
0
  i_assert(generator->state == JSON_GENERATOR_STATE_SPACE);
1253
0
  i_assert(generator->write_state == JSON_GENERATOR_STATE_SPACE);
1254
1255
0
  json_generator_value_end(generator);
1256
0
}
1257
1258
/*
1259
 * value
1260
 */
1261
1262
/* A stream stored in a json_tree node (JSON_CONTENT_TYPE_STREAM) is a
1263
   shared resource: json_tree_node_get_str_istream() wrappers seek it as a
1264
   side effect of tracking their own progress, and the tree may be
1265
   serialized more than once.  Rewind before reading so this generator
1266
   never depends on where some other consumer last left the stream.
1267
1268
   A STREAM value that isn't tree-owned (e.g. a JSON parser's one-shot
1269
   string stream, or a stream handed directly to
1270
   json_ostream_write_string_stream()) is read exactly once as it is
1271
   produced and must be passed through untouched: it may not be seekable,
1272
   and rewinding it would lose data already consumed by an earlier partial
1273
   write. */
1274
static void json_generate_stream_rewind(const struct json_value *value)
1275
0
{
1276
0
  if (!value->stream_is_tree_resource)
1277
0
    return;
1278
0
  i_assert(value->content.stream->seekable);
1279
0
  i_stream_seek(value->content.stream, 0);
1280
0
}
1281
1282
int json_generate_value(struct json_generator *generator,
1283
      enum json_type type, const struct json_value *value)
1284
0
{
1285
0
  switch (type) {
1286
  /* string */
1287
0
  case JSON_TYPE_STRING:
1288
0
    switch (value->content_type) {
1289
0
    case JSON_CONTENT_TYPE_STRING:
1290
0
      return json_generate_string(generator,
1291
0
                value->content.str);
1292
0
    case JSON_CONTENT_TYPE_DATA:
1293
0
      return json_generate_string_data(
1294
0
        generator, value->content.data->data,
1295
0
        value->content.data->size);
1296
0
    case JSON_CONTENT_TYPE_STREAM:
1297
0
      json_generate_stream_rewind(value);
1298
0
      return json_generate_string_stream(
1299
0
        generator, value->content.stream);
1300
0
    default:
1301
0
      break;
1302
0
    }
1303
0
    break;
1304
  /* number */
1305
0
  case JSON_TYPE_NUMBER:
1306
0
    switch (value->content_type) {
1307
0
    case JSON_CONTENT_TYPE_STRING:
1308
0
      return json_generate_number_raw(generator,
1309
0
              value->content.str);
1310
0
    case JSON_CONTENT_TYPE_INTEGER:
1311
0
      return json_generate_number(generator,
1312
0
                value->content.intnum);
1313
0
    default:
1314
0
      break;
1315
0
    }
1316
0
    break;
1317
  /* true */
1318
0
  case JSON_TYPE_TRUE:
1319
0
    return json_generate_true(generator);
1320
  /* false */
1321
0
  case JSON_TYPE_FALSE:
1322
0
    return json_generate_false(generator);
1323
  /* null */
1324
0
  case JSON_TYPE_NULL:
1325
0
    return json_generate_null(generator);
1326
  /* JSON-text */
1327
0
  case JSON_TYPE_TEXT:
1328
0
    switch (value->content_type) {
1329
0
    case JSON_CONTENT_TYPE_STRING:
1330
0
      return json_generate_text(generator,
1331
0
              value->content.str);
1332
0
    case JSON_CONTENT_TYPE_DATA:
1333
0
      return json_generate_text_data(
1334
0
        generator, value->content.data->data,
1335
0
        value->content.data->size);
1336
0
    case JSON_CONTENT_TYPE_STREAM:
1337
0
      json_generate_stream_rewind(value);
1338
0
      return json_generate_text_stream(
1339
0
        generator, value->content.stream);
1340
0
    default:
1341
0
      break;
1342
0
    }
1343
0
    break;
1344
  /* ?? */
1345
0
  default:
1346
0
    break;
1347
0
  }
1348
0
  i_unreached();
1349
0
}
1350
1351
/*
1352
 * string stream
1353
 */
1354
1355
struct json_string_ostream {
1356
  struct ostream_private ostream;
1357
1358
  buffer_t *buf;
1359
1360
  struct json_generator *generator;
1361
};
1362
1363
static void json_string_ostream_finish(struct json_string_ostream *jstream)
1364
0
{
1365
0
  struct json_generator *generator = jstream->generator;
1366
1367
0
  if (generator == NULL)
1368
0
    return;
1369
1370
0
  generator->streaming = TRUE;
1371
0
  json_generate_string_close(generator);
1372
0
  generator->streaming = FALSE;
1373
1374
0
  generator->str_stream = NULL;
1375
0
  jstream->generator = NULL;
1376
0
}
1377
1378
static void json_string_ostream_cork(struct ostream_private *stream, bool set)
1379
0
{
1380
0
  struct json_string_ostream *jstream =
1381
0
    container_of(stream, struct json_string_ostream, ostream);
1382
0
  struct json_generator *generator = jstream->generator;
1383
1384
0
  if (generator == NULL || generator->output == NULL)
1385
0
    return;
1386
0
  if (set)
1387
0
    o_stream_cork(generator->output);
1388
0
  else
1389
0
    o_stream_uncork(generator->output);
1390
0
}
1391
1392
static void
1393
json_string_ostream_close(struct iostream_private *stream,
1394
         bool close_parent)
1395
0
{
1396
0
  struct ostream_private *_stream =
1397
0
    container_of(stream, struct ostream_private, iostream);
1398
0
  struct json_string_ostream *jstream =
1399
0
    container_of(_stream, struct json_string_ostream, ostream);
1400
1401
0
  if (jstream->ostream.ostream.stream_errno == 0)
1402
0
    json_string_ostream_finish(jstream);
1403
0
  if (close_parent)
1404
0
    o_stream_close(jstream->ostream.parent);
1405
0
}
1406
1407
static ssize_t
1408
json_string_ostream_send(struct json_string_ostream *jstream,
1409
        const void *data, size_t size)
1410
0
{
1411
0
  struct ostream_private *stream = &jstream->ostream;
1412
0
  struct json_generator *generator = jstream->generator;
1413
0
  ssize_t sret;
1414
1415
0
  generator->streaming = TRUE;
1416
1417
0
  sret = json_generate_string_more(generator, data, size,
1418
0
           stream->finished);
1419
0
  if (sret < 0) {
1420
0
    io_stream_set_error(&stream->iostream, "%s",
1421
0
            o_stream_get_error(generator->output));
1422
0
    stream->ostream.stream_errno =
1423
0
      generator->output->stream_errno;
1424
0
    generator->streaming = FALSE;
1425
0
    return -1;
1426
0
  }
1427
1428
0
  generator->streaming = FALSE;
1429
0
  return sret;
1430
0
}
1431
1432
static int json_string_ostream_send_buffer(struct json_string_ostream *jstream)
1433
0
{
1434
0
  ssize_t sret;
1435
1436
0
  if (jstream->buf == NULL)
1437
0
    return 1;
1438
1439
0
  sret = json_string_ostream_send(jstream, jstream->buf->data,
1440
0
          jstream->buf->used);
1441
0
  if (sret < 0)
1442
0
    return -1;
1443
1444
0
  if ((size_t)sret == jstream->buf->used) {
1445
0
    buffer_set_used_size(jstream->buf, 0);
1446
0
    return 1;
1447
0
  }
1448
0
  buffer_delete(jstream->buf, 0, (size_t)sret);
1449
0
  return 0;
1450
0
}
1451
1452
static ssize_t
1453
json_string_ostream_sendv(struct ostream_private *stream,
1454
        const struct const_iovec *iov,
1455
        unsigned int iov_count)
1456
0
{
1457
0
  struct json_string_ostream *jstream =
1458
0
    container_of(stream, struct json_string_ostream, ostream);
1459
0
  ssize_t sret, sent;
1460
0
  unsigned int i;
1461
0
  int ret;
1462
1463
0
  ret = json_string_ostream_send_buffer(jstream);
1464
0
  if (ret <= 0)
1465
0
    return (ssize_t)ret;
1466
1467
0
  sent = 0;
1468
0
  for (i = 0; i < iov_count; i++) {
1469
0
    sret = json_string_ostream_send(jstream, iov[i].iov_base,
1470
0
            iov[i].iov_len);
1471
0
    if (sret < 0)
1472
0
      return -1;
1473
0
    sent += sret;
1474
0
    if ((size_t)sret != iov[i].iov_len)
1475
0
      break;
1476
0
  }
1477
1478
0
  if (jstream->buf != NULL) {
1479
0
    for (; i < iov_count; i++) {
1480
0
      const void *base;
1481
0
      size_t avail, append;
1482
1483
0
      i_assert(jstream->buf->used <=
1484
0
         jstream->ostream.max_buffer_size);
1485
0
      avail = (jstream->ostream.max_buffer_size -
1486
0
         jstream->buf->used);
1487
0
      if (avail == 0)
1488
0
        break;
1489
1490
0
      if (sret > 0) {
1491
0
        i_assert((size_t)sret < iov[i].iov_len);
1492
0
        append = iov[i].iov_len - (size_t)sret;
1493
0
        base = PTR_OFFSET(iov[i].iov_base, (size_t)sret);
1494
0
        sret = 0;
1495
0
      } else {
1496
0
        append = iov[i].iov_len;
1497
0
        base = iov[i].iov_base;
1498
0
      }
1499
1500
0
      if (append < avail) {
1501
0
        buffer_append(jstream->buf, base, append);
1502
0
        sent += append;
1503
0
      } else {
1504
0
        buffer_append(jstream->buf, base, avail);
1505
0
        sent += avail;
1506
0
        break;
1507
0
      }
1508
0
    }
1509
0
  }
1510
1511
0
  return sent;
1512
0
}
1513
1514
static int json_string_ostream_flush(struct ostream_private *stream)
1515
0
{
1516
0
  struct json_string_ostream *jstream =
1517
0
    container_of(stream, struct json_string_ostream, ostream);
1518
1519
0
  if (json_string_ostream_send_buffer(jstream) <= 0)
1520
0
    return 0;
1521
1522
0
  if (stream->finished)
1523
0
    json_string_ostream_finish(jstream);
1524
0
  return 1;
1525
0
}
1526
1527
static void json_string_ostream_destroy(struct iostream_private *stream)
1528
0
{
1529
0
  struct ostream_private *_stream =
1530
0
    container_of(stream, struct ostream_private, iostream);
1531
0
  struct json_string_ostream *jstream =
1532
0
    container_of(_stream, struct json_string_ostream, ostream);
1533
1534
0
  buffer_free(&jstream->buf);
1535
0
}
1536
1537
static size_t
1538
json_string_ostream_get_buffer_used_size(const struct ostream_private *stream)
1539
0
{
1540
0
  const struct json_string_ostream *jstream =
1541
0
    container_of(stream, const struct json_string_ostream,
1542
0
           ostream);
1543
0
  struct json_generator *generator = jstream->generator;
1544
0
  size_t size = 0;
1545
1546
0
  if (jstream->buf != NULL)
1547
0
    size += jstream->buf->used;
1548
0
  return (size + o_stream_get_buffer_used_size(generator->output));
1549
0
}
1550
1551
static size_t
1552
json_string_ostream_get_buffer_avail_size(const struct ostream_private *stream)
1553
0
{
1554
0
  const struct json_string_ostream *jstream =
1555
0
    container_of(stream, const struct json_string_ostream,
1556
0
           ostream);
1557
0
  struct json_generator *generator = jstream->generator;
1558
1559
0
  return o_stream_get_buffer_avail_size(generator->output);
1560
0
}
1561
1562
static void
1563
json_string_ostream_set_max_buffer_size(struct iostream_private *stream,
1564
          size_t max_size)
1565
0
{
1566
0
  struct ostream_private *_stream =
1567
0
    container_of(stream, struct ostream_private, iostream);
1568
0
  struct json_string_ostream *jstream =
1569
0
    container_of(_stream, struct json_string_ostream, ostream);
1570
0
  struct json_generator *generator = jstream->generator;
1571
1572
0
  jstream->ostream.max_buffer_size =
1573
0
    o_stream_get_max_buffer_size(generator->output) / 6;
1574
0
  if (jstream->ostream.max_buffer_size < max_size) {
1575
0
    jstream->ostream.max_buffer_size = max_size;
1576
0
    if (jstream->buf == NULL)
1577
0
      jstream->buf = buffer_create_dynamic(default_pool, 256);
1578
0
  } else {
1579
0
    buffer_free(&jstream->buf);
1580
0
  }
1581
0
}
1582
1583
struct ostream *
1584
json_generate_string_open_stream(struct json_generator *generator)
1585
0
{
1586
0
  struct json_string_ostream *jstream;
1587
1588
0
  i_assert(generator->str_stream == NULL);
1589
1590
0
  jstream = i_new(struct json_string_ostream, 1);
1591
0
  jstream->generator = generator;
1592
0
  jstream->ostream.cork = json_string_ostream_cork;
1593
0
  jstream->ostream.sendv = json_string_ostream_sendv;
1594
0
  jstream->ostream.flush = json_string_ostream_flush;
1595
0
  jstream->ostream.iostream.close = json_string_ostream_close;
1596
0
  jstream->ostream.get_buffer_used_size =
1597
0
    json_string_ostream_get_buffer_used_size;
1598
0
  jstream->ostream.get_buffer_avail_size =
1599
0
    json_string_ostream_get_buffer_avail_size;
1600
0
  jstream->ostream.iostream.destroy = json_string_ostream_destroy;
1601
0
  jstream->ostream.iostream.set_max_buffer_size =
1602
0
    json_string_ostream_set_max_buffer_size;
1603
1604
  /* base default max_buffer_size on worst-case escape ratio */
1605
0
  jstream->ostream.max_buffer_size =
1606
0
    o_stream_get_max_buffer_size(generator->output) / 6;
1607
0
  if (jstream->ostream.max_buffer_size <
1608
0
    JSON_STRING_OSTREAM_DEFAULT_BUFFER_SIZE) {
1609
0
    jstream->ostream.max_buffer_size =
1610
0
      JSON_STRING_OSTREAM_DEFAULT_BUFFER_SIZE;
1611
0
    jstream->buf = buffer_create_dynamic(default_pool, 256);
1612
0
  }
1613
1614
0
  json_generate_string_open(jstream->generator);
1615
0
  generator->str_stream = jstream;
1616
1617
0
  return o_stream_create(&jstream->ostream, NULL, -1);
1618
0
}
1619
1620
/*
1621
 * Simple string output
1622
 */
1623
1624
static void json_append_escaped_char(string_t *dest, unsigned char src)
1625
0
{
1626
0
  switch (src) {
1627
0
  case '\b':
1628
0
    str_append(dest, "\\b");
1629
0
    break;
1630
0
  case '\f':
1631
0
    str_append(dest, "\\f");
1632
0
    break;
1633
0
  case '\n':
1634
0
    str_append(dest, "\\n");
1635
0
    break;
1636
0
  case '\r':
1637
0
    str_append(dest, "\\r");
1638
0
    break;
1639
0
  case '\t':
1640
0
    str_append(dest, "\\t");
1641
0
    break;
1642
0
  case '"':
1643
0
    str_append(dest, "\\\"");
1644
0
    break;
1645
0
  case '\\':
1646
0
    str_append(dest, "\\\\");
1647
0
    break;
1648
0
  default:
1649
0
    if (src < 0x20)
1650
0
      str_printfa(dest, "\\u%04x", src);
1651
0
    else
1652
0
      str_append_c(dest, src);
1653
0
    break;
1654
0
  }
1655
0
}
1656
1657
static void json_append_escaped_ucs4(string_t *dest, unichar_t chr)
1658
0
{
1659
0
  if (chr < 0x80)
1660
0
    json_append_escaped_char(dest, (unsigned char)chr);
1661
0
  else if (chr == 0x2028 || chr == 0x2029)
1662
0
    str_printfa(dest, "\\u%04x", chr);
1663
0
  else
1664
0
    uni_ucs4_to_utf8_c(chr, dest);
1665
0
}
1666
1667
1668
void json_append_escaped(string_t *dest, const char *src)
1669
0
{
1670
0
  json_append_escaped_data(dest, (const unsigned char*)src, strlen(src));
1671
0
}
1672
1673
void json_append_escaped_data(string_t *dest, const unsigned char *src,
1674
            size_t size)
1675
0
{
1676
0
  size_t i;
1677
0
  int bytes = 0;
1678
0
  unichar_t chr;
1679
1680
0
  for (i = 0; i < size;) {
1681
0
    bytes = uni_utf8_get_char_n(src+i, size-i, &chr);
1682
0
    if (bytes > 0 && uni_is_valid_ucs4(chr)) {
1683
0
      json_append_escaped_ucs4(dest, chr);
1684
0
      i += bytes;
1685
0
    } else {
1686
0
      str_append_data(dest, UNICODE_REPLACEMENT_CHAR_UTF8,
1687
0
          UTF8_REPLACEMENT_CHAR_LEN);
1688
0
      i++;
1689
0
    }
1690
0
  }
1691
0
}