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