Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 49 additions & 3 deletions plugins/out_stackdriver/stackdriver_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
*/


#include <errno.h>

#include "stackdriver.h"

int equal_obj_str(msgpack_object obj, const char *str, const int size) {
Expand All @@ -37,8 +39,13 @@ int validate_key(msgpack_object obj, const char *str, const int size) {

void try_assign_subfield_str(msgpack_object obj, flb_sds_t *subfield) {
if (obj.type == MSGPACK_OBJECT_STR) {
*subfield = flb_sds_copy(*subfield, obj.via.str.ptr,
obj.via.str.size);
if (!*subfield) {
*subfield = flb_sds_create_len(obj.via.str.ptr, obj.via.str.size);
}
else {
*subfield = flb_sds_copy(*subfield, obj.via.str.ptr,
obj.via.str.size);
}
}
}

Expand All @@ -55,9 +62,48 @@ void try_assign_subfield_bool(msgpack_object obj, int *subfield) {

void try_assign_subfield_int(msgpack_object obj, int64_t *subfield) {
if (obj.type == MSGPACK_OBJECT_STR) {
*subfield = atoll(obj.via.str.ptr);
char buf[32];
char *end;
long long val;
size_t len = obj.via.str.size;

/*
* Reject empty or oversized strings: no valid int64 has more than 20
* characters (19 digits plus an optional sign), so anything that does
* not fit the buffer cannot be a complete integer.
*/
if (len == 0 || len > sizeof(buf) - 1) {
return;
}

memcpy(buf, obj.via.str.ptr, len);
buf[len] = '\0';

errno = 0;
val = strtoll(buf, &end, 10);

/*
* Only assign when the whole string parsed as a single complete
* integer (no leftover characters) and the value did not overflow;
* otherwise leave the field at its previous value.
*/
if (errno == 0 && end != buf && *end == '\0') {
*subfield = val;
}
}
else if (obj.type == MSGPACK_OBJECT_POSITIVE_INTEGER) {
*subfield = obj.via.i64;
}
}

void pack_sds_safe(msgpack_packer *mp_pck, flb_sds_t s) {
if (s) {
msgpack_pack_str(mp_pck, flb_sds_len(s));
msgpack_pack_str_body(mp_pck, s, flb_sds_len(s));
}
else {
msgpack_pack_str(mp_pck, 0);
msgpack_pack_str_body(mp_pck, "", 0);
}
}

2 changes: 2 additions & 0 deletions plugins/out_stackdriver/stackdriver_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,6 @@ void try_assign_subfield_bool(msgpack_object obj, int *subfield);
*/
void try_assign_subfield_int(msgpack_object obj, int64_t *subfield);

void pack_sds_safe(msgpack_packer *mp_pck, flb_sds_t s);

#endif
57 changes: 23 additions & 34 deletions plugins/out_stackdriver/stackdriver_http_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ typedef enum {

void init_http_request(struct http_request_field *http_request)
{
http_request->latency = flb_sds_create("");
http_request->protocol = flb_sds_create("");
http_request->referer = flb_sds_create("");
http_request->remoteIp = flb_sds_create("");
http_request->requestMethod = flb_sds_create("");
http_request->requestUrl = flb_sds_create("");
http_request->serverIp = flb_sds_create("");
http_request->userAgent = flb_sds_create("");
http_request->latency = NULL;
http_request->protocol = NULL;
http_request->referer = NULL;
http_request->remoteIp = NULL;
http_request->requestMethod = NULL;
http_request->requestUrl = NULL;
http_request->serverIp = NULL;
http_request->userAgent = NULL;

http_request->cacheFillBytes = 0;
http_request->requestSize = 0;
Expand Down Expand Up @@ -67,7 +67,7 @@ void add_http_request_field(struct http_request_field *http_request,
msgpack_pack_str(mp_pck, 11);
msgpack_pack_str_body(mp_pck, "httpRequest", 11);

if (flb_sds_is_empty(http_request->latency) == FLB_TRUE) {
if (!http_request->latency || flb_sds_is_empty(http_request->latency) == FLB_TRUE) {
msgpack_pack_map(mp_pck, 14);
}
else {
Expand All @@ -76,60 +76,44 @@ void add_http_request_field(struct http_request_field *http_request,
msgpack_pack_str(mp_pck, HTTP_REQUEST_LATENCY_SIZE);
msgpack_pack_str_body(mp_pck, HTTP_REQUEST_LATENCY,
HTTP_REQUEST_LATENCY_SIZE);
msgpack_pack_str(mp_pck, flb_sds_len(http_request->latency));
msgpack_pack_str_body(mp_pck, http_request->latency,
flb_sds_len(http_request->latency));
pack_sds_safe(mp_pck, http_request->latency);
}

/* String sub-fields */
msgpack_pack_str(mp_pck, HTTP_REQUEST_REQUEST_METHOD_SIZE);
msgpack_pack_str_body(mp_pck, HTTP_REQUEST_REQUEST_METHOD,
HTTP_REQUEST_REQUEST_METHOD_SIZE);
msgpack_pack_str(mp_pck, flb_sds_len(http_request->requestMethod));
msgpack_pack_str_body(mp_pck, http_request->requestMethod,
flb_sds_len(http_request->requestMethod));
pack_sds_safe(mp_pck, http_request->requestMethod);

msgpack_pack_str(mp_pck, HTTP_REQUEST_REQUEST_URL_SIZE);
msgpack_pack_str_body(mp_pck, HTTP_REQUEST_REQUEST_URL,
HTTP_REQUEST_REQUEST_URL_SIZE);
msgpack_pack_str(mp_pck, flb_sds_len(http_request->requestUrl));
msgpack_pack_str_body(mp_pck, http_request->requestUrl,
flb_sds_len(http_request->requestUrl));
pack_sds_safe(mp_pck, http_request->requestUrl);

msgpack_pack_str(mp_pck, HTTP_REQUEST_USER_AGENT_SIZE);
msgpack_pack_str_body(mp_pck, HTTP_REQUEST_USER_AGENT,
HTTP_REQUEST_USER_AGENT_SIZE);
msgpack_pack_str(mp_pck, flb_sds_len(http_request->userAgent));
msgpack_pack_str_body(mp_pck, http_request->userAgent,
flb_sds_len(http_request->userAgent));
pack_sds_safe(mp_pck, http_request->userAgent);

msgpack_pack_str(mp_pck, HTTP_REQUEST_REMOTE_IP_SIZE);
msgpack_pack_str_body(mp_pck, HTTP_REQUEST_REMOTE_IP,
HTTP_REQUEST_REMOTE_IP_SIZE);
msgpack_pack_str(mp_pck, flb_sds_len(http_request->remoteIp));
msgpack_pack_str_body(mp_pck, http_request->remoteIp,
flb_sds_len(http_request->remoteIp));
pack_sds_safe(mp_pck, http_request->remoteIp);

msgpack_pack_str(mp_pck, HTTP_REQUEST_SERVER_IP_SIZE);
msgpack_pack_str_body(mp_pck, HTTP_REQUEST_SERVER_IP,
HTTP_REQUEST_SERVER_IP_SIZE);
msgpack_pack_str(mp_pck, flb_sds_len(http_request->serverIp));
msgpack_pack_str_body(mp_pck, http_request->serverIp,
flb_sds_len(http_request->serverIp));
pack_sds_safe(mp_pck, http_request->serverIp);

msgpack_pack_str(mp_pck, HTTP_REQUEST_REFERER_SIZE);
msgpack_pack_str_body(mp_pck, HTTP_REQUEST_REFERER,
HTTP_REQUEST_REFERER_SIZE);
msgpack_pack_str(mp_pck, flb_sds_len(http_request->referer));
msgpack_pack_str_body(mp_pck, http_request->referer,
flb_sds_len(http_request->referer));
pack_sds_safe(mp_pck, http_request->referer);

msgpack_pack_str(mp_pck, HTTP_REQUEST_PROTOCOL_SIZE);
msgpack_pack_str_body(mp_pck, HTTP_REQUEST_PROTOCOL,
HTTP_REQUEST_PROTOCOL_SIZE);
msgpack_pack_str(mp_pck, flb_sds_len(http_request->protocol));
msgpack_pack_str_body(mp_pck, http_request->protocol,
flb_sds_len(http_request->protocol));
pack_sds_safe(mp_pck, http_request->protocol);

/* Integer sub-fields */
msgpack_pack_str(mp_pck, HTTP_REQUEST_REQUESTSIZE_SIZE);
Expand Down Expand Up @@ -224,7 +208,12 @@ static void validate_latency(msgpack_object_str latency_in_payload,
++ j;
}
}
http_request->latency = flb_sds_copy(http_request->latency, extract_latency, j);
if (!http_request->latency) {
http_request->latency = flb_sds_create_len(extract_latency, j);
}
else {
http_request->latency = flb_sds_copy(http_request->latency, extract_latency, j);
}
}
}

Expand Down
7 changes: 2 additions & 5 deletions plugins/out_stackdriver/stackdriver_operation.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,11 @@ void add_operation_field(flb_sds_t *operation_id, flb_sds_t *operation_producer,

msgpack_pack_str(mp_pck, OPERATION_ID_SIZE);
msgpack_pack_str_body(mp_pck, OPERATION_ID, OPERATION_ID_SIZE);
msgpack_pack_str(mp_pck, flb_sds_len(*operation_id));
msgpack_pack_str_body(mp_pck, *operation_id, flb_sds_len(*operation_id));
pack_sds_safe(mp_pck, *operation_id);

msgpack_pack_str(mp_pck, OPERATION_PRODUCER_SIZE);
msgpack_pack_str_body(mp_pck, OPERATION_PRODUCER, OPERATION_PRODUCER_SIZE);
msgpack_pack_str(mp_pck, flb_sds_len(*operation_producer));
msgpack_pack_str_body(mp_pck, *operation_producer,
flb_sds_len(*operation_producer));
pack_sds_safe(mp_pck, *operation_producer);

msgpack_pack_str(mp_pck, OPERATION_FIRST_SIZE);
msgpack_pack_str_body(mp_pck, OPERATION_FIRST, OPERATION_FIRST_SIZE);
Expand Down
8 changes: 2 additions & 6 deletions plugins/out_stackdriver/stackdriver_source_location.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ void add_source_location_field(flb_sds_t *source_location_file,

msgpack_pack_str(mp_pck, SOURCE_LOCATION_FILE_SIZE);
msgpack_pack_str_body(mp_pck, SOURCE_LOCATION_FILE, SOURCE_LOCATION_FILE_SIZE);
msgpack_pack_str(mp_pck, flb_sds_len(*source_location_file));
msgpack_pack_str_body(mp_pck, *source_location_file,
flb_sds_len(*source_location_file));
pack_sds_safe(mp_pck, *source_location_file);

msgpack_pack_str(mp_pck, SOURCE_LOCATION_LINE_SIZE);
msgpack_pack_str_body(mp_pck, SOURCE_LOCATION_LINE, SOURCE_LOCATION_LINE_SIZE);
Expand All @@ -48,9 +46,7 @@ void add_source_location_field(flb_sds_t *source_location_file,
msgpack_pack_str(mp_pck, SOURCE_LOCATION_FUNCTION_SIZE);
msgpack_pack_str_body(mp_pck, SOURCE_LOCATION_FUNCTION,
SOURCE_LOCATION_FUNCTION_SIZE);
msgpack_pack_str(mp_pck, flb_sds_len(*source_location_function));
msgpack_pack_str_body(mp_pck, *source_location_function,
flb_sds_len(*source_location_function));
pack_sds_safe(mp_pck, *source_location_function);
}

/* Return FLB_TRUE if sourceLocation extracted */
Expand Down
11 changes: 11 additions & 0 deletions tests/runtime/data/stackdriver/stackdriver_test_source_location.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@
"}" \
"}]"

#define SOURCELOCATION_COMMON_CASE_LINE_INVALID_STRING "[" \
"1591111124," \
"{" \
"\"logging.googleapis.com/sourceLocation\": " \
"{" \
"\"file\": \"test_file\"," \
"\"line\": \"123abc\"," \
"\"function\": \"test_function\"" \
"}" \
"}]"

#define EMPTY_SOURCELOCATION "[" \
"1591111124," \
"{" \
Expand Down
65 changes: 65 additions & 0 deletions tests/runtime/out_stackdriver.c
Original file line number Diff line number Diff line change
Expand Up @@ -1706,6 +1706,30 @@ static void cb_check_source_location_common_case_line_in_string(void *ctx, int f
flb_sds_destroy(res_data);
}

static void cb_check_source_location_line_invalid_string(void *ctx, int ffd,
int res_ret, void *res_data, size_t res_size,
void *data)
{
int ret;

/* sourceLocation_file */
ret = mp_kv_cmp(res_data, res_size, "$entries[0]['sourceLocation']['file']", "test_file");
TEST_CHECK(ret == FLB_TRUE);

/*
* line is "123abc": a malformed integer string must be rejected and leave
* the field at its default (0) rather than being partially parsed to 123
*/
ret = mp_kv_cmp_integer(res_data, res_size, "$entries[0]['sourceLocation']['line']", 0);
TEST_CHECK(ret == FLB_TRUE);

/* sourceLocation_function */
ret = mp_kv_cmp(res_data, res_size, "$entries[0]['sourceLocation']['function']", "test_function");
TEST_CHECK(ret == FLB_TRUE);

flb_sds_destroy(res_data);
}

static void cb_check_empty_source_location(void *ctx, int ffd,
int res_ret, void *res_data, size_t res_size,
void *data)
Expand Down Expand Up @@ -5493,6 +5517,46 @@ void flb_test_source_location_line_in_string()
flb_destroy(ctx);
}

void flb_test_source_location_line_invalid_string()
{
int ret;
int size = sizeof(SOURCELOCATION_COMMON_CASE_LINE_INVALID_STRING) - 1;
flb_ctx_t *ctx;
int in_ffd;
int out_ffd;

/* Create context, flush every second (some checks omitted here) */
ctx = flb_create();
flb_service_set(ctx, "flush", "1", "grace", "1", NULL);

/* Lib input mode */
in_ffd = flb_input(ctx, (char *) "lib", NULL);
flb_input_set(ctx, in_ffd, "tag", "test", NULL);

/* Stackdriver output */
out_ffd = flb_output(ctx, (char *) "stackdriver", NULL);
flb_output_set(ctx, out_ffd,
"match", "test",
"resource", "gce_instance",
NULL);

/* Enable test mode */
ret = flb_output_set_test(ctx, out_ffd, "formatter",
cb_check_source_location_line_invalid_string,
NULL, NULL);

/* Start */
ret = flb_start(ctx);
TEST_CHECK(ret == 0);

/* Ingest data sample */
flb_lib_push(ctx, in_ffd, (char *) SOURCELOCATION_COMMON_CASE_LINE_INVALID_STRING, size);

sleep(2);
flb_stop(ctx);
flb_destroy(ctx);
}

void flb_test_empty_source_location()
{
int ret;
Expand Down Expand Up @@ -6588,6 +6652,7 @@ TEST_LIST = {
/* test sourceLocation */
{"sourceLocation_common_case", flb_test_source_location_common_case},
{"sourceLocation_line_in_string", flb_test_source_location_line_in_string},
{"sourceLocation_line_invalid_string", flb_test_source_location_line_invalid_string},
{"empty_sourceLocation", flb_test_empty_source_location},
{"sourceLocation_not_a_map", flb_test_source_location_in_string},
{"sourceLocation_partial_subfields", flb_test_source_location_partial_subfields},
Expand Down
Loading