|
7 | 7 | #include "azure_macro_utils/macro_utils.h" |
8 | 8 | #include "azure_c_shared_utility/gballoc.h" |
9 | 9 | #include "azure_c_shared_utility/xlogging.h" |
| 10 | +#include "azure_c_shared_utility/safe_math.h" |
10 | 11 | #include "azure_uamqp_c/amqp_definitions.h" |
11 | 12 | #include "azure_uamqp_c/message.h" |
12 | 13 | #include "azure_uamqp_c/amqpvalue.h" |
@@ -232,78 +233,100 @@ MESSAGE_HANDLE message_clone(MESSAGE_HANDLE source_message) |
232 | 233 |
|
233 | 234 | if ((result != NULL) && (source_message->body_amqp_data_count > 0)) |
234 | 235 | { |
235 | | - size_t i; |
| 236 | + size_t calloc_size = safe_multiply_size_t(source_message->body_amqp_data_count, sizeof(BODY_AMQP_DATA)); |
236 | 237 |
|
237 | | - result->body_amqp_data_items = (BODY_AMQP_DATA*)calloc(1, (source_message->body_amqp_data_count * sizeof(BODY_AMQP_DATA))); |
238 | | - if (result->body_amqp_data_items == NULL) |
| 238 | + if (calloc_size == SIZE_MAX) |
239 | 239 | { |
240 | | - /* Codes_SRS_MESSAGE_01_012: [ If any cloning operation for the members of the source message fails, then `message_clone` shall fail and return NULL. ]*/ |
241 | | - LogError("Cannot allocate memory for body data sections"); |
242 | | - message_destroy(result); |
| 240 | + LogError("Invalid size for body_amqp_data_items"); |
243 | 241 | result = NULL; |
244 | 242 | } |
245 | 243 | else |
246 | 244 | { |
247 | | - for (i = 0; i < source_message->body_amqp_data_count; i++) |
| 245 | + result->body_amqp_data_items = (BODY_AMQP_DATA*)calloc(1, calloc_size); |
| 246 | + |
| 247 | + if (result->body_amqp_data_items == NULL) |
248 | 248 | { |
249 | | - result->body_amqp_data_items[i].body_data_section_length = source_message->body_amqp_data_items[i].body_data_section_length; |
| 249 | + /* Codes_SRS_MESSAGE_01_012: [ If any cloning operation for the members of the source message fails, then `message_clone` shall fail and return NULL. ]*/ |
| 250 | + LogError("Cannot allocate memory for body data sections"); |
| 251 | + message_destroy(result); |
| 252 | + result = NULL; |
| 253 | + } |
| 254 | + else |
| 255 | + { |
| 256 | + size_t i; |
250 | 257 |
|
251 | | - /* Codes_SRS_MESSAGE_01_011: [If an AMQP data has been set as message body on the source message it shall be cloned by allocating memory for the binary payload.] */ |
252 | | - result->body_amqp_data_items[i].body_data_section_bytes = (unsigned char*)malloc(source_message->body_amqp_data_items[i].body_data_section_length); |
253 | | - if (result->body_amqp_data_items[i].body_data_section_bytes == NULL) |
| 258 | + for (i = 0; i < source_message->body_amqp_data_count; i++) |
254 | 259 | { |
255 | | - LogError("Cannot allocate memory for body data section %u", (unsigned int)i); |
256 | | - break; |
| 260 | + result->body_amqp_data_items[i].body_data_section_length = source_message->body_amqp_data_items[i].body_data_section_length; |
| 261 | + |
| 262 | + /* Codes_SRS_MESSAGE_01_011: [If an AMQP data has been set as message body on the source message it shall be cloned by allocating memory for the binary payload.] */ |
| 263 | + result->body_amqp_data_items[i].body_data_section_bytes = (unsigned char*)malloc(source_message->body_amqp_data_items[i].body_data_section_length); |
| 264 | + if (result->body_amqp_data_items[i].body_data_section_bytes == NULL) |
| 265 | + { |
| 266 | + LogError("Cannot allocate memory for body data section %u", (unsigned int)i); |
| 267 | + break; |
| 268 | + } |
| 269 | + else |
| 270 | + { |
| 271 | + (void)memcpy(result->body_amqp_data_items[i].body_data_section_bytes, source_message->body_amqp_data_items[i].body_data_section_bytes, result->body_amqp_data_items[i].body_data_section_length); |
| 272 | + } |
257 | 273 | } |
258 | | - else |
| 274 | + |
| 275 | + result->body_amqp_data_count = i; |
| 276 | + if (i < source_message->body_amqp_data_count) |
259 | 277 | { |
260 | | - (void)memcpy(result->body_amqp_data_items[i].body_data_section_bytes, source_message->body_amqp_data_items[i].body_data_section_bytes, result->body_amqp_data_items[i].body_data_section_length); |
| 278 | + /* Codes_SRS_MESSAGE_01_012: [ If any cloning operation for the members of the source message fails, then `message_clone` shall fail and return NULL. ]*/ |
| 279 | + message_destroy(result); |
| 280 | + result = NULL; |
261 | 281 | } |
262 | 282 | } |
263 | | - |
264 | | - result->body_amqp_data_count = i; |
265 | | - if (i < source_message->body_amqp_data_count) |
266 | | - { |
267 | | - /* Codes_SRS_MESSAGE_01_012: [ If any cloning operation for the members of the source message fails, then `message_clone` shall fail and return NULL. ]*/ |
268 | | - message_destroy(result); |
269 | | - result = NULL; |
270 | | - } |
271 | 283 | } |
272 | 284 | } |
273 | 285 |
|
274 | 286 | if ((result != NULL) && (source_message->body_amqp_sequence_count > 0)) |
275 | 287 | { |
276 | | - size_t i; |
| 288 | + size_t calloc_size = safe_multiply_size_t(source_message->body_amqp_sequence_count, sizeof(AMQP_VALUE)); |
277 | 289 |
|
278 | | - result->body_amqp_sequence_items = (AMQP_VALUE*)calloc(1, (source_message->body_amqp_sequence_count * sizeof(AMQP_VALUE))); |
279 | | - if (result->body_amqp_sequence_items == NULL) |
| 290 | + if (calloc_size == SIZE_MAX) |
280 | 291 | { |
281 | | - /* Codes_SRS_MESSAGE_01_012: [ If any cloning operation for the members of the source message fails, then `message_clone` shall fail and return NULL. ]*/ |
282 | | - LogError("Cannot allocate memory for body AMQP sequences"); |
| 292 | + LogError("Invalid size for body_amqp_sequence_items"); |
283 | 293 | message_destroy(result); |
284 | 294 | result = NULL; |
285 | 295 | } |
286 | 296 | else |
287 | 297 | { |
288 | | - for (i = 0; i < source_message->body_amqp_sequence_count; i++) |
289 | | - { |
290 | | - /* Codes_SRS_MESSAGE_01_160: [ If AMQP sequences are set as AMQP body they shall be cloned by calling `amqpvalue_clone`. ] */ |
291 | | - result->body_amqp_sequence_items[i] = amqpvalue_clone(source_message->body_amqp_sequence_items[i]); |
292 | | - if (result->body_amqp_sequence_items[i] == NULL) |
293 | | - { |
294 | | - LogError("Cannot clone AMQP sequence %u", (unsigned int)i); |
295 | | - break; |
296 | | - } |
297 | | - } |
298 | | - |
299 | | - result->body_amqp_sequence_count = i; |
300 | | - if (i < source_message->body_amqp_sequence_count) |
| 298 | + result->body_amqp_sequence_items = (AMQP_VALUE*)calloc(1, calloc_size); |
| 299 | + if (result->body_amqp_sequence_items == NULL) |
301 | 300 | { |
302 | 301 | /* Codes_SRS_MESSAGE_01_012: [ If any cloning operation for the members of the source message fails, then `message_clone` shall fail and return NULL. ]*/ |
| 302 | + LogError("Cannot allocate memory for body AMQP sequences"); |
303 | 303 | message_destroy(result); |
304 | 304 | result = NULL; |
305 | 305 | } |
306 | | - } |
| 306 | + else |
| 307 | + { |
| 308 | + size_t i; |
| 309 | + |
| 310 | + for (i = 0; i < source_message->body_amqp_sequence_count; i++) |
| 311 | + { |
| 312 | + /* Codes_SRS_MESSAGE_01_160: [ If AMQP sequences are set as AMQP body they shall be cloned by calling `amqpvalue_clone`. ] */ |
| 313 | + result->body_amqp_sequence_items[i] = amqpvalue_clone(source_message->body_amqp_sequence_items[i]); |
| 314 | + if (result->body_amqp_sequence_items[i] == NULL) |
| 315 | + { |
| 316 | + LogError("Cannot clone AMQP sequence %u", (unsigned int)i); |
| 317 | + break; |
| 318 | + } |
| 319 | + } |
| 320 | + |
| 321 | + result->body_amqp_sequence_count = i; |
| 322 | + if (i < source_message->body_amqp_sequence_count) |
| 323 | + { |
| 324 | + /* Codes_SRS_MESSAGE_01_012: [ If any cloning operation for the members of the source message fails, then `message_clone` shall fail and return NULL. ]*/ |
| 325 | + message_destroy(result); |
| 326 | + result = NULL; |
| 327 | + } |
| 328 | + } |
| 329 | + } |
307 | 330 | } |
308 | 331 |
|
309 | 332 | if ((result != NULL) && (source_message->body_amqp_value != NULL)) |
@@ -1017,45 +1040,56 @@ int message_add_body_amqp_data(MESSAGE_HANDLE message, BINARY_DATA amqp_data) |
1017 | 1040 | } |
1018 | 1041 | else |
1019 | 1042 | { |
1020 | | - /* Codes_SRS_MESSAGE_01_086: [ `message_add_body_amqp_data` shall add the contents of `amqp_data` to the list of AMQP data values for the body of the message identified by `message`. ]*/ |
1021 | | - BODY_AMQP_DATA* new_body_amqp_data_items = (BODY_AMQP_DATA*)realloc(message->body_amqp_data_items, sizeof(BODY_AMQP_DATA) * (message->body_amqp_data_count + 1)); |
1022 | | - if (new_body_amqp_data_items == NULL) |
| 1043 | + size_t realloc_size = safe_add_size_t(message->body_amqp_data_count, 1); |
| 1044 | + realloc_size = safe_multiply_size_t(sizeof(BODY_AMQP_DATA), realloc_size); |
| 1045 | + |
| 1046 | + if (realloc_size == SIZE_MAX) |
1023 | 1047 | { |
1024 | | - /* Codes_SRS_MESSAGE_01_153: [ If allocating memory to store the added AMQP data fails, `message_add_body_amqp_data` shall fail and return a non-zero value. ]*/ |
1025 | | - LogError("Cannot allocate memory for body AMQP data items"); |
| 1048 | + LogError("Invalid size for new_body_amqp_data_items"); |
1026 | 1049 | result = MU_FAILURE; |
1027 | 1050 | } |
1028 | 1051 | else |
1029 | 1052 | { |
1030 | | - message->body_amqp_data_items = new_body_amqp_data_items; |
1031 | | - |
1032 | | - if (amqp_data.length == 0) |
| 1053 | + /* Codes_SRS_MESSAGE_01_086: [ `message_add_body_amqp_data` shall add the contents of `amqp_data` to the list of AMQP data values for the body of the message identified by `message`. ]*/ |
| 1054 | + BODY_AMQP_DATA* new_body_amqp_data_items = (BODY_AMQP_DATA*)realloc(message->body_amqp_data_items, realloc_size); |
| 1055 | + if (new_body_amqp_data_items == NULL) |
1033 | 1056 | { |
1034 | | - message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_bytes = NULL; |
1035 | | - message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_length = 0; |
1036 | | - message->body_amqp_data_count++; |
1037 | | - |
1038 | | - /* Codes_SRS_MESSAGE_01_087: [ On success it shall return 0. ]*/ |
1039 | | - result = 0; |
| 1057 | + /* Codes_SRS_MESSAGE_01_153: [ If allocating memory to store the added AMQP data fails, `message_add_body_amqp_data` shall fail and return a non-zero value. ]*/ |
| 1058 | + LogError("Cannot allocate memory for body AMQP data items"); |
| 1059 | + result = MU_FAILURE; |
1040 | 1060 | } |
1041 | 1061 | else |
1042 | 1062 | { |
1043 | | - message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_bytes = (unsigned char*)malloc(amqp_data.length); |
1044 | | - if (message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_bytes == NULL) |
1045 | | - { |
1046 | | - /* Codes_SRS_MESSAGE_01_153: [ If allocating memory to store the added AMQP data fails, `message_add_body_amqp_data` shall fail and return a non-zero value. ]*/ |
1047 | | - LogError("Cannot allocate memory for body AMQP data to be added"); |
1048 | | - result = MU_FAILURE; |
1049 | | - } |
1050 | | - else |
| 1063 | + message->body_amqp_data_items = new_body_amqp_data_items; |
| 1064 | + |
| 1065 | + if (amqp_data.length == 0) |
1051 | 1066 | { |
1052 | | - message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_length = amqp_data.length; |
1053 | | - (void)memcpy(message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_bytes, amqp_data.bytes, amqp_data.length); |
| 1067 | + message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_bytes = NULL; |
| 1068 | + message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_length = 0; |
1054 | 1069 | message->body_amqp_data_count++; |
1055 | 1070 |
|
1056 | 1071 | /* Codes_SRS_MESSAGE_01_087: [ On success it shall return 0. ]*/ |
1057 | 1072 | result = 0; |
1058 | 1073 | } |
| 1074 | + else |
| 1075 | + { |
| 1076 | + message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_bytes = (unsigned char*)malloc(amqp_data.length); |
| 1077 | + if (message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_bytes == NULL) |
| 1078 | + { |
| 1079 | + /* Codes_SRS_MESSAGE_01_153: [ If allocating memory to store the added AMQP data fails, `message_add_body_amqp_data` shall fail and return a non-zero value. ]*/ |
| 1080 | + LogError("Cannot allocate memory for body AMQP data to be added"); |
| 1081 | + result = MU_FAILURE; |
| 1082 | + } |
| 1083 | + else |
| 1084 | + { |
| 1085 | + message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_length = amqp_data.length; |
| 1086 | + (void)memcpy(message->body_amqp_data_items[message->body_amqp_data_count].body_data_section_bytes, amqp_data.bytes, amqp_data.length); |
| 1087 | + message->body_amqp_data_count++; |
| 1088 | + |
| 1089 | + /* Codes_SRS_MESSAGE_01_087: [ On success it shall return 0. ]*/ |
| 1090 | + result = 0; |
| 1091 | + } |
| 1092 | + } |
1059 | 1093 | } |
1060 | 1094 | } |
1061 | 1095 | } |
@@ -1250,33 +1284,45 @@ int message_add_body_amqp_sequence(MESSAGE_HANDLE message, AMQP_VALUE sequence_l |
1250 | 1284 | } |
1251 | 1285 | else |
1252 | 1286 | { |
1253 | | - AMQP_VALUE* new_body_amqp_sequence_items = (AMQP_VALUE*)realloc(message->body_amqp_sequence_items, sizeof(AMQP_VALUE) * (message->body_amqp_sequence_count + 1)); |
1254 | | - if (new_body_amqp_sequence_items == NULL) |
| 1287 | + size_t realloc_size = safe_add_size_t(message->body_amqp_sequence_count, 1); |
| 1288 | + realloc_size = safe_multiply_size_t(sizeof(AMQP_VALUE), realloc_size); |
| 1289 | + |
| 1290 | + if (realloc_size == SIZE_MAX) |
1255 | 1291 | { |
1256 | | - /* Codes_SRS_MESSAGE_01_158: [ If allocating memory in order to store the sequence fails, `message_add_body_amqp_sequence` shall fail and return a non-zero value. ]*/ |
1257 | | - LogError("Cannot allocate enough memory for sequence items"); |
| 1292 | + LogError("Invalid size for new_body_amqp_sequence_items"); |
1258 | 1293 | result = MU_FAILURE; |
1259 | 1294 | } |
1260 | 1295 | else |
1261 | 1296 | { |
1262 | | - message->body_amqp_sequence_items = new_body_amqp_sequence_items; |
| 1297 | + AMQP_VALUE* new_body_amqp_sequence_items = (AMQP_VALUE*)realloc(message->body_amqp_sequence_items, realloc_size); |
1263 | 1298 |
|
1264 | | - /* Codes_SRS_MESSAGE_01_110: [ `message_add_body_amqp_sequence` shall add the contents of `sequence` to the list of AMQP sequences for the body of the message identified by `message`. ]*/ |
1265 | | - /* Codes_SRS_MESSAGE_01_156: [ The AMQP sequence shall be cloned by calling `amqpvalue_clone`. ]*/ |
1266 | | - message->body_amqp_sequence_items[message->body_amqp_sequence_count] = amqpvalue_clone(sequence_list); |
1267 | | - if (message->body_amqp_sequence_items[message->body_amqp_sequence_count] == NULL) |
| 1299 | + if (new_body_amqp_sequence_items == NULL) |
1268 | 1300 | { |
1269 | | - /* Codes_SRS_MESSAGE_01_157: [ If `amqpvalue_clone` fails, `message_add_body_amqp_sequence` shall fail and return a non-zero value. ]*/ |
1270 | | - LogError("Cloning sequence failed"); |
| 1301 | + /* Codes_SRS_MESSAGE_01_158: [ If allocating memory in order to store the sequence fails, `message_add_body_amqp_sequence` shall fail and return a non-zero value. ]*/ |
| 1302 | + LogError("Cannot allocate enough memory for sequence items"); |
1271 | 1303 | result = MU_FAILURE; |
1272 | 1304 | } |
1273 | 1305 | else |
1274 | 1306 | { |
1275 | | - /* Codes_SRS_MESSAGE_01_114: [ If adding the AMQP sequence fails, the previous value shall be preserved. ]*/ |
1276 | | - message->body_amqp_sequence_count++; |
| 1307 | + message->body_amqp_sequence_items = new_body_amqp_sequence_items; |
1277 | 1308 |
|
1278 | | - /* Codes_SRS_MESSAGE_01_111: [ On success it shall return 0. ]*/ |
1279 | | - result = 0; |
| 1309 | + /* Codes_SRS_MESSAGE_01_110: [ `message_add_body_amqp_sequence` shall add the contents of `sequence` to the list of AMQP sequences for the body of the message identified by `message`. ]*/ |
| 1310 | + /* Codes_SRS_MESSAGE_01_156: [ The AMQP sequence shall be cloned by calling `amqpvalue_clone`. ]*/ |
| 1311 | + message->body_amqp_sequence_items[message->body_amqp_sequence_count] = amqpvalue_clone(sequence_list); |
| 1312 | + if (message->body_amqp_sequence_items[message->body_amqp_sequence_count] == NULL) |
| 1313 | + { |
| 1314 | + /* Codes_SRS_MESSAGE_01_157: [ If `amqpvalue_clone` fails, `message_add_body_amqp_sequence` shall fail and return a non-zero value. ]*/ |
| 1315 | + LogError("Cloning sequence failed"); |
| 1316 | + result = MU_FAILURE; |
| 1317 | + } |
| 1318 | + else |
| 1319 | + { |
| 1320 | + /* Codes_SRS_MESSAGE_01_114: [ If adding the AMQP sequence fails, the previous value shall be preserved. ]*/ |
| 1321 | + message->body_amqp_sequence_count++; |
| 1322 | + |
| 1323 | + /* Codes_SRS_MESSAGE_01_111: [ On success it shall return 0. ]*/ |
| 1324 | + result = 0; |
| 1325 | + } |
1280 | 1326 | } |
1281 | 1327 | } |
1282 | 1328 | } |
|
0 commit comments