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