Coverage Report

Created: 2026-03-11 07:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libcbor/src/cbor/common.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2014-2020 Pavel Kalvoda <me@pavelkalvoda.com>
3
 *
4
 * libcbor 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
#include "cbor/common.h"
9
#include "arrays.h"
10
#include "bytestrings.h"
11
#include "data.h"
12
#include "floats_ctrls.h"
13
#include "ints.h"
14
#include "maps.h"
15
#include "strings.h"
16
#include "tags.h"
17
18
#ifdef DEBUG
19
bool _cbor_enable_assert = true;
20
#endif
21
22
438k
bool cbor_isa_uint(const cbor_item_t *item) {
23
438k
  return item->type == CBOR_TYPE_UINT;
24
438k
}
25
26
1.48k
bool cbor_isa_negint(const cbor_item_t *item) {
27
1.48k
  return item->type == CBOR_TYPE_NEGINT;
28
1.48k
}
29
30
640k
bool cbor_isa_bytestring(const cbor_item_t *item) {
31
640k
  return item->type == CBOR_TYPE_BYTESTRING;
32
640k
}
33
34
448k
bool cbor_isa_string(const cbor_item_t *item) {
35
448k
  return item->type == CBOR_TYPE_STRING;
36
448k
}
37
38
294k
bool cbor_isa_array(const cbor_item_t *item) {
39
294k
  return item->type == CBOR_TYPE_ARRAY;
40
294k
}
41
42
2.50M
bool cbor_isa_map(const cbor_item_t *item) {
43
2.50M
  return item->type == CBOR_TYPE_MAP;
44
2.50M
}
45
46
0
bool cbor_isa_tag(const cbor_item_t *item) {
47
0
  return item->type == CBOR_TYPE_TAG;
48
0
}
49
50
0
bool cbor_isa_float_ctrl(const cbor_item_t *item) {
51
0
  return item->type == CBOR_TYPE_FLOAT_CTRL;
52
0
}
53
54
9.45M
cbor_type cbor_typeof(const cbor_item_t *item) { return item->type; }
55
56
1.12k
bool cbor_is_int(const cbor_item_t *item) {
57
1.12k
  return cbor_isa_uint(item) || cbor_isa_negint(item);
58
1.12k
}
59
60
0
bool cbor_is_bool(const cbor_item_t *item) {
61
0
  return cbor_isa_float_ctrl(item) &&
62
0
         (cbor_ctrl_value(item) == CBOR_CTRL_FALSE ||
63
0
          cbor_ctrl_value(item) == CBOR_CTRL_TRUE);
64
0
}
65
66
0
bool cbor_is_null(const cbor_item_t *item) {
67
0
  return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_NULL;
68
0
}
69
70
0
bool cbor_is_undef(const cbor_item_t *item) {
71
0
  return cbor_isa_float_ctrl(item) && cbor_ctrl_value(item) == CBOR_CTRL_UNDEF;
72
0
}
73
74
0
bool cbor_is_float(const cbor_item_t *item) {
75
0
  return cbor_isa_float_ctrl(item) && !cbor_float_ctrl_is_ctrl(item);
76
0
}
77
78
16.7M
cbor_item_t *cbor_incref(cbor_item_t *item) {
79
16.7M
  item->refcount++;
80
16.7M
  return item;
81
16.7M
}
82
83
31.3M
void cbor_decref(cbor_item_t **item_ref) {
84
31.3M
  cbor_item_t *item = *item_ref;
85
31.3M
  CBOR_ASSERT(item->refcount > 0);
86
31.3M
  if (--item->refcount == 0) {
87
14.6M
    switch (item->type) {
88
6.03M
      case CBOR_TYPE_UINT:
89
        /* Fallthrough */
90
7.00M
      case CBOR_TYPE_NEGINT:
91
        /* Combined allocation, freeing the item suffices */
92
7.00M
        { break; }
93
648k
      case CBOR_TYPE_BYTESTRING: {
94
648k
        if (cbor_bytestring_is_definite(item)) {
95
637k
          _cbor_free(item->data);
96
637k
        } else {
97
          /* We need to decref all chunks */
98
11.5k
          cbor_item_t **handle = cbor_bytestring_chunks_handle(item);
99
104k
          for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++)
100
92.6k
            cbor_decref(&handle[i]);
101
11.5k
          _cbor_free(
102
11.5k
              ((struct cbor_indefinite_string_data *)item->data)->chunks);
103
11.5k
          _cbor_free(item->data);
104
11.5k
        }
105
648k
        break;
106
6.03M
      }
107
491k
      case CBOR_TYPE_STRING: {
108
491k
        if (cbor_string_is_definite(item)) {
109
480k
          _cbor_free(item->data);
110
480k
        } else {
111
          /* We need to decref all chunks */
112
10.6k
          cbor_item_t **handle = cbor_string_chunks_handle(item);
113
22.3k
          for (size_t i = 0; i < cbor_string_chunk_count(item); i++)
114
11.7k
            cbor_decref(&handle[i]);
115
10.6k
          _cbor_free(
116
10.6k
              ((struct cbor_indefinite_string_data *)item->data)->chunks);
117
10.6k
          _cbor_free(item->data);
118
10.6k
        }
119
491k
        break;
120
6.03M
      }
121
555k
      case CBOR_TYPE_ARRAY: {
122
        /* Get all items and decref them */
123
555k
        cbor_item_t **handle = cbor_array_handle(item);
124
555k
        size_t size = cbor_array_size(item);
125
6.82M
        for (size_t i = 0; i < size; i++)
126
6.27M
          if (handle[i] != NULL) cbor_decref(&handle[i]);
127
555k
        _cbor_free(item->data);
128
555k
        break;
129
6.03M
      }
130
5.40M
      case CBOR_TYPE_MAP: {
131
5.40M
        struct cbor_pair *handle = cbor_map_handle(item);
132
9.11M
        for (size_t i = 0; i < item->metadata.map_metadata.end_ptr;
133
5.40M
             i++, handle++) {
134
3.70M
          cbor_decref(&handle->key);
135
3.70M
          if (handle->value != NULL) cbor_decref(&handle->value);
136
3.70M
        }
137
5.40M
        _cbor_free(item->data);
138
5.40M
        break;
139
6.03M
      }
140
413k
      case CBOR_TYPE_TAG: {
141
413k
        if (item->metadata.tag_metadata.tagged_item != NULL)
142
299k
          cbor_decref(&item->metadata.tag_metadata.tagged_item);
143
413k
        _cbor_free(item->data);
144
413k
        break;
145
6.03M
      }
146
104k
      case CBOR_TYPE_FLOAT_CTRL: {
147
        /* Floats have combined allocation */
148
104k
        break;
149
6.03M
      }
150
14.6M
    }
151
14.6M
    _cbor_free(item);
152
14.6M
    *item_ref = NULL;
153
14.6M
  }
154
31.3M
}
155
156
7.81M
void cbor_intermediate_decref(cbor_item_t *item) { cbor_decref(&item); }
157
158
0
size_t cbor_refcount(const cbor_item_t *item) { return item->refcount; }
159
160
0
cbor_item_t *cbor_move(cbor_item_t *item) {
161
0
  item->refcount--;
162
0
  return item;
163
0
}