Line data Source code
1 : #include "mem.h"
2 : #include <string.h>
3 :
4 27 : Return memory_concat_strings(
5 : memory *destination,
6 : const memory *source)
7 : {
8 27 : Return status = SUCCESS;
9 :
10 27 : if(destination == NULL || source == NULL)
11 : {
12 0 : slog(ERROR,"Memory management; concat_strings arguments must be non-NULL");
13 0 : provide(FAILURE);
14 : }
15 :
16 27 : if(destination->element_size != source->element_size)
17 : {
18 0 : slog(ERROR,
19 : "Memory management; Element size mismatch (%zu vs %zu)",
20 : destination->element_size,
21 : source->element_size);
22 0 : provide(FAILURE);
23 : }
24 :
25 27 : if(destination->element_size != sizeof(char))
26 : {
27 0 : slog(ERROR,"Memory management; concat_strings supports byte-sized elements only");
28 0 : provide(FAILURE);
29 : }
30 :
31 27 : size_t destination_length = 0;
32 27 : size_t source_length = 0;
33 :
34 27 : run(string_length(destination,&destination_length));
35 27 : run(string_length(source,&source_length));
36 :
37 27 : size_t new_total_elements = 0;
38 :
39 27 : if(SUCCESS == status)
40 : {
41 27 : if(destination_length > SIZE_MAX - source_length)
42 : {
43 0 : slog(ERROR,"Memory management; Concatenation would overflow element count");
44 0 : status = FAILURE;
45 : } else {
46 27 : const size_t sum = destination_length + source_length;
47 :
48 27 : if(sum == SIZE_MAX)
49 : {
50 0 : slog(ERROR,"Memory management; Not enough room for string terminator");
51 0 : status = FAILURE;
52 : } else {
53 27 : new_total_elements = sum + 1;
54 : }
55 : }
56 : }
57 :
58 27 : size_t offset_bytes = 0;
59 27 : size_t source_bytes = 0;
60 :
61 27 : run(memory_guarded_size(destination->element_size,destination_length,&offset_bytes));
62 27 : run(memory_guarded_size(source->element_size,source_length,&source_bytes));
63 27 : run(resize(destination,new_total_elements));
64 :
65 27 : if(SUCCESS == status)
66 : {
67 27 : unsigned char *destination_bytes = (unsigned char *)destination->data;
68 :
69 27 : if(destination_bytes == NULL)
70 : {
71 0 : slog(ERROR,"Memory management; Destination data pointer is NULL after resize");
72 0 : status = FAILURE;
73 : } else {
74 27 : if(source_bytes > 0)
75 : {
76 27 : const unsigned char *source_bytes_ptr = (const unsigned char *)source->data;
77 :
78 27 : if(source_bytes_ptr == NULL)
79 : {
80 0 : slog(ERROR,"Memory management; Source data pointer is NULL");
81 0 : status = FAILURE;
82 : } else {
83 27 : memmove(destination_bytes + offset_bytes,source_bytes_ptr,source_bytes);
84 : }
85 : }
86 :
87 27 : if(SUCCESS == status)
88 : {
89 27 : destination_bytes[offset_bytes + source_bytes] = '\0';
90 27 : telemetry_string_padding_event();
91 : }
92 : }
93 : }
94 :
95 27 : provide(status);
96 : }
|