|
1 | 1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
| 2 | + |
| 3 | +/* |
| 4 | + * AWS Client Mock Implementation |
| 5 | + * |
| 6 | + * NOTE: This .c file is directly included in test files (not compiled separately). |
| 7 | + * Each test is built as a standalone executable, avoiding symbol conflicts. |
| 8 | + * DO NOT compile multiple tests using this mock into a single executable |
| 9 | + * without refactoring to a test library or using static functions. |
| 10 | + */ |
| 11 | + |
2 | 12 | #include "aws_client_mock.h" |
3 | 13 |
|
4 | 14 | #include <fluent-bit/flb_aws_util.h> |
@@ -39,14 +49,30 @@ void flb_aws_client_mock_configure_generator( |
39 | 49 | /* |
40 | 50 | * Clean up generator's memory |
41 | 51 | * Cleanup should be called on exiting generator |
| 52 | + * Note: This is safe to call even if the mock was already freed by S3 plugin cleanup |
42 | 53 | */ |
43 | 54 | void flb_aws_client_mock_destroy_generator() |
44 | 55 | { |
45 | | - if (flb_aws_client_mock_instance != NULL) { |
46 | | - flb_aws_client_mock_destroy(flb_aws_client_mock_instance); |
| 56 | + struct flb_aws_client_mock *mock = flb_aws_client_mock_instance; |
| 57 | + |
| 58 | + /* Clear instance first to prevent double-free scenarios */ |
| 59 | + flb_aws_client_mock_instance = NULL; |
| 60 | + |
| 61 | + if (mock != NULL) { |
| 62 | + flb_aws_client_mock_destroy(mock); |
47 | 63 | } |
48 | 64 | } |
49 | 65 |
|
| 66 | +/* |
| 67 | + * Clear generator instance without freeing |
| 68 | + * Use this after flb_destroy() when the S3 plugin has already freed the mock client |
| 69 | + * This prevents use-after-free when configure_generator is called again |
| 70 | + */ |
| 71 | +void flb_aws_client_mock_clear_generator_instance() |
| 72 | +{ |
| 73 | + flb_aws_client_mock_instance = NULL; |
| 74 | +} |
| 75 | + |
50 | 76 | /* Create Mock of flb_aws_client */ |
51 | 77 | struct flb_aws_client_mock *flb_aws_client_mock_create( |
52 | 78 | struct flb_aws_client_mock_request_chain *request_chain) |
@@ -203,6 +229,7 @@ static struct flb_http_client *flb_aws_client_mock_vtable_request( |
203 | 229 | char *flb_http_methods[] = { |
204 | 230 | "FLB_HTTP_GET", "FLB_HTTP_POST", "FLB_HTTP_PUT", |
205 | 231 | "FLB_HTTP_HEAD", "FLB_HTTP_CONNECT", "FLB_HTTP_PATCH", |
| 232 | + "FLB_HTTP_DELETE", |
206 | 233 | }; |
207 | 234 |
|
208 | 235 | /* |
@@ -236,12 +263,49 @@ static struct flb_http_client *flb_aws_client_mock_vtable_request( |
236 | 263 | c = (struct flb_http_client *)val1; |
237 | 264 | } |
238 | 265 |
|
| 266 | + /* |
| 267 | + * Special handling for DATA field - must be dynamically allocated |
| 268 | + * because flb_http_client_destroy() will call flb_free(c->resp.data) |
| 269 | + */ |
| 270 | + else if (response_config->config_parameter == FLB_AWS_CLIENT_MOCK_SET_DATA) { |
| 271 | + if (val1 != NULL) { |
| 272 | + /* Get data size from response config or use strlen */ |
| 273 | + size_t data_len = 0; |
| 274 | + int j; |
| 275 | + for (j = 0; j < response->length; ++j) { |
| 276 | + if (response->config_parameters[j].config_parameter == |
| 277 | + FLB_AWS_CLIENT_MOCK_SET_DATA_SIZE) { |
| 278 | + data_len = (size_t)(uintptr_t)response->config_parameters[j].config_value; |
| 279 | + break; |
| 280 | + } |
| 281 | + if (response->config_parameters[j].config_parameter == |
| 282 | + FLB_AWS_CLIENT_MOCK_SET_DATA_LEN) { |
| 283 | + data_len = (size_t)(uintptr_t)response->config_parameters[j].config_value; |
| 284 | + break; |
| 285 | + } |
| 286 | + } |
| 287 | + if (data_len == 0) { |
| 288 | + data_len = strlen((char *)val1); |
| 289 | + } |
| 290 | + /* Allocate and copy data so flb_http_client_destroy can free it */ |
| 291 | + c->resp.data = flb_malloc(data_len + 1); |
| 292 | + if (c->resp.data) { |
| 293 | + memcpy(c->resp.data, val1, data_len); |
| 294 | + c->resp.data[data_len] = '\0'; |
| 295 | + c->resp.data_len = data_len; |
| 296 | + c->resp.data_size = data_len + 1; |
| 297 | + } |
| 298 | + } |
| 299 | + } |
| 300 | + |
239 | 301 | /* |
240 | 302 | * Response setters |
241 | 303 | * Set client fields using XMacro definitions |
| 304 | + * Note: DATA field is handled specially above |
242 | 305 | */ |
243 | 306 | #define EXPAND_CLIENT_RESPONSE_PARAMETER(lower, UPPER, type) \ |
244 | | - else if (response_config->config_parameter == FLB_AWS_CLIENT_MOCK_SET_##UPPER) \ |
| 307 | + else if (response_config->config_parameter == FLB_AWS_CLIENT_MOCK_SET_##UPPER \ |
| 308 | + && response_config->config_parameter != FLB_AWS_CLIENT_MOCK_SET_DATA) \ |
245 | 309 | { \ |
246 | 310 | c->resp.lower = CONVERT_##type((char *)val1); \ |
247 | 311 | } |
|
0 commit comments