Skip to content

Commit fc16b24

Browse files
committed
Fix possible memory and file descriptors leaks
1 parent 571c198 commit fc16b24

File tree

5 files changed

+134
-119
lines changed

5 files changed

+134
-119
lines changed

src/backend/utils/adt/age_global_graph.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,12 +1237,10 @@ Datum age_delete_global_graphs(PG_FUNCTION_ARGS)
12371237
{
12381238
char *graph_name = NULL;
12391239

1240-
graph_name = strndup(agtv_temp->val.string.val,
1241-
agtv_temp->val.string.len);
1240+
graph_name = pnstrdup(agtv_temp->val.string.val,
1241+
agtv_temp->val.string.len);
12421242

12431243
success = delete_specific_GRAPH_global_contexts(graph_name);
1244-
1245-
free(graph_name);
12461244
}
12471245
else
12481246
{

src/backend/utils/adt/agtype.c

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,14 @@ static agtype_value *agtype_build_map_as_agtype_value(FunctionCallInfo fcinfo);
181181
agtype_value *agtype_composite_to_agtype_value_binary(agtype *a);
182182
static agtype_value *tostring_helper(Datum arg, Oid type, char *msghdr);
183183

184+
185+
void *repalloc_check(void *ptr, size_t len)
186+
{
187+
if (ptr)
188+
return repalloc(ptr, len);
189+
return palloc(len);
190+
}
191+
184192
/*
185193
* Due to how pfree can be implemented, it may not check for a passed NULL. This
186194
* wrapper does just that, it will only call pfree is the pointer passed is not
@@ -5580,7 +5588,7 @@ static char *get_label_name(const char *graph_name, graphid element_graphid)
55805588
result = NameStr(*DatumGetName(heap_getattr(tuple, Anum_ag_label_name,
55815589
tupdesc, &column_is_null)));
55825590
/* duplicate it */
5583-
result = strdup(result);
5591+
result = pstrdup(result);
55845592

55855593
/* end the scan and close the relation */
55865594
systable_endscan(scan_desc);
@@ -5673,8 +5681,8 @@ Datum age_startnode(PG_FUNCTION_ARGS)
56735681
Assert(AGT_ROOT_IS_SCALAR(agt_arg));
56745682
agtv_object = get_ith_agtype_value_from_container(&agt_arg->root, 0);
56755683
Assert(agtv_object->type == AGTV_STRING);
5676-
graph_name = strndup(agtv_object->val.string.val,
5677-
agtv_object->val.string.len);
5684+
graph_name = pnstrdup(agtv_object->val.string.val,
5685+
agtv_object->val.string.len);
56785686

56795687
/* get the edge */
56805688
agt_arg = AG_GET_ARG_AGTYPE_P(1);
@@ -5708,8 +5716,6 @@ Datum age_startnode(PG_FUNCTION_ARGS)
57085716

57095717
result = get_vertex(graph_name, label_name, start_id);
57105718

5711-
free(label_name);
5712-
57135719
return result;
57145720
}
57155721

@@ -5738,8 +5744,8 @@ Datum age_endnode(PG_FUNCTION_ARGS)
57385744
Assert(AGT_ROOT_IS_SCALAR(agt_arg));
57395745
agtv_object = get_ith_agtype_value_from_container(&agt_arg->root, 0);
57405746
Assert(agtv_object->type == AGTV_STRING);
5741-
graph_name = strndup(agtv_object->val.string.val,
5742-
agtv_object->val.string.len);
5747+
graph_name = pnstrdup(agtv_object->val.string.val,
5748+
agtv_object->val.string.len);
57435749

57445750
/* get the edge */
57455751
agt_arg = AG_GET_ARG_AGTYPE_P(1);
@@ -5773,8 +5779,6 @@ Datum age_endnode(PG_FUNCTION_ARGS)
57735779

57745780
result = get_vertex(graph_name, label_name, end_id);
57755781

5776-
free(label_name);
5777-
57785782
return result;
57795783
}
57805784

@@ -6401,11 +6405,10 @@ Datum age_tofloat(PG_FUNCTION_ARGS)
64016405
NumericGetDatum(agtv_value->val.numeric)));
64026406
else if (agtv_value->type == AGTV_STRING)
64036407
{
6404-
string = strndup(agtv_value->val.string.val,
6405-
agtv_value->val.string.len);
6408+
string = pnstrdup(agtv_value->val.string.val,
6409+
agtv_value->val.string.len);
64066410
result = float8in_internal_null(string, NULL, "double precision",
64076411
string, &is_valid);
6408-
free(string);
64096412
if (!is_valid)
64106413
PG_RETURN_NULL();
64116414
}
@@ -6703,8 +6706,8 @@ Datum age_tointeger(PG_FUNCTION_ARGS)
67036706
{
67046707
char *endptr;
67056708
/* we need a null terminated cstring */
6706-
string = strndup(agtv_value->val.string.val,
6707-
agtv_value->val.string.len);
6709+
string = pnstrdup(agtv_value->val.string.val,
6710+
agtv_value->val.string.len);
67086711
/* convert it if it is a regular integer string */
67096712
result = strtoi64(string, &endptr, 10);
67106713

@@ -6718,7 +6721,6 @@ Datum age_tointeger(PG_FUNCTION_ARGS)
67186721

67196722
f = float8in_internal_null(string, NULL, "double precision",
67206723
string, &is_valid);
6721-
free(string);
67226724
/*
67236725
* If the conversions failed or it's a special float value,
67246726
* return null.
@@ -6731,10 +6733,6 @@ Datum age_tointeger(PG_FUNCTION_ARGS)
67316733

67326734
result = (int64) f;
67336735
}
6734-
else
6735-
{
6736-
free(string);
6737-
}
67386736
}
67396737
else
67406738
{

src/backend/utils/load/ag_load_edges.c

Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ void edge_field_cb(void *field, size_t field_len, void *data)
4141
if (cr->cur_field == cr->alloc)
4242
{
4343
cr->alloc *= 2;
44-
cr->fields = realloc(cr->fields, sizeof(char *) * cr->alloc);
45-
cr->fields_len = realloc(cr->header, sizeof(size_t *) * cr->alloc);
44+
cr->fields = repalloc_check(cr->fields, sizeof(char *) * cr->alloc);
45+
cr->fields_len = repalloc_check(cr->header, sizeof(size_t *) * cr->alloc);
4646
if (cr->fields == NULL)
4747
{
4848
cr->error = 1;
@@ -53,7 +53,7 @@ void edge_field_cb(void *field, size_t field_len, void *data)
5353
}
5454
cr->fields_len[cr->cur_field] = field_len;
5555
cr->curr_row_length += field_len;
56-
cr->fields[cr->cur_field] = strndup((char*)field, field_len);
56+
cr->fields[cr->cur_field] = pnstrdup((char*)field, field_len);
5757
cr->cur_field += 1;
5858
}
5959

@@ -83,13 +83,13 @@ void edge_row_cb(int delim __attribute__((unused)), void *data)
8383
{
8484
cr->header_num = cr->cur_field;
8585
cr->header_row_length = cr->curr_row_length;
86-
cr->header_len = (size_t* )malloc(sizeof(size_t *) * cr->cur_field);
87-
cr->header = malloc((sizeof (char*) * cr->cur_field));
86+
cr->header_len = (size_t* )palloc(sizeof(size_t *) * cr->cur_field);
87+
cr->header = palloc((sizeof (char*) * cr->cur_field));
8888

8989
for (i = 0; i<cr->cur_field; i++)
9090
{
9191
cr->header_len[i] = cr->fields_len[i];
92-
cr->header[i] = strndup(cr->fields[i], cr->header_len[i]);
92+
cr->header[i] = pnstrdup(cr->fields[i], cr->header_len[i]);
9393
}
9494
}
9595
else
@@ -138,7 +138,7 @@ void edge_row_cb(int delim __attribute__((unused)), void *data)
138138

139139
for (i = 0; i < n_fields; ++i)
140140
{
141-
free(cr->fields[i]);
141+
pfree_if_not_null(cr->fields[i]);
142142
}
143143

144144
if (cr->error)
@@ -197,6 +197,10 @@ int create_edges_from_csv_file(char *file_path,
197197
(errmsg("Failed to initialize csv parser\n")));
198198
}
199199

200+
p.malloc_func = palloc;
201+
p.realloc_func = repalloc_check;
202+
p.free_func = pfree_if_not_null;
203+
200204
csv_set_space_func(&p, is_space);
201205
csv_set_term_func(&p, is_term);
202206

@@ -207,48 +211,53 @@ int create_edges_from_csv_file(char *file_path,
207211
(errmsg("Failed to open %s\n", file_path)));
208212
}
209213

210-
label_seq_name = get_label_seq_relation_name(label_name);
211-
212-
memset((void*)&cr, 0, sizeof(csv_edge_reader));
213-
cr.alloc = 128;
214-
cr.fields = malloc(sizeof(char *) * cr.alloc);
215-
cr.fields_len = malloc(sizeof(size_t *) * cr.alloc);
216-
cr.header_row_length = 0;
217-
cr.curr_row_length = 0;
218-
cr.graph_name = graph_name;
219-
cr.graph_oid = graph_oid;
220-
cr.label_name = label_name;
221-
cr.label_id = label_id;
222-
cr.label_seq_relid = get_relname_relid(label_seq_name, graph_oid);
223-
cr.load_as_agtype = load_as_agtype;
224-
225-
/* Initialize the batch insert state */
226-
init_edge_batch_insert(&cr.batch_state, label_name, graph_oid);
227-
228-
while ((bytes_read=fread(buf, 1, 1024, fp)) > 0)
214+
PG_TRY();
229215
{
230-
if (csv_parse(&p, buf, bytes_read, edge_field_cb,
231-
edge_row_cb, &cr) != bytes_read)
216+
label_seq_name = get_label_seq_relation_name(label_name);
217+
218+
memset((void*)&cr, 0, sizeof(csv_edge_reader));
219+
cr.alloc = 128;
220+
cr.fields = palloc(sizeof(char *) * cr.alloc);
221+
cr.fields_len = palloc(sizeof(size_t *) * cr.alloc);
222+
cr.header_row_length = 0;
223+
cr.curr_row_length = 0;
224+
cr.graph_name = graph_name;
225+
cr.graph_oid = graph_oid;
226+
cr.label_name = label_name;
227+
cr.label_id = label_id;
228+
cr.label_seq_relid = get_relname_relid(label_seq_name, graph_oid);
229+
cr.load_as_agtype = load_as_agtype;
230+
231+
/* Initialize the batch insert state */
232+
init_edge_batch_insert(&cr.batch_state, label_name, graph_oid);
233+
234+
while ((bytes_read=fread(buf, 1, 1024, fp)) > 0)
232235
{
233-
ereport(ERROR, (errmsg("Error while parsing file: %s\n",
234-
csv_strerror(csv_error(&p)))));
236+
if (csv_parse(&p, buf, bytes_read, edge_field_cb,
237+
edge_row_cb, &cr) != bytes_read)
238+
{
239+
ereport(ERROR, (errmsg("Error while parsing file: %s\n",
240+
csv_strerror(csv_error(&p)))));
241+
}
235242
}
236-
}
237243

238-
csv_fini(&p, edge_field_cb, edge_row_cb, &cr);
244+
csv_fini(&p, edge_field_cb, edge_row_cb, &cr);
239245

240-
/* Finish any remaining batch inserts */
241-
finish_edge_batch_insert(&cr.batch_state, label_name, graph_oid);
246+
/* Finish any remaining batch inserts */
247+
finish_edge_batch_insert(&cr.batch_state, label_name, graph_oid);
242248

243-
if (ferror(fp))
249+
if (ferror(fp))
250+
{
251+
ereport(ERROR, (errmsg("Error while reading file %s\n", file_path)));
252+
}
253+
}
254+
PG_FINALLY();
244255
{
245-
ereport(ERROR, (errmsg("Error while reading file %s\n", file_path)));
256+
fclose(fp);
257+
csv_free(&p);
246258
}
259+
PG_END_TRY();
247260

248-
fclose(fp);
249-
250-
free(cr.fields);
251-
csv_free(&p);
252261
return EXIT_SUCCESS;
253262
}
254263

0 commit comments

Comments
 (0)