From d9a6b6f32465cca7b63ed11b00164b7a3c4a3957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Fri, 2 Jun 2017 10:55:45 +0300 Subject: [PATCH] Fix avrorouter memory leaks The loading of the JSON schemas leaked memory as functions that increment the reference count were used. --- server/modules/routing/avro/avro.c | 1 + server/modules/routing/avro/avro_index.c | 1 + server/modules/routing/avro/avro_schema.c | 35 ++++++++++++----------- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/server/modules/routing/avro/avro.c b/server/modules/routing/avro/avro.c index 34b092c3e..1cc024b03 100644 --- a/server/modules/routing/avro/avro.c +++ b/server/modules/routing/avro/avro.c @@ -338,6 +338,7 @@ createInstance(SERVICE *service, char **options) inst->gtid.seq = 0; inst->gtid.server_id = 0; inst->gtid.timestamp = 0; + memset(&inst->active_maps, 0, sizeof(inst->active_maps)); int first_file = 1; bool err = false; diff --git a/server/modules/routing/avro/avro_index.c b/server/modules/routing/avro/avro_index.c index 09d5bbb92..fd894b492 100644 --- a/server/modules/routing/avro/avro_index.c +++ b/server/modules/routing/avro/avro_index.c @@ -139,6 +139,7 @@ void avro_index_file(AVRO_INSTANCE *router, const char* filename) errmsg = NULL; prev_gtid = gtid; } + json_decref(row); } else { diff --git a/server/modules/routing/avro/avro_schema.c b/server/modules/routing/avro/avro_schema.c index 156bf94a9..ef956cfc6 100644 --- a/server/modules/routing/avro/avro_schema.c +++ b/server/modules/routing/avro/avro_schema.c @@ -104,16 +104,16 @@ char* json_new_schema_from_table(TABLE_MAP *map) json_object_set_new(schema, "name", json_string("ChangeRecord")); json_t *array = json_array(); - json_array_append(array, json_pack_ex(&err, 0, "{s:s, s:s}", "name", - avro_domain, "type", "int")); - json_array_append(array, json_pack_ex(&err, 0, "{s:s, s:s}", "name", - avro_server_id, "type", "int")); - json_array_append(array, json_pack_ex(&err, 0, "{s:s, s:s}", "name", - avro_sequence, "type", "int")); - json_array_append(array, json_pack_ex(&err, 0, "{s:s, s:s}", "name", - avro_event_number, "type", "int")); - json_array_append(array, json_pack_ex(&err, 0, "{s:s, s:s}", "name", - avro_timestamp, "type", "int")); + json_array_append_new(array, json_pack_ex(&err, 0, "{s:s, s:s}", "name", + avro_domain, "type", "int")); + json_array_append_new(array, json_pack_ex(&err, 0, "{s:s, s:s}", "name", + avro_server_id, "type", "int")); + json_array_append_new(array, json_pack_ex(&err, 0, "{s:s, s:s}", "name", + avro_sequence, "type", "int")); + json_array_append_new(array, json_pack_ex(&err, 0, "{s:s, s:s}", "name", + avro_event_number, "type", "int")); + json_array_append_new(array, json_pack_ex(&err, 0, "{s:s, s:s}", "name", + avro_timestamp, "type", "int")); /** Enums and other complex types are defined with complete JSON objects * instead of string values */ @@ -121,18 +121,19 @@ char* json_new_schema_from_table(TABLE_MAP *map) "name", "EVENT_TYPES", "symbols", "insert", "update_before", "update_after", "delete"); - json_array_append(array, json_pack_ex(&err, 0, "{s:s, s:o}", "name", avro_event_type, - "type", event_types)); + // Ownership of `event_types` is stolen when using the `o` format + json_array_append_new(array, json_pack_ex(&err, 0, "{s:s, s:o}", "name", avro_event_type, + "type", event_types)); for (uint64_t i = 0; i < map->columns; i++) { ss_info_dassert(create->column_names[i] && *create->column_names[i], "Column name should not be empty or NULL"); - json_array_append(array, json_pack_ex(&err, 0, "{s:s, s:s, s:s, s:i}", - "name", create->column_names[i], - "type", column_type_to_avro_type(map->column_types[i]), - "real_type", create->column_types[i], - "length", create->column_lengths[i])); + json_array_append_new(array, json_pack_ex(&err, 0, "{s:s, s:s, s:s, s:i}", + "name", create->column_names[i], + "type", column_type_to_avro_type(map->column_types[i]), + "real_type", create->column_types[i], + "length", create->column_lengths[i])); } json_object_set_new(schema, "fields", array); char* rval = json_dumps(schema, JSON_PRESERVE_ORDER);