Coverage Report

Created: 2026-01-16 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libcbor/src/cbor/strings.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 "strings.h"
9
#include <string.h>
10
#include "internal/memory_utils.h"
11
#include "internal/unicode.h"
12
13
745k
cbor_item_t *cbor_new_definite_string(void) {
14
745k
  cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t));
15
745k
  _CBOR_NOTNULL(item);
16
745k
  *item = (cbor_item_t){
17
745k
      .refcount = 1,
18
745k
      .type = CBOR_TYPE_STRING,
19
745k
      .metadata = {.string_metadata = {_CBOR_METADATA_DEFINITE, 0}}};
20
745k
  return item;
21
745k
}
22
23
17.6k
cbor_item_t *cbor_new_indefinite_string(void) {
24
17.6k
  cbor_item_t *item = _cbor_malloc(sizeof(cbor_item_t));
25
17.6k
  _CBOR_NOTNULL(item);
26
17.6k
  *item = (cbor_item_t){
27
17.6k
      .refcount = 1,
28
17.6k
      .type = CBOR_TYPE_STRING,
29
17.6k
      .metadata = {.string_metadata = {.type = _CBOR_METADATA_INDEFINITE,
30
17.6k
                                       .length = 0}},
31
17.6k
      .data = _cbor_malloc(sizeof(struct cbor_indefinite_string_data))};
32
17.6k
  _CBOR_DEPENDENT_NOTNULL(item, item->data);
33
17.6k
  *((struct cbor_indefinite_string_data *)item->data) =
34
17.6k
      (struct cbor_indefinite_string_data){
35
17.6k
          .chunk_count = 0,
36
17.6k
          .chunk_capacity = 0,
37
17.6k
          .chunks = NULL,
38
17.6k
      };
39
17.6k
  return item;
40
17.6k
}
41
42
84.0k
cbor_item_t *cbor_build_string(const char *val) {
43
84.0k
  cbor_item_t *item = cbor_new_definite_string();
44
84.0k
  _CBOR_NOTNULL(item);
45
84.0k
  size_t len = strlen(val);
46
84.0k
  unsigned char *handle = _cbor_malloc(len);
47
84.0k
  _CBOR_DEPENDENT_NOTNULL(item, handle);
48
84.0k
  memcpy(handle, val, len);
49
84.0k
  cbor_string_set_handle(item, handle, len);
50
84.0k
  return item;
51
84.0k
}
52
53
0
cbor_item_t *cbor_build_stringn(const char *val, size_t length) {
54
0
  cbor_item_t *item = cbor_new_definite_string();
55
0
  _CBOR_NOTNULL(item);
56
0
  unsigned char *handle = _cbor_malloc(length);
57
0
  _CBOR_DEPENDENT_NOTNULL(item, handle);
58
0
  memcpy(handle, val, length);
59
0
  cbor_string_set_handle(item, handle, length);
60
0
  return item;
61
0
}
62
63
void cbor_string_set_handle(cbor_item_t *item,
64
                            cbor_mutable_data CBOR_RESTRICT_POINTER data,
65
745k
                            size_t length) {
66
745k
  CBOR_ASSERT(cbor_isa_string(item));
67
745k
  CBOR_ASSERT(cbor_string_is_definite(item));
68
745k
  item->data = data;
69
745k
  item->metadata.string_metadata.length = length;
70
745k
  struct _cbor_unicode_status unicode_status;
71
745k
  size_t codepoint_count =
72
745k
      _cbor_unicode_codepoint_count(data, length, &unicode_status);
73
745k
  CBOR_ASSERT(codepoint_count <= length);
74
745k
  if (unicode_status.status == _CBOR_UNICODE_OK) {
75
679k
    item->metadata.string_metadata.codepoint_count = codepoint_count;
76
679k
  } else {
77
66.3k
    item->metadata.string_metadata.codepoint_count = 0;
78
66.3k
  }
79
745k
}
80
81
17.6k
cbor_item_t **cbor_string_chunks_handle(const cbor_item_t *item) {
82
17.6k
  CBOR_ASSERT(cbor_isa_string(item));
83
17.6k
  CBOR_ASSERT(cbor_string_is_indefinite(item));
84
17.6k
  return ((struct cbor_indefinite_string_data *)item->data)->chunks;
85
17.6k
}
86
87
110k
size_t cbor_string_chunk_count(const cbor_item_t *item) {
88
110k
  CBOR_ASSERT(cbor_isa_string(item));
89
110k
  CBOR_ASSERT(cbor_string_is_indefinite(item));
90
110k
  return ((struct cbor_indefinite_string_data *)item->data)->chunk_count;
91
110k
}
92
93
93.3k
bool cbor_string_add_chunk(cbor_item_t *item, cbor_item_t *chunk) {
94
93.3k
  CBOR_ASSERT(cbor_isa_string(item));
95
93.3k
  CBOR_ASSERT(cbor_string_is_indefinite(item));
96
93.3k
  struct cbor_indefinite_string_data *data =
97
93.3k
      (struct cbor_indefinite_string_data *)item->data;
98
93.3k
  if (data->chunk_count == data->chunk_capacity) {
99
4.51k
    if (!_cbor_safe_to_multiply(CBOR_BUFFER_GROWTH, data->chunk_capacity)) {
100
0
      return false;
101
0
    }
102
103
4.51k
    size_t new_chunk_capacity =
104
4.51k
        data->chunk_capacity == 0 ? 1
105
4.51k
                                  : CBOR_BUFFER_GROWTH * (data->chunk_capacity);
106
4.51k
    cbor_item_t **new_chunks_data = _cbor_realloc_multiple(
107
4.51k
        data->chunks, sizeof(cbor_item_t *), new_chunk_capacity);
108
109
4.51k
    if (new_chunks_data == NULL) {
110
1
      return false;
111
1
    }
112
113
4.51k
    data->chunk_capacity = new_chunk_capacity;
114
4.51k
    data->chunks = new_chunks_data;
115
4.51k
  }
116
93.3k
  data->chunks[data->chunk_count++] = cbor_incref(chunk);
117
93.3k
  return true;
118
93.3k
}
119
120
378k
size_t cbor_string_length(const cbor_item_t *item) {
121
378k
  CBOR_ASSERT(cbor_isa_string(item));
122
378k
  return item->metadata.string_metadata.length;
123
378k
}
124
125
190k
unsigned char *cbor_string_handle(const cbor_item_t *item) {
126
190k
  CBOR_ASSERT(cbor_isa_string(item));
127
190k
  return item->data;
128
190k
}
129
130
0
size_t cbor_string_codepoint_count(const cbor_item_t *item) {
131
0
  CBOR_ASSERT(cbor_isa_string(item));
132
0
  return item->metadata.string_metadata.codepoint_count;
133
0
}
134
135
1.02M
bool cbor_string_is_definite(const cbor_item_t *item) {
136
1.02M
  CBOR_ASSERT(cbor_isa_string(item));
137
1.02M
  return item->metadata.string_metadata.type == _CBOR_METADATA_DEFINITE;
138
1.02M
}
139
140
94.9k
bool cbor_string_is_indefinite(const cbor_item_t *item) {
141
94.9k
  return !cbor_string_is_definite(item);
142
94.9k
}