On Wed, Jul 20, 2022 at 03:14:35AM +0000, tanghy.f...@fujitsu.com wrote: > Your fix LGTM so please allow me to merge it in the attached patch. > Based on your rebased version, now this new patch version is V3.
What about the argument of upthread where we could use a goto in functions where there are multiple pattern validation checks? Per se v4 attached. -- Michael
From ccc8bb83baf618ea1a481193403a9009cd4a24a5 Mon Sep 17 00:00:00 2001 From: Michael Paquier <mich...@paquier.xyz> Date: Wed, 20 Jul 2022 12:47:52 +0900 Subject: [PATCH v4] fix the memory leak in psql describe --- src/bin/psql/describe.c | 239 +++++++++++++++++++++++++++++++++++----- 1 file changed, 212 insertions(+), 27 deletions(-) diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 88d92a08ae..1c40cc6d59 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -112,7 +112,10 @@ describeAggregates(const char *pattern, bool verbose, bool showSystem) "n.nspname", "p.proname", NULL, "pg_catalog.pg_function_is_visible(p.oid)", NULL, 3)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;"); @@ -182,7 +185,10 @@ describeAccessMethods(const char *pattern, bool verbose) NULL, "amname", NULL, NULL, NULL, 1)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1;"); @@ -244,7 +250,10 @@ describeTablespaces(const char *pattern, bool verbose) NULL, "spcname", NULL, NULL, NULL, 1)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1;"); @@ -534,7 +543,9 @@ describeFunctions(const char *functypes, const char *func_pattern, "n.nspname", "p.proname", NULL, "pg_catalog.pg_function_is_visible(p.oid)", NULL, 3)) - return false; + { + goto error_return; + } for (int i = 0; i < num_arg_patterns; i++) { @@ -561,7 +572,9 @@ describeFunctions(const char *functypes, const char *func_pattern, true, false, nspname, typname, ft, tiv, NULL, 3)) - return false; + { + goto error_return; + } } else { @@ -599,6 +612,10 @@ describeFunctions(const char *functypes, const char *func_pattern, PQclear(res); return true; + +error_return: + termPQExpBuffer(&buf); + return false; } @@ -682,7 +699,10 @@ describeTypes(const char *pattern, bool verbose, bool showSystem) "pg_catalog.format_type(t.oid, NULL)", "pg_catalog.pg_type_is_visible(t.oid)", NULL, 3)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); @@ -836,7 +856,9 @@ describeOperators(const char *oper_pattern, "n.nspname", "o.oprname", NULL, "pg_catalog.pg_operator_is_visible(o.oid)", NULL, 3)) - return false; + { + goto error_return; + } if (num_arg_patterns == 1) appendPQExpBufferStr(&buf, " AND o.oprleft = 0\n"); @@ -866,7 +888,9 @@ describeOperators(const char *oper_pattern, true, false, nspname, typname, ft, tiv, NULL, 3)) - return false; + { + goto error_return; + } } else { @@ -890,6 +914,10 @@ describeOperators(const char *oper_pattern, PQclear(res); return true; + +error_return: + termPQExpBuffer(&buf); + return false; } @@ -953,7 +981,10 @@ listAllDbs(const char *pattern, bool verbose) if (!validateSQLNamePattern(&buf, pattern, false, false, NULL, "d.datname", NULL, NULL, NULL, 1)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1;"); res = PSQLexec(buf.data); @@ -1106,7 +1137,10 @@ permissionsList(const char *pattern) "n.nspname", "c.relname", NULL, "n.nspname !~ '^pg_' AND pg_catalog.pg_table_is_visible(c.oid)", NULL, 3)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); @@ -1177,16 +1211,15 @@ listDefaultACLs(const char *pattern) "pg_catalog.pg_get_userbyid(d.defaclrole)", NULL, NULL, 3)) - return false; + { + goto error_return; + } appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 3;"); res = PSQLexec(buf.data); if (!res) - { - termPQExpBuffer(&buf); - return false; - } + goto error_return; myopt.nullPrint = NULL; printfPQExpBuffer(&buf, _("Default access privileges")); @@ -1200,6 +1233,10 @@ listDefaultACLs(const char *pattern) termPQExpBuffer(&buf); PQclear(res); return true; + +error_return: + termPQExpBuffer(&buf); + return false; } @@ -1253,7 +1290,9 @@ objectDescription(const char *pattern, bool showSystem) false, "n.nspname", "pgc.conname", NULL, "pg_catalog.pg_table_is_visible(c.oid)", NULL, 3)) - return false; + { + goto error_return; + } /* Domain constraint descriptions */ appendPQExpBuffer(&buf, @@ -1277,7 +1316,9 @@ objectDescription(const char *pattern, bool showSystem) false, "n.nspname", "pgc.conname", NULL, "pg_catalog.pg_type_is_visible(t.oid)", NULL, 3)) - return false; + { + goto error_return; + } /* Operator class descriptions */ appendPQExpBuffer(&buf, @@ -1301,7 +1342,9 @@ objectDescription(const char *pattern, bool showSystem) "n.nspname", "o.opcname", NULL, "pg_catalog.pg_opclass_is_visible(o.oid)", NULL, 3)) - return false; + { + goto error_return; + } /* Operator family descriptions */ appendPQExpBuffer(&buf, @@ -1325,7 +1368,9 @@ objectDescription(const char *pattern, bool showSystem) "n.nspname", "opf.opfname", NULL, "pg_catalog.pg_opfamily_is_visible(opf.oid)", NULL, 3)) - return false; + { + goto error_return; + } /* Rule descriptions (ignore rules for views) */ appendPQExpBuffer(&buf, @@ -1348,7 +1393,9 @@ objectDescription(const char *pattern, bool showSystem) "n.nspname", "r.rulename", NULL, "pg_catalog.pg_table_is_visible(c.oid)", NULL, 3)) - return false; + { + goto error_return; + } /* Trigger descriptions */ appendPQExpBuffer(&buf, @@ -1370,7 +1417,9 @@ objectDescription(const char *pattern, bool showSystem) "n.nspname", "t.tgname", NULL, "pg_catalog.pg_table_is_visible(c.oid)", NULL, 3)) - return false; + { + goto error_return; + } appendPQExpBufferStr(&buf, ") AS tt\n" @@ -1393,6 +1442,10 @@ objectDescription(const char *pattern, bool showSystem) PQclear(res); return true; + +error_return: + termPQExpBuffer(&buf); + return false; } @@ -1428,7 +1481,10 @@ describeTableDetails(const char *pattern, bool verbose, bool showSystem) "n.nspname", "c.relname", NULL, "pg_catalog.pg_table_is_visible(c.oid)", NULL, 3)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 2, 3;"); @@ -3614,7 +3670,10 @@ describeRoles(const char *pattern, bool verbose, bool showSystem) if (!validateSQLNamePattern(&buf, pattern, false, false, NULL, "r.rolname", NULL, NULL, NULL, 1)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1;"); @@ -3739,11 +3798,15 @@ listDbRoleSettings(const char *pattern, const char *pattern2) gettext_noop("Settings")); if (!validateSQLNamePattern(&buf, pattern, false, false, NULL, "r.rolname", NULL, NULL, &havewhere, 1)) - return false; + { + goto error_return; + } if (!validateSQLNamePattern(&buf, pattern2, havewhere, false, NULL, "d.datname", NULL, NULL, NULL, 1)) - return false; + { + goto error_return; + } appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); res = PSQLexec(buf.data); @@ -3779,6 +3842,10 @@ listDbRoleSettings(const char *pattern, const char *pattern2) PQclear(res); return true; + +error_return: + termPQExpBuffer(&buf); + return false; } @@ -3940,7 +4007,10 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys "n.nspname", "c.relname", NULL, "pg_catalog.pg_table_is_visible(c.oid)", NULL, 3)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1,2;"); @@ -4157,7 +4227,10 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose) "n.nspname", "c.relname", NULL, "pg_catalog.pg_table_is_visible(c.oid)", NULL, 3)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBuffer(&buf, "ORDER BY \"Schema\", %s%s\"Name\";", mixed_output ? "\"Type\" DESC, " : "", @@ -4233,7 +4306,10 @@ listLanguages(const char *pattern, bool verbose, bool showSystem) if (!validateSQLNamePattern(&buf, pattern, false, false, NULL, "l.lanname", NULL, NULL, NULL, 2)) + { + termPQExpBuffer(&buf); return false; + } if (!showSystem && !pattern) appendPQExpBufferStr(&buf, "WHERE l.lanplcallfoid != 0\n"); @@ -4319,7 +4395,10 @@ listDomains(const char *pattern, bool verbose, bool showSystem) "n.nspname", "t.typname", NULL, "pg_catalog.pg_type_is_visible(t.oid)", NULL, 3)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); @@ -4395,7 +4474,10 @@ listConversions(const char *pattern, bool verbose, bool showSystem) "n.nspname", "c.conname", NULL, "pg_catalog.pg_conversion_is_visible(c.oid)", NULL, 3)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); @@ -4542,7 +4624,10 @@ listEventTriggers(const char *pattern, bool verbose) if (!validateSQLNamePattern(&buf, pattern, false, false, NULL, "evtname", NULL, NULL, NULL, 1)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1"); @@ -4638,7 +4723,10 @@ listExtendedStats(const char *pattern) "es.stxnamespace::pg_catalog.regnamespace::pg_catalog.text", "es.stxname", NULL, "pg_catalog.pg_statistics_obj_is_visible(es.oid)", NULL, 3)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); @@ -4742,7 +4830,9 @@ listCasts(const char *pattern, bool verbose) "pg_catalog.format_type(ts.oid, NULL)", "pg_catalog.pg_type_is_visible(ts.oid)", NULL, 3)) - return false; + { + goto error_return; + } appendPQExpBufferStr(&buf, ") OR (true"); @@ -4751,7 +4841,9 @@ listCasts(const char *pattern, bool verbose) "pg_catalog.format_type(tt.oid, NULL)", "pg_catalog.pg_type_is_visible(tt.oid)", NULL, 3)) - return false; + { + goto error_return; + } appendPQExpBufferStr(&buf, ") )\nORDER BY 1, 2;"); @@ -4770,6 +4862,10 @@ listCasts(const char *pattern, bool verbose) PQclear(res); return true; + +error_return: + termPQExpBuffer(&buf); + return false; } /* @@ -4851,7 +4947,10 @@ listCollations(const char *pattern, bool verbose, bool showSystem) "n.nspname", "c.collname", NULL, "pg_catalog.pg_collation_is_visible(c.oid)", NULL, 3)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); @@ -4914,7 +5013,10 @@ listSchemas(const char *pattern, bool verbose, bool showSystem) NULL, "n.nspname", NULL, NULL, NULL, 2)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1;"); @@ -5029,7 +5131,10 @@ listTSParsers(const char *pattern, bool verbose) "n.nspname", "p.prsname", NULL, "pg_catalog.pg_ts_parser_is_visible(p.oid)", NULL, 3)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); @@ -5072,7 +5177,10 @@ listTSParsersVerbose(const char *pattern) "n.nspname", "p.prsname", NULL, "pg_catalog.pg_ts_parser_is_visible(p.oid)", NULL, 3)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); @@ -5215,7 +5323,10 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname) res = PSQLexec(buf.data); termPQExpBuffer(&buf); if (!res) + { + termPQExpBuffer(&title); return false; + } myopt.nullPrint = NULL; if (nspname) @@ -5281,7 +5392,10 @@ listTSDictionaries(const char *pattern, bool verbose) "n.nspname", "d.dictname", NULL, "pg_catalog.pg_ts_dict_is_visible(d.oid)", NULL, 3)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); @@ -5344,7 +5458,10 @@ listTSTemplates(const char *pattern, bool verbose) "n.nspname", "t.tmplname", NULL, "pg_catalog.pg_ts_template_is_visible(t.oid)", NULL, 3)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); @@ -5396,7 +5513,10 @@ listTSConfigs(const char *pattern, bool verbose) "n.nspname", "c.cfgname", NULL, "pg_catalog.pg_ts_config_is_visible(c.oid)", NULL, 3)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); @@ -5440,7 +5560,10 @@ listTSConfigsVerbose(const char *pattern) "n.nspname", "c.cfgname", NULL, "pg_catalog.pg_ts_config_is_visible(c.oid)", NULL, 3)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 3, 2;"); @@ -5613,7 +5736,10 @@ listForeignDataWrappers(const char *pattern, bool verbose) if (!validateSQLNamePattern(&buf, pattern, false, false, NULL, "fdwname", NULL, NULL, NULL, 1)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1;"); @@ -5687,7 +5813,10 @@ listForeignServers(const char *pattern, bool verbose) if (!validateSQLNamePattern(&buf, pattern, false, false, NULL, "s.srvname", NULL, NULL, NULL, 1)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1;"); @@ -5740,7 +5869,10 @@ listUserMappings(const char *pattern, bool verbose) if (!validateSQLNamePattern(&buf, pattern, false, false, NULL, "um.srvname", "um.usename", NULL, NULL, 1)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); @@ -5810,7 +5942,10 @@ listForeignTables(const char *pattern, bool verbose) "n.nspname", "c.relname", NULL, "pg_catalog.pg_table_is_visible(c.oid)", NULL, 3)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); @@ -5859,7 +5994,10 @@ listExtensions(const char *pattern) NULL, "e.extname", NULL, NULL, NULL, 1)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1;"); @@ -5900,7 +6038,10 @@ listExtensionContents(const char *pattern) NULL, "e.extname", NULL, NULL, NULL, 1)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1;"); @@ -6023,15 +6164,18 @@ validateSQLNamePattern(PQExpBuffer buf, const char *pattern, bool have_where, if (PQdb(pset.db) == NULL) { pg_log_error("You are currently not connected to a database."); + termPQExpBuffer(&dbbuf); return false; } if (strcmp(PQdb(pset.db), dbbuf.data) != 0) { pg_log_error("cross-database references are not implemented: %s", pattern); + termPQExpBuffer(&dbbuf); return false; } } + termPQExpBuffer(&dbbuf); return true; } @@ -6090,7 +6234,10 @@ listPublications(const char *pattern) NULL, "pubname", NULL, NULL, NULL, 1)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1;"); @@ -6205,7 +6352,10 @@ describePublications(const char *pattern) NULL, "pubname", NULL, NULL, NULL, 1)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 2;"); @@ -6417,7 +6567,10 @@ describeSubscriptions(const char *pattern, bool verbose) NULL, "subname", NULL, NULL, NULL, 1)) + { + termPQExpBuffer(&buf); return false; + } appendPQExpBufferStr(&buf, "ORDER BY 1;"); @@ -6521,7 +6674,9 @@ listOperatorClasses(const char *access_method_pattern, if (!validateSQLNamePattern(&buf, access_method_pattern, false, false, NULL, "am.amname", NULL, NULL, &have_where, 1)) - return false; + { + goto error_return; + } if (type_pattern) { /* Match type name pattern against either internal or external name */ @@ -6530,7 +6685,9 @@ listOperatorClasses(const char *access_method_pattern, "pg_catalog.format_type(t.oid, NULL)", "pg_catalog.pg_type_is_visible(t.oid)", NULL, 3)) - return false; + { + goto error_return; + } } appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;"); @@ -6549,6 +6706,10 @@ listOperatorClasses(const char *access_method_pattern, PQclear(res); return true; + +error_return: + termPQExpBuffer(&buf); + return false; } /* @@ -6597,7 +6758,9 @@ listOperatorFamilies(const char *access_method_pattern, if (!validateSQLNamePattern(&buf, access_method_pattern, false, false, NULL, "am.amname", NULL, NULL, &have_where, 1)) - return false; + { + goto error_return; + } if (type_pattern) { appendPQExpBuffer(&buf, @@ -6614,7 +6777,9 @@ listOperatorFamilies(const char *access_method_pattern, "pg_catalog.format_type(t.oid, NULL)", "pg_catalog.pg_type_is_visible(t.oid)", NULL, 3)) - return false; + { + goto error_return; + } appendPQExpBufferStr(&buf, " )\n"); } @@ -6634,6 +6799,10 @@ listOperatorFamilies(const char *access_method_pattern, PQclear(res); return true; + +error_return: + termPQExpBuffer(&buf); + return false; } /* @@ -6696,13 +6865,17 @@ listOpFamilyOperators(const char *access_method_pattern, false, false, NULL, "am.amname", NULL, NULL, &have_where, 1)) - return false; + { + goto error_return; + } if (family_pattern) if (!validateSQLNamePattern(&buf, family_pattern, have_where, false, "nsf.nspname", "of.opfname", NULL, NULL, NULL, 3)) - return false; + { + goto error_return; + } appendPQExpBufferStr(&buf, "ORDER BY 1, 2,\n" " o.amoplefttype = o.amoprighttype DESC,\n" @@ -6725,6 +6898,10 @@ listOpFamilyOperators(const char *access_method_pattern, PQclear(res); return true; + +error_return: + termPQExpBuffer(&buf); + return false; } /* @@ -6784,12 +6961,16 @@ listOpFamilyFunctions(const char *access_method_pattern, false, false, NULL, "am.amname", NULL, NULL, &have_where, 1)) - return false; + { + goto error_return; + } if (family_pattern) if (!validateSQLNamePattern(&buf, family_pattern, have_where, false, "ns.nspname", "of.opfname", NULL, NULL, NULL, 3)) - return false; + { + goto error_return; + } appendPQExpBufferStr(&buf, "ORDER BY 1, 2,\n" " ap.amproclefttype = ap.amprocrighttype DESC,\n" @@ -6810,6 +6991,10 @@ listOpFamilyFunctions(const char *access_method_pattern, PQclear(res); return true; + +error_return: + termPQExpBuffer(&buf); + return false; } /* -- 2.36.1
signature.asc
Description: PGP signature