Skip to content

Commit bd7dd4c

Browse files
authored
Fix issue 2093: pfree() called with a NULL pointer (#2095)
Fixed issue 2093 where pfree() was called with a NULL pointer. The issue is due to some confusion with pfree(). There are 2 definitions for it, one that checks for a passed NULL and the other which does not. Created a function, pfree_if_not_null(), to check for NULL and call pfree() if a NULL wasn't passed. Modified the pfree references in the following files - src/backend/commands/label_commands.c src/backend/executor/cypher_merge.c src/backend/executor/cypher_set.c src/backend/parser/ag_scanner.l src/backend/parser/cypher_analyze.c src/backend/parser/cypher_expr.c src/backend/parser/cypher_gram.y src/backend/parser/cypher_parse_agg.c src/backend/utils/adt/age_global_graph.c src/backend/utils/adt/age_graphid_ds.c src/backend/utils/adt/age_session_info.c src/backend/utils/adt/age_vle.c src/backend/utils/adt/agtype.c src/backend/utils/adt/agtype_gin.c src/backend/utils/adt/agtype_raw.c src/backend/utils/adt/agtype_util.c src/backend/utils/load/ag_load_edges.c src/backend/utils/load/ag_load_labels.c src/include/utils/age_graphid_ds.h src/include/utils/age_session_info.h src/include/utils/agtype.h Added regression tests for the original issue.
1 parent 0f0d9be commit bd7dd4c

23 files changed

+141
-100
lines changed

regress/expected/expr.out

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8786,6 +8786,21 @@ SELECT * FROM cypher('fuzzystrmatch', $$ RETURN difference("hello world!", "hell
87868786
ERROR: extension fuzzystrmatch is not installed for function difference
87878787
LINE 1: SELECT * FROM cypher('fuzzystrmatch', $$ RETURN difference("...
87888788
^
8789+
--
8790+
-- Issue 2093: Server crashes when executing SELECT agtype_hash_cmp(agtype_in('[null, null, null, null, null]'));
8791+
--
8792+
SELECT agtype_access_operator(agtype_in('[null, null]'));
8793+
agtype_access_operator
8794+
------------------------
8795+
8796+
(1 row)
8797+
8798+
SELECT agtype_hash_cmp(agtype_in('[null, null, null, null, null]'));
8799+
agtype_hash_cmp
8800+
-----------------
8801+
-505290721
8802+
(1 row)
8803+
87898804
--
87908805
-- Cleanup
87918806
--

regress/sql/expr.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3544,6 +3544,12 @@ SELECT * FROM create_graph('fuzzystrmatch');
35443544
SELECT * FROM cypher('fuzzystrmatch', $$ RETURN soundex("hello world!") $$) AS (result agtype);
35453545
SELECT * FROM cypher('fuzzystrmatch', $$ RETURN difference("hello world!", "hello world!") $$) AS (result agtype);
35463546

3547+
--
3548+
-- Issue 2093: Server crashes when executing SELECT agtype_hash_cmp(agtype_in('[null, null, null, null, null]'));
3549+
--
3550+
SELECT agtype_access_operator(agtype_in('[null, null]'));
3551+
SELECT agtype_hash_cmp(agtype_in('[null, null, null, null, null]'));
3552+
35473553
--
35483554
-- Cleanup
35493555
--

src/backend/commands/label_commands.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ Datum age_is_valid_label_name(PG_FUNCTION_ARGS)
117117
agtv_value->val.string.len);
118118

119119
is_valid = is_valid_label_name(label_name, 0);
120-
pfree(label_name);
120+
pfree_if_not_null(label_name);
121121

122122
if (is_valid)
123123
{

src/backend/executor/cypher_merge.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ static void free_path_entry_array(path_entry **path_array, int length)
346346

347347
for (index = 0; index < length; index++)
348348
{
349-
pfree(path_array[index]);
349+
pfree_if_not_null(path_array[index]);
350350
}
351351
}
352352

@@ -893,10 +893,10 @@ static void end_cypher_merge(CustomScanState *node)
893893
free_path_entry_array(entry, path_length);
894894

895895
/* free up the array container */
896-
pfree(entry);
896+
pfree_if_not_null(entry);
897897

898898
/* free up the created_path container */
899-
pfree(css->created_paths_list);
899+
pfree_if_not_null(css->created_paths_list);
900900

901901
css->created_paths_list = next;
902902
}

src/backend/executor/cypher_set.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ static void process_update_list(CustomScanState *node)
596596
lidx++;
597597
}
598598
/* free our lookup array */
599-
pfree(luindex);
599+
pfree_if_not_null(luindex);
600600
}
601601

602602
static TupleTableSlot *exec_cypher_set(CustomScanState *node)

src/backend/parser/ag_scanner.l

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "mb/pg_wchar.h"
3535

3636
#include "parser/ag_scanner.h"
37+
#include "utils/agtype.h"
3738
}
3839

3940
%option 8bit
@@ -794,7 +795,7 @@ void *ag_yyrealloc(void *ptr, yy_size_t size, yyscan_t yyscanner)
794795
{
795796
if (size == 0)
796797
{
797-
pfree(ptr);
798+
pfree_if_not_null(ptr);
798799
return NULL;
799800
}
800801
else
@@ -811,7 +812,7 @@ void *ag_yyrealloc(void *ptr, yy_size_t size, yyscan_t yyscanner)
811812
void ag_yyfree(void *ptr, yyscan_t yyscanner)
812813
{
813814
if (ptr)
814-
pfree(ptr);
815+
pfree_if_not_null(ptr);
815816
}
816817

817818
static void strbuf_init(strbuf *sb, int capacity)
@@ -824,7 +825,7 @@ static void strbuf_init(strbuf *sb, int capacity)
824825
static void strbuf_cleanup(strbuf *sb)
825826
{
826827
if (sb->buffer)
827-
pfree(sb->buffer);
828+
pfree_if_not_null(sb->buffer);
828829
}
829830

830831
static void strbuf_append_buf(strbuf *sb, const char *b, const int len)
@@ -1119,8 +1120,8 @@ static void _numstr_to_decimal(const char *numstr, const int base, strbuf *sb)
11191120
strbuf_append_buf(sb, &buf[buf_i], NDIGITS_PER_REMAINDER - buf_i);
11201121
}
11211122

1122-
pfree(remainders);
1123-
pfree(words);
1123+
pfree_if_not_null(remainders);
1124+
pfree_if_not_null(words);
11241125
}
11251126

11261127
static uint32 hexdigit_value(const char c)

src/backend/parser/cypher_analyze.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ static void post_parse_analyze(ParseState *pstate, Query *query, JumbleState *js
113113
}
114114

115115
/* reset extra_node */
116-
pfree(extra_node);
116+
pfree_if_not_null(extra_node);
117117
extra_node = NULL;
118118
}
119119
}
@@ -303,7 +303,7 @@ static void build_explain_query(Query *query, Node *explain_node)
303303
((ExplainStmt *)explain_node)->options = NULL;
304304

305305
/* we need to free query_node as it is no longer needed */
306-
pfree(query_node);
306+
pfree_if_not_null(query_node);
307307
}
308308

309309
static bool is_rte_cypher(RangeTblEntry *rte)

src/backend/parser/cypher_expr.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1688,7 +1688,7 @@ static List *cast_agtype_input_to_other_type(cypher_parsestate *cpstate,
16881688
}
16891689

16901690
/* free the old args and replace them with the new ones */
1691-
pfree(targs);
1691+
pfree_if_not_null(targs);
16921692
targs = new_targs;
16931693
break;
16941694
}
@@ -1743,7 +1743,7 @@ static void check_for_extension_functions(char *extension, FuncCall *fn)
17431743
if (procform->pronamespace == oid &&
17441744
isTempNamespace(procform->pronamespace) == false)
17451745
{
1746-
pfree(asp);
1746+
pfree_if_not_null(asp);
17471747
found = true;
17481748
break;
17491749
}
@@ -1754,7 +1754,7 @@ static void check_for_extension_functions(char *extension, FuncCall *fn)
17541754
break;
17551755
}
17561756

1757-
pfree(asp);
1757+
pfree_if_not_null(asp);
17581758
}
17591759

17601760
/* if we didn't find it, it isn't in the search path */

src/backend/parser/cypher_gram.y

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "parser/cypher_gram.h"
2727
#include "parser/cypher_parse_node.h"
2828
#include "parser/scansup.h"
29+
#include "utils/agtype.h"
2930

3031
/* override the default action for locations */
3132
#define YYLLOC_DEFAULT(current, rhs, n) \
@@ -2924,7 +2925,7 @@ static char *create_unique_name(char *prefix_name)
29242925
/* if we created the prefix, we need to free it */
29252926
if (prefix_name == NULL || strlen(prefix_name) <= 0)
29262927
{
2927-
pfree(prefix);
2928+
pfree_if_not_null(prefix);
29282929
}
29292930

29302931
return name;

src/backend/parser/cypher_parse_agg.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "parser/cypher_parse_agg.h"
3232
#include "parser/parsetree.h"
3333
#include "rewrite/rewriteManip.h"
34+
#include "utils/agtype.h"
3435

3536
typedef struct
3637
{
@@ -817,7 +818,7 @@ static List * expand_grouping_sets(List *groupingSets, int limit)
817818
result = lappend(result, list_union_int(NIL, (List *) lfirst(lc)));
818819
}
819820

820-
for_each_cell(lc, expanded_groups,
821+
for_each_cell(lc, expanded_groups,
821822
lnext(expanded_groups, list_head(expanded_groups)))
822823
{
823824
List *p = lfirst(lc);
@@ -857,7 +858,7 @@ static List * expand_grouping_sets(List *groupingSets, int limit)
857858
while (result_len-- > 0)
858859
result = lappend(result, *ptr++);
859860

860-
pfree(buf);
861+
pfree_if_not_null(buf);
861862
}
862863

863864
return result;

0 commit comments

Comments
 (0)