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