Coverage Report

Created: 2025-12-14 06:56

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
879k
bool cbor_isa_uint(const cbor_item_t *item) {
23
879k
  return item->type == CBOR_TYPE_UINT;
24
879k
}
25
26
3.12k
bool cbor_isa_negint(const cbor_item_t *item) {
27
3.12k
  return item->type == CBOR_TYPE_NEGINT;
28
3.12k
}
29
30
581k
bool cbor_isa_bytestring(const cbor_item_t *item) {
31
581k
  return item->type == CBOR_TYPE_BYTESTRING;
32
581k
}
33
34
726k
bool cbor_isa_string(const cbor_item_t *item) {
35
726k
  return item->type == CBOR_TYPE_STRING;
36
726k
}
37
38
289k
bool cbor_isa_array(const cbor_item_t *item) {
39
289k
  return item->type == CBOR_TYPE_ARRAY;
40
289k
}
41
42
3.30M
bool cbor_isa_map(const cbor_item_t *item) {
43
3.30M
  return item->type == CBOR_TYPE_MAP;
44
3.30M
}
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
7.03M
cbor_type cbor_typeof(const cbor_item_t *item) { return item->type; }
55
56
2.67k
bool cbor_is_int(const cbor_item_t *item) {
57
2.67k
  return cbor_isa_uint(item) || cbor_isa_negint(item);
58
2.67k
}
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
18.8M
cbor_item_t *cbor_incref(cbor_item_t *item) {
79
18.8M
  item->refcount++;
80
18.8M
  return item;
81
18.8M
}
82
83
35.6M
void cbor_decref(cbor_item_t **item_ref) {
84
35.6M
  cbor_item_t *item = *item_ref;
85
35.6M
  CBOR_ASSERT(item->refcount > 0);
86
35.6M
  if (--item->refcount == 0) {
87
16.8M
    switch (item->type) {
88
7.20M
      case CBOR_TYPE_UINT:
89
        /* Fallthrough */
90
7.80M
      case CBOR_TYPE_NEGINT:
91
        /* Combined allocation, freeing the item suffices */
92
7.80M
        { break; }
93
575k
      case CBOR_TYPE_BYTESTRING: {
94
575k
        if (cbor_bytestring_is_definite(item)) {
95
563k
          _cbor_free(item->data);
96
563k
        } else {
97
          /* We need to decref all chunks */
98
12.3k
          cbor_item_t **handle = cbor_bytestring_chunks_handle(item);
99
61.1k
          for (size_t i = 0; i < cbor_bytestring_chunk_count(item); i++)
100
48.8k
            cbor_decref(&handle[i]);
101
12.3k
          _cbor_free(
102
12.3k
              ((struct cbor_indefinite_string_data *)item->data)->chunks);
103
12.3k
          _cbor_free(item->data);
104
12.3k
        }
105
575k
        break;
106
7.20M
      }
107
742k
      case CBOR_TYPE_STRING: {
108
742k
        if (cbor_string_is_definite(item)) {
109
729k
          _cbor_free(item->data);
110
729k
        } else {
111
          /* We need to decref all chunks */
112
13.4k
          cbor_item_t **handle = cbor_string_chunks_handle(item);
113
94.9k
          for (size_t i = 0; i < cbor_string_chunk_count(item); i++)
114
81.5k
            cbor_decref(&handle[i]);
115
13.4k
          _cbor_free(
116
13.4k
              ((struct cbor_indefinite_string_data *)item->data)->chunks);
117
13.4k
          _cbor_free(item->data);
118
13.4k
        }
119
742k
        break;
120
7.20M
      }
121
795k
      case CBOR_TYPE_ARRAY: {
122
        /* Get all items and decref them */
123
795k
        cbor_item_t **handle = cbor_array_handle(item);
124
795k
        size_t size = cbor_array_size(item);
125
7.81M
        for (size_t i = 0; i < size; i++)
126
7.02M
          if (handle[i] != NULL) cbor_decref(&handle[i]);
127
795k
        _cbor_free(item->data);
128
795k
        break;
129
7.20M
      }
130
5.91M
      case CBOR_TYPE_MAP: {
131
5.91M
        struct cbor_pair *handle = cbor_map_handle(item);
132
9.91M
        for (size_t i = 0; i < item->metadata.map_metadata.end_ptr;
133
5.91M
             i++, handle++) {
134
3.99M
          cbor_decref(&handle->key);
135
3.99M
          if (handle->value != NULL) cbor_decref(&handle->value);
136
3.99M
        }
137
5.91M
        _cbor_free(item->data);
138
5.91M
        break;
139
7.20M
      }
140
755k
      case CBOR_TYPE_TAG: {
141
755k
        if (item->metadata.tag_metadata.tagged_item != NULL)
142
324k
          cbor_decref(&item->metadata.tag_metadata.tagged_item);
143
755k
        _cbor_free(item->data);
144
755k
        break;
145
7.20M
      }
146
233k
      case CBOR_TYPE_FLOAT_CTRL: {
147
        /* Floats have combined allocation */
148
233k
        break;
149
7.20M
      }
150
16.8M
    }
151
16.8M
    _cbor_free(item);
152
16.8M
    *item_ref = NULL;
153
16.8M
  }
154
35.6M
}
155
156
7.41M
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
}