Coverage Report

Created: 2026-08-31 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/jansson/src/value.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>
3
 *
4
 * Jansson is free software; you can redistribute it and/or modify
5
 * it under the terms of the MIT license. See LICENSE for details.
6
 */
7
8
#ifndef _GNU_SOURCE
9
#define _GNU_SOURCE
10
#endif
11
12
#ifdef HAVE_CONFIG_H
13
#include <jansson_private_config.h>
14
#endif
15
16
#include <math.h>
17
#include <stddef.h>
18
#include <stdlib.h>
19
#include <string.h>
20
21
#ifdef HAVE_STDINT_H
22
#include <stdint.h>
23
#endif
24
25
#include "hashtable.h"
26
#include "jansson.h"
27
#include "jansson_private.h"
28
#include "utf.h"
29
30
/* Work around nonstandard isnan() and isinf() implementations */
31
#ifndef isnan
32
#ifndef __sun
33
static JSON_INLINE int isnan(double x) { return x != x; }
34
#endif
35
#endif
36
#ifndef isinf
37
static JSON_INLINE int isinf(double x) { return !isnan(x) && isnan(x - x); }
38
#endif
39
40
static int do_equal(const json_t *json1, const json_t *json2, int depth);
41
json_t *do_deep_copy(const json_t *json, hashtable_t *parents, int depth);
42
43
0
static JSON_INLINE void json_init(json_t *json, json_type type) {
44
0
    json->type = type;
45
0
    json->refcount = 1;
46
0
}
47
48
int jsonp_loop_check(hashtable_t *parents, const json_t *json, char *key, size_t key_size,
49
0
                     size_t *key_len_out) {
50
0
    size_t key_len = snprintf(key, key_size, "%p", json);
51
52
0
    if (key_len_out)
53
0
        *key_len_out = key_len;
54
55
0
    if (hashtable_get(parents, key, key_len))
56
0
        return -1;
57
58
0
    return hashtable_set(parents, key, key_len, json_null());
59
0
}
60
61
/*** object ***/
62
63
extern volatile uint32_t hashtable_seed;
64
65
0
json_t *json_object(void) {
66
0
    json_object_t *object = jsonp_malloc(sizeof(json_object_t));
67
0
    if (!object)
68
0
        return NULL;
69
70
0
    if (!hashtable_seed) {
71
        /* Autoseed */
72
0
        json_object_seed(0);
73
0
    }
74
75
0
    json_init(&object->json, JSON_OBJECT);
76
77
0
    if (hashtable_init(&object->hashtable)) {
78
0
        jsonp_free(object);
79
0
        return NULL;
80
0
    }
81
82
0
    return &object->json;
83
0
}
84
85
0
static void json_delete_object(json_object_t *object) {
86
0
    hashtable_close(&object->hashtable);
87
0
    jsonp_free(object);
88
0
}
89
90
0
size_t json_object_size(const json_t *json) {
91
0
    json_object_t *object;
92
93
0
    if (!json_is_object(json))
94
0
        return 0;
95
96
0
    object = json_to_object(json);
97
0
    return object->hashtable.size;
98
0
}
99
100
0
json_t *json_object_get(const json_t *json, const char *key) {
101
0
    if (!key)
102
0
        return NULL;
103
104
0
    return json_object_getn(json, key, strlen(key));
105
0
}
106
107
0
json_t *json_object_getn(const json_t *json, const char *key, size_t key_len) {
108
0
    json_object_t *object;
109
110
0
    if (!key || !json_is_object(json))
111
0
        return NULL;
112
113
0
    object = json_to_object(json);
114
0
    return hashtable_get(&object->hashtable, key, key_len);
115
0
}
116
117
0
int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value) {
118
0
    if (!key) {
119
0
        json_decref(value);
120
0
        return -1;
121
0
    }
122
0
    return json_object_setn_new_nocheck(json, key, strlen(key), value);
123
0
}
124
125
int json_object_setn_new_nocheck(json_t *json, const char *key, size_t key_len,
126
0
                                 json_t *value) {
127
0
    json_object_t *object;
128
129
0
    if (!value)
130
0
        return -1;
131
132
0
    if (!key || !json_is_object(json) || json == value) {
133
0
        json_decref(value);
134
0
        return -1;
135
0
    }
136
0
    object = json_to_object(json);
137
138
0
    if (hashtable_set(&object->hashtable, key, key_len, value)) {
139
0
        json_decref(value);
140
0
        return -1;
141
0
    }
142
143
0
    return 0;
144
0
}
145
146
0
int json_object_set_new(json_t *json, const char *key, json_t *value) {
147
0
    if (!key) {
148
0
        json_decref(value);
149
0
        return -1;
150
0
    }
151
152
0
    return json_object_setn_new(json, key, strlen(key), value);
153
0
}
154
155
0
int json_object_setn_new(json_t *json, const char *key, size_t key_len, json_t *value) {
156
0
    if (!key || !utf8_check_string(key, key_len)) {
157
0
        json_decref(value);
158
0
        return -1;
159
0
    }
160
161
0
    return json_object_setn_new_nocheck(json, key, key_len, value);
162
0
}
163
164
0
int json_object_del(json_t *json, const char *key) {
165
0
    if (!key)
166
0
        return -1;
167
168
0
    return json_object_deln(json, key, strlen(key));
169
0
}
170
171
0
int json_object_deln(json_t *json, const char *key, size_t key_len) {
172
0
    json_object_t *object;
173
174
0
    if (!key || !json_is_object(json))
175
0
        return -1;
176
177
0
    object = json_to_object(json);
178
0
    return hashtable_del(&object->hashtable, key, key_len);
179
0
}
180
181
0
int json_object_clear(json_t *json) {
182
0
    json_object_t *object;
183
184
0
    if (!json_is_object(json))
185
0
        return -1;
186
187
0
    object = json_to_object(json);
188
0
    hashtable_clear(&object->hashtable);
189
190
0
    return 0;
191
0
}
192
193
0
int json_object_update(json_t *object, json_t *other) {
194
0
    const char *key;
195
0
    size_t key_len;
196
0
    json_t *value;
197
198
0
    if (!json_is_object(object) || !json_is_object(other))
199
0
        return -1;
200
201
0
    json_object_keylen_foreach(other, key, key_len, value) {
202
0
        if (json_object_setn_nocheck(object, key, key_len, value))
203
0
            return -1;
204
0
    }
205
206
0
    return 0;
207
0
}
208
209
0
int json_object_update_existing(json_t *object, json_t *other) {
210
0
    const char *key;
211
0
    size_t key_len;
212
0
    json_t *value;
213
214
0
    if (!json_is_object(object) || !json_is_object(other))
215
0
        return -1;
216
217
0
    json_object_keylen_foreach(other, key, key_len, value) {
218
0
        if (json_object_getn(object, key, key_len))
219
0
            json_object_setn_nocheck(object, key, key_len, value);
220
0
    }
221
222
0
    return 0;
223
0
}
224
225
0
int json_object_update_missing(json_t *object, json_t *other) {
226
0
    const char *key;
227
0
    size_t key_len;
228
0
    json_t *value;
229
230
0
    if (!json_is_object(object) || !json_is_object(other))
231
0
        return -1;
232
233
0
    json_object_keylen_foreach(other, key, key_len, value) {
234
0
        if (!json_object_getn(object, key, key_len))
235
0
            json_object_setn_nocheck(object, key, key_len, value);
236
0
    }
237
238
0
    return 0;
239
0
}
240
241
0
int do_object_update_recursive(json_t *object, json_t *other, hashtable_t *parents) {
242
0
    const char *key;
243
0
    size_t key_len;
244
0
    json_t *value;
245
0
    char loop_key[LOOP_KEY_LEN];
246
0
    int res = 0;
247
0
    size_t loop_key_len;
248
249
0
    if (!json_is_object(object) || !json_is_object(other))
250
0
        return -1;
251
252
0
    if (jsonp_loop_check(parents, other, loop_key, sizeof(loop_key), &loop_key_len))
253
0
        return -1;
254
255
0
    json_object_keylen_foreach(other, key, key_len, value) {
256
0
        json_t *v = json_object_getn(object, key, key_len);
257
258
0
        if (json_is_object(v) && json_is_object(value)) {
259
0
            if (do_object_update_recursive(v, value, parents)) {
260
0
                res = -1;
261
0
                break;
262
0
            }
263
0
        } else {
264
0
            if (json_object_setn_nocheck(object, key, key_len, value)) {
265
0
                res = -1;
266
0
                break;
267
0
            }
268
0
        }
269
0
    }
270
271
0
    hashtable_del(parents, loop_key, loop_key_len);
272
273
0
    return res;
274
0
}
275
276
0
int json_object_update_recursive(json_t *object, json_t *other) {
277
0
    int res;
278
0
    hashtable_t parents_set;
279
280
0
    if (hashtable_init(&parents_set))
281
0
        return -1;
282
0
    res = do_object_update_recursive(object, other, &parents_set);
283
0
    hashtable_close(&parents_set);
284
285
0
    return res;
286
0
}
287
288
0
void *json_object_iter(json_t *json) {
289
0
    json_object_t *object;
290
291
0
    if (!json_is_object(json))
292
0
        return NULL;
293
294
0
    object = json_to_object(json);
295
0
    return hashtable_iter(&object->hashtable);
296
0
}
297
298
0
void *json_object_iter_at(json_t *json, const char *key) {
299
0
    json_object_t *object;
300
301
0
    if (!key || !json_is_object(json))
302
0
        return NULL;
303
304
0
    object = json_to_object(json);
305
0
    return hashtable_iter_at(&object->hashtable, key, strlen(key));
306
0
}
307
308
0
void *json_object_iter_next(json_t *json, void *iter) {
309
0
    json_object_t *object;
310
311
0
    if (!json_is_object(json) || iter == NULL)
312
0
        return NULL;
313
314
0
    object = json_to_object(json);
315
0
    return hashtable_iter_next(&object->hashtable, iter);
316
0
}
317
318
0
const char *json_object_iter_key(void *iter) {
319
0
    if (!iter)
320
0
        return NULL;
321
322
0
    return hashtable_iter_key(iter);
323
0
}
324
325
0
size_t json_object_iter_key_len(void *iter) {
326
0
    if (!iter)
327
0
        return 0;
328
329
0
    return hashtable_iter_key_len(iter);
330
0
}
331
332
0
json_t *json_object_iter_value(void *iter) {
333
0
    if (!iter)
334
0
        return NULL;
335
336
0
    return (json_t *)hashtable_iter_value(iter);
337
0
}
338
339
0
int json_object_iter_set_new(json_t *json, void *iter, json_t *value) {
340
0
    if (!json_is_object(json) || !iter || !value) {
341
0
        json_decref(value);
342
0
        return -1;
343
0
    }
344
345
0
    hashtable_iter_set(iter, value);
346
0
    return 0;
347
0
}
348
349
0
void *json_object_key_to_iter(const char *key) {
350
0
    if (!key)
351
0
        return NULL;
352
353
0
    return hashtable_key_to_iter(key);
354
0
}
355
356
0
static int json_object_equal(const json_t *object1, const json_t *object2, int depth) {
357
0
    const char *key;
358
0
    size_t key_len;
359
0
    const json_t *value1, *value2;
360
361
0
    if (json_object_size(object1) != json_object_size(object2))
362
0
        return 0;
363
364
0
    json_object_keylen_foreach((json_t *)object1, key, key_len, value1) {
365
0
        value2 = json_object_getn(object2, key, key_len);
366
367
0
        if (!do_equal(value1, value2, depth + 1))
368
0
            return 0;
369
0
    }
370
371
0
    return 1;
372
0
}
373
374
0
static json_t *json_object_copy(json_t *object) {
375
0
    json_t *result;
376
377
0
    const char *key;
378
0
    size_t key_len;
379
0
    json_t *value;
380
381
0
    result = json_object();
382
0
    if (!result)
383
0
        return NULL;
384
385
0
    json_object_keylen_foreach(object, key, key_len, value)
386
0
        json_object_setn_nocheck(result, key, key_len, value);
387
388
0
    return result;
389
0
}
390
391
static json_t *json_object_deep_copy(const json_t *object, hashtable_t *parents,
392
0
                                     int depth) {
393
0
    json_t *result;
394
0
    void *iter;
395
0
    char loop_key[LOOP_KEY_LEN];
396
0
    size_t loop_key_len;
397
398
0
    if (jsonp_loop_check(parents, object, loop_key, sizeof(loop_key), &loop_key_len))
399
0
        return NULL;
400
401
0
    result = json_object();
402
0
    if (!result)
403
0
        goto out;
404
405
    /* Cannot use json_object_foreach because object has to be cast
406
       non-const */
407
0
    iter = json_object_iter((json_t *)object);
408
0
    while (iter) {
409
0
        const char *key;
410
0
        size_t key_len;
411
0
        const json_t *value;
412
0
        key = json_object_iter_key(iter);
413
0
        key_len = json_object_iter_key_len(iter);
414
0
        value = json_object_iter_value(iter);
415
416
0
        if (json_object_setn_new_nocheck(result, key, key_len,
417
0
                                         do_deep_copy(value, parents, depth + 1))) {
418
0
            json_decref(result);
419
0
            result = NULL;
420
0
            break;
421
0
        }
422
0
        iter = json_object_iter_next((json_t *)object, iter);
423
0
    }
424
425
0
out:
426
0
    hashtable_del(parents, loop_key, loop_key_len);
427
428
0
    return result;
429
0
}
430
431
/*** array ***/
432
433
0
json_t *json_array(void) {
434
0
    json_array_t *array = jsonp_malloc(sizeof(json_array_t));
435
0
    if (!array)
436
0
        return NULL;
437
0
    json_init(&array->json, JSON_ARRAY);
438
439
0
    array->entries = 0;
440
0
    array->size = 8;
441
442
0
    array->table = jsonp_malloc(array->size * sizeof(json_t *));
443
0
    if (!array->table) {
444
0
        jsonp_free(array);
445
0
        return NULL;
446
0
    }
447
448
0
    return &array->json;
449
0
}
450
451
0
static void json_delete_array(json_array_t *array) {
452
0
    size_t i;
453
454
0
    for (i = 0; i < array->entries; i++)
455
0
        json_decref(array->table[i]);
456
457
0
    jsonp_free(array->table);
458
0
    jsonp_free(array);
459
0
}
460
461
0
size_t json_array_size(const json_t *json) {
462
0
    if (!json_is_array(json))
463
0
        return 0;
464
465
0
    return json_to_array(json)->entries;
466
0
}
467
468
0
json_t *json_array_get(const json_t *json, size_t index) {
469
0
    json_array_t *array;
470
0
    if (!json_is_array(json))
471
0
        return NULL;
472
0
    array = json_to_array(json);
473
474
0
    if (index >= array->entries)
475
0
        return NULL;
476
477
0
    return array->table[index];
478
0
}
479
480
0
int json_array_set_new(json_t *json, size_t index, json_t *value) {
481
0
    json_array_t *array;
482
483
0
    if (!value)
484
0
        return -1;
485
486
0
    if (!json_is_array(json) || json == value) {
487
0
        json_decref(value);
488
0
        return -1;
489
0
    }
490
0
    array = json_to_array(json);
491
492
0
    if (index >= array->entries) {
493
0
        json_decref(value);
494
0
        return -1;
495
0
    }
496
497
0
    json_decref(array->table[index]);
498
0
    array->table[index] = value;
499
500
0
    return 0;
501
0
}
502
503
0
static void array_move(json_array_t *array, size_t dest, size_t src, size_t count) {
504
0
    memmove(&array->table[dest], &array->table[src], count * sizeof(json_t *));
505
0
}
506
507
static void array_copy(json_t **dest, size_t dpos, json_t **src, size_t spos,
508
0
                       size_t count) {
509
0
    memcpy(&dest[dpos], &src[spos], count * sizeof(json_t *));
510
0
}
511
512
0
static json_t **json_array_grow(json_array_t *array, size_t amount) {
513
0
    size_t new_size;
514
0
    json_t **old_table, **new_table;
515
516
0
    if (array->entries + amount <= array->size)
517
0
        return array->table;
518
519
0
    old_table = array->table;
520
521
0
    new_size = max(array->size + amount, array->size * 2);
522
0
    new_table = jsonp_realloc(old_table, array->size * sizeof(json_t *),
523
0
                              new_size * sizeof(json_t *));
524
0
    if (!new_table)
525
0
        return NULL;
526
527
0
    array->size = new_size;
528
0
    array->table = new_table;
529
530
0
    return array->table;
531
0
}
532
533
0
int json_array_append_new(json_t *json, json_t *value) {
534
0
    json_array_t *array;
535
536
0
    if (!value)
537
0
        return -1;
538
539
0
    if (!json_is_array(json) || json == value) {
540
0
        json_decref(value);
541
0
        return -1;
542
0
    }
543
0
    array = json_to_array(json);
544
545
0
    if (!json_array_grow(array, 1)) {
546
0
        json_decref(value);
547
0
        return -1;
548
0
    }
549
550
0
    array->table[array->entries] = value;
551
0
    array->entries++;
552
553
0
    return 0;
554
0
}
555
556
0
int json_array_insert_new(json_t *json, size_t index, json_t *value) {
557
0
    json_array_t *array;
558
559
0
    if (!value)
560
0
        return -1;
561
562
0
    if (!json_is_array(json) || json == value) {
563
0
        json_decref(value);
564
0
        return -1;
565
0
    }
566
0
    array = json_to_array(json);
567
568
0
    if (index > array->entries) {
569
0
        json_decref(value);
570
0
        return -1;
571
0
    }
572
573
0
    if (!json_array_grow(array, 1)) {
574
0
        json_decref(value);
575
0
        return -1;
576
0
    }
577
0
    if (index != array->entries)
578
0
        array_move(array, index + 1, index, array->entries - index);
579
580
0
    array->table[index] = value;
581
0
    array->entries++;
582
583
0
    return 0;
584
0
}
585
586
0
int json_array_remove(json_t *json, size_t index) {
587
0
    json_array_t *array;
588
589
0
    if (!json_is_array(json))
590
0
        return -1;
591
0
    array = json_to_array(json);
592
593
0
    if (index >= array->entries)
594
0
        return -1;
595
596
0
    json_decref(array->table[index]);
597
598
    /* If we're removing the last element, nothing has to be moved */
599
0
    if (index < array->entries - 1)
600
0
        array_move(array, index, index + 1, array->entries - index - 1);
601
602
0
    array->entries--;
603
604
0
    return 0;
605
0
}
606
607
0
int json_array_clear(json_t *json) {
608
0
    json_array_t *array;
609
0
    size_t i;
610
611
0
    if (!json_is_array(json))
612
0
        return -1;
613
0
    array = json_to_array(json);
614
615
0
    for (i = 0; i < array->entries; i++)
616
0
        json_decref(array->table[i]);
617
618
0
    array->entries = 0;
619
0
    return 0;
620
0
}
621
622
0
int json_array_extend(json_t *json, json_t *other_json) {
623
0
    json_array_t *array, *other;
624
0
    size_t i;
625
626
0
    if (!json_is_array(json) || !json_is_array(other_json))
627
0
        return -1;
628
0
    array = json_to_array(json);
629
0
    other = json_to_array(other_json);
630
631
0
    if (!json_array_grow(array, other->entries))
632
0
        return -1;
633
634
0
    for (i = 0; i < other->entries; i++)
635
0
        json_incref(other->table[i]);
636
637
0
    array_copy(array->table, array->entries, other->table, 0, other->entries);
638
639
0
    array->entries += other->entries;
640
0
    return 0;
641
0
}
642
643
0
static int json_array_equal(const json_t *array1, const json_t *array2, int depth) {
644
0
    size_t i, size;
645
646
0
    size = json_array_size(array1);
647
0
    if (size != json_array_size(array2))
648
0
        return 0;
649
650
0
    for (i = 0; i < size; i++) {
651
0
        json_t *value1, *value2;
652
653
0
        value1 = json_array_get(array1, i);
654
0
        value2 = json_array_get(array2, i);
655
656
0
        if (!do_equal(value1, value2, depth + 1))
657
0
            return 0;
658
0
    }
659
660
0
    return 1;
661
0
}
662
663
0
static json_t *json_array_copy(json_t *array) {
664
0
    json_t *result;
665
0
    size_t i;
666
667
0
    result = json_array();
668
0
    if (!result)
669
0
        return NULL;
670
671
0
    for (i = 0; i < json_array_size(array); i++)
672
0
        json_array_append(result, json_array_get(array, i));
673
674
0
    return result;
675
0
}
676
677
static json_t *json_array_deep_copy(const json_t *array, hashtable_t *parents,
678
0
                                    int depth) {
679
0
    json_t *result;
680
0
    size_t i;
681
0
    char loop_key[LOOP_KEY_LEN];
682
0
    size_t loop_key_len;
683
684
0
    if (jsonp_loop_check(parents, array, loop_key, sizeof(loop_key), &loop_key_len))
685
0
        return NULL;
686
687
0
    result = json_array();
688
0
    if (!result)
689
0
        goto out;
690
691
0
    for (i = 0; i < json_array_size(array); i++) {
692
0
        if (json_array_append_new(
693
0
                result, do_deep_copy(json_array_get(array, i), parents, depth + 1))) {
694
0
            json_decref(result);
695
0
            result = NULL;
696
0
            break;
697
0
        }
698
0
    }
699
700
0
out:
701
0
    hashtable_del(parents, loop_key, loop_key_len);
702
703
0
    return result;
704
0
}
705
706
/*** string ***/
707
708
0
static json_t *string_create(const char *value, size_t len, int own) {
709
0
    char *v;
710
0
    json_string_t *string;
711
712
0
    if (!value)
713
0
        return NULL;
714
715
0
    if (own)
716
0
        v = (char *)value;
717
0
    else {
718
0
        v = jsonp_strndup(value, len);
719
0
        if (!v)
720
0
            return NULL;
721
0
    }
722
723
0
    string = jsonp_malloc(sizeof(json_string_t));
724
0
    if (!string) {
725
0
        jsonp_free(v);
726
0
        return NULL;
727
0
    }
728
0
    json_init(&string->json, JSON_STRING);
729
0
    string->value = v;
730
0
    string->length = len;
731
732
0
    return &string->json;
733
0
}
734
735
0
json_t *json_string_nocheck(const char *value) {
736
0
    if (!value)
737
0
        return NULL;
738
739
0
    return string_create(value, strlen(value), 0);
740
0
}
741
742
0
json_t *json_stringn_nocheck(const char *value, size_t len) {
743
0
    return string_create(value, len, 0);
744
0
}
745
746
/* this is private; "steal" is not a public API concept */
747
0
json_t *jsonp_stringn_nocheck_own(const char *value, size_t len) {
748
0
    return string_create(value, len, 1);
749
0
}
750
751
0
json_t *json_string(const char *value) {
752
0
    if (!value)
753
0
        return NULL;
754
755
0
    return json_stringn(value, strlen(value));
756
0
}
757
758
0
json_t *json_stringn(const char *value, size_t len) {
759
0
    if (!value || !utf8_check_string(value, len))
760
0
        return NULL;
761
762
0
    return json_stringn_nocheck(value, len);
763
0
}
764
765
0
const char *json_string_value(const json_t *json) {
766
0
    if (!json_is_string(json))
767
0
        return NULL;
768
769
0
    return json_to_string(json)->value;
770
0
}
771
772
0
size_t json_string_length(const json_t *json) {
773
0
    if (!json_is_string(json))
774
0
        return 0;
775
776
0
    return json_to_string(json)->length;
777
0
}
778
779
0
int json_string_set_nocheck(json_t *json, const char *value) {
780
0
    if (!value)
781
0
        return -1;
782
783
0
    return json_string_setn_nocheck(json, value, strlen(value));
784
0
}
785
786
0
int json_string_setn_nocheck(json_t *json, const char *value, size_t len) {
787
0
    char *dup;
788
0
    json_string_t *string;
789
790
0
    if (!json_is_string(json) || !value)
791
0
        return -1;
792
793
0
    dup = jsonp_strndup(value, len);
794
0
    if (!dup)
795
0
        return -1;
796
797
0
    string = json_to_string(json);
798
0
    jsonp_free(string->value);
799
0
    string->value = dup;
800
0
    string->length = len;
801
802
0
    return 0;
803
0
}
804
805
0
int json_string_set(json_t *json, const char *value) {
806
0
    if (!value)
807
0
        return -1;
808
809
0
    return json_string_setn(json, value, strlen(value));
810
0
}
811
812
0
int json_string_setn(json_t *json, const char *value, size_t len) {
813
0
    if (!value || !utf8_check_string(value, len))
814
0
        return -1;
815
816
0
    return json_string_setn_nocheck(json, value, len);
817
0
}
818
819
0
static void json_delete_string(json_string_t *string) {
820
0
    jsonp_free(string->value);
821
0
    jsonp_free(string);
822
0
}
823
824
0
static int json_string_equal(const json_t *string1, const json_t *string2) {
825
0
    json_string_t *s1, *s2;
826
827
0
    s1 = json_to_string(string1);
828
0
    s2 = json_to_string(string2);
829
0
    return s1->length == s2->length && !memcmp(s1->value, s2->value, s1->length);
830
0
}
831
832
0
static json_t *json_string_copy(const json_t *string) {
833
0
    json_string_t *s;
834
835
0
    s = json_to_string(string);
836
0
    return json_stringn_nocheck(s->value, s->length);
837
0
}
838
839
0
json_t *json_vsprintf(const char *fmt, va_list ap) {
840
0
    json_t *json = NULL;
841
0
    int length;
842
0
    char *buf;
843
0
    va_list aq;
844
0
    va_copy(aq, ap);
845
846
0
    length = vsnprintf(NULL, 0, fmt, ap);
847
0
    if (length < 0)
848
0
        goto out;
849
0
    if (length == 0) {
850
0
        json = json_string("");
851
0
        goto out;
852
0
    }
853
854
0
    buf = jsonp_malloc((size_t)length + 1);
855
0
    if (!buf)
856
0
        goto out;
857
858
0
    vsnprintf(buf, (size_t)length + 1, fmt, aq);
859
0
    if (!utf8_check_string(buf, length)) {
860
0
        jsonp_free(buf);
861
0
        goto out;
862
0
    }
863
864
0
    json = jsonp_stringn_nocheck_own(buf, length);
865
866
0
out:
867
0
    va_end(aq);
868
0
    return json;
869
0
}
870
871
0
json_t *json_sprintf(const char *fmt, ...) {
872
0
    json_t *result;
873
0
    va_list ap;
874
875
0
    va_start(ap, fmt);
876
0
    result = json_vsprintf(fmt, ap);
877
0
    va_end(ap);
878
879
0
    return result;
880
0
}
881
882
/*** integer ***/
883
884
0
json_t *json_integer(json_int_t value) {
885
0
    json_integer_t *integer = jsonp_malloc(sizeof(json_integer_t));
886
0
    if (!integer)
887
0
        return NULL;
888
0
    json_init(&integer->json, JSON_INTEGER);
889
890
0
    integer->value = value;
891
0
    return &integer->json;
892
0
}
893
894
0
json_int_t json_integer_value(const json_t *json) {
895
0
    if (!json_is_integer(json))
896
0
        return 0;
897
898
0
    return json_to_integer(json)->value;
899
0
}
900
901
0
int json_integer_set(json_t *json, json_int_t value) {
902
0
    if (!json_is_integer(json))
903
0
        return -1;
904
905
0
    json_to_integer(json)->value = value;
906
907
0
    return 0;
908
0
}
909
910
0
static void json_delete_integer(json_integer_t *integer) { jsonp_free(integer); }
911
912
0
static int json_integer_equal(const json_t *integer1, const json_t *integer2) {
913
0
    return json_integer_value(integer1) == json_integer_value(integer2);
914
0
}
915
916
0
static json_t *json_integer_copy(const json_t *integer) {
917
0
    return json_integer(json_integer_value(integer));
918
0
}
919
920
/*** real ***/
921
922
0
json_t *json_real(double value) {
923
0
    json_real_t *real;
924
925
0
    if (isnan(value) || isinf(value))
926
0
        return NULL;
927
928
0
    real = jsonp_malloc(sizeof(json_real_t));
929
0
    if (!real)
930
0
        return NULL;
931
0
    json_init(&real->json, JSON_REAL);
932
933
0
    real->value = value;
934
0
    return &real->json;
935
0
}
936
937
0
double json_real_value(const json_t *json) {
938
0
    if (!json_is_real(json))
939
0
        return 0;
940
941
0
    return json_to_real(json)->value;
942
0
}
943
944
0
int json_real_set(json_t *json, double value) {
945
0
    if (!json_is_real(json) || isnan(value) || isinf(value))
946
0
        return -1;
947
948
0
    json_to_real(json)->value = value;
949
950
0
    return 0;
951
0
}
952
953
0
static void json_delete_real(json_real_t *real) { jsonp_free(real); }
954
955
0
static int json_real_equal(const json_t *real1, const json_t *real2) {
956
0
    return json_real_value(real1) == json_real_value(real2);
957
0
}
958
959
0
static json_t *json_real_copy(const json_t *real) {
960
0
    return json_real(json_real_value(real));
961
0
}
962
963
/*** number ***/
964
965
0
double json_number_value(const json_t *json) {
966
0
    if (json_is_integer(json))
967
0
        return (double)json_integer_value(json);
968
0
    else if (json_is_real(json))
969
0
        return json_real_value(json);
970
0
    else
971
0
        return 0.0;
972
0
}
973
974
/*** simple values ***/
975
976
0
json_t *json_true(void) {
977
0
    static json_t the_true = {JSON_TRUE, (size_t)-1};
978
0
    return &the_true;
979
0
}
980
981
0
json_t *json_false(void) {
982
0
    static json_t the_false = {JSON_FALSE, (size_t)-1};
983
0
    return &the_false;
984
0
}
985
986
0
json_t *json_null(void) {
987
0
    static json_t the_null = {JSON_NULL, (size_t)-1};
988
0
    return &the_null;
989
0
}
990
991
/*** deletion ***/
992
993
0
void json_delete(json_t *json) {
994
0
    if (!json)
995
0
        return;
996
997
0
    switch (json_typeof(json)) {
998
0
        case JSON_OBJECT:
999
0
            json_delete_object(json_to_object(json));
1000
0
            break;
1001
0
        case JSON_ARRAY:
1002
0
            json_delete_array(json_to_array(json));
1003
0
            break;
1004
0
        case JSON_STRING:
1005
0
            json_delete_string(json_to_string(json));
1006
0
            break;
1007
0
        case JSON_INTEGER:
1008
0
            json_delete_integer(json_to_integer(json));
1009
0
            break;
1010
0
        case JSON_REAL:
1011
0
            json_delete_real(json_to_real(json));
1012
0
            break;
1013
0
        default:
1014
0
            return;
1015
0
    }
1016
1017
    /* json_delete is not called for true, false or null */
1018
0
}
1019
1020
/*** equality ***/
1021
1022
0
int json_equal(const json_t *json1, const json_t *json2) {
1023
0
    return do_equal(json1, json2, 0);
1024
0
}
1025
1026
0
static int do_equal(const json_t *json1, const json_t *json2, int depth) {
1027
0
    if (!json1 || !json2)
1028
0
        return 0;
1029
1030
0
    if (json_typeof(json1) != json_typeof(json2))
1031
0
        return 0;
1032
1033
    /* this covers true, false and null as they are singletons */
1034
0
    if (json1 == json2)
1035
0
        return 1;
1036
1037
0
    if (depth >= JSON_PARSER_MAX_DEPTH)
1038
0
        return 0;
1039
1040
0
    switch (json_typeof(json1)) {
1041
0
        case JSON_OBJECT:
1042
0
            return json_object_equal(json1, json2, depth);
1043
0
        case JSON_ARRAY:
1044
0
            return json_array_equal(json1, json2, depth);
1045
0
        case JSON_STRING:
1046
0
            return json_string_equal(json1, json2);
1047
0
        case JSON_INTEGER:
1048
0
            return json_integer_equal(json1, json2);
1049
0
        case JSON_REAL:
1050
0
            return json_real_equal(json1, json2);
1051
0
        default:
1052
0
            return 0;
1053
0
    }
1054
0
}
1055
1056
/*** copying ***/
1057
1058
0
json_t *json_copy(json_t *json) {
1059
0
    if (!json)
1060
0
        return NULL;
1061
1062
0
    switch (json_typeof(json)) {
1063
0
        case JSON_OBJECT:
1064
0
            return json_object_copy(json);
1065
0
        case JSON_ARRAY:
1066
0
            return json_array_copy(json);
1067
0
        case JSON_STRING:
1068
0
            return json_string_copy(json);
1069
0
        case JSON_INTEGER:
1070
0
            return json_integer_copy(json);
1071
0
        case JSON_REAL:
1072
0
            return json_real_copy(json);
1073
0
        case JSON_TRUE:
1074
0
        case JSON_FALSE:
1075
0
        case JSON_NULL:
1076
0
            return json;
1077
0
        default:
1078
0
            return NULL;
1079
0
    }
1080
0
}
1081
1082
0
json_t *json_deep_copy(const json_t *json) {
1083
0
    json_t *res;
1084
0
    hashtable_t parents_set;
1085
1086
0
    if (hashtable_init(&parents_set))
1087
0
        return NULL;
1088
0
    res = do_deep_copy(json, &parents_set, 0);
1089
0
    hashtable_close(&parents_set);
1090
1091
0
    return res;
1092
0
}
1093
1094
0
json_t *do_deep_copy(const json_t *json, hashtable_t *parents, int depth) {
1095
0
    if (!json)
1096
0
        return NULL;
1097
1098
0
    if (depth >= JSON_PARSER_MAX_DEPTH)
1099
0
        return NULL;
1100
1101
0
    switch (json_typeof(json)) {
1102
0
        case JSON_OBJECT:
1103
0
            return json_object_deep_copy(json, parents, depth);
1104
0
        case JSON_ARRAY:
1105
0
            return json_array_deep_copy(json, parents, depth);
1106
            /* for the rest of the types, deep copying doesn't differ from
1107
               shallow copying */
1108
0
        case JSON_STRING:
1109
0
            return json_string_copy(json);
1110
0
        case JSON_INTEGER:
1111
0
            return json_integer_copy(json);
1112
0
        case JSON_REAL:
1113
0
            return json_real_copy(json);
1114
0
        case JSON_TRUE:
1115
0
        case JSON_FALSE:
1116
0
        case JSON_NULL:
1117
0
            return (json_t *)json;
1118
0
        default:
1119
            return NULL;
1120
0
    }
1121
0
}