From: Tom Lane Date: Tue, 3 May 2005 16:51:45 +0000 (+0000) Subject: Change tsearch2 to not use the unsafe practice of creating functions X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=760d3ce117f64b6bc54fa2e55823e9334c13c9fe;p=users%2Fbernd%2Fpostgres.git Change tsearch2 to not use the unsafe practice of creating functions that return INTERNAL without also having INTERNAL arguments. Since the functions in question aren't meant to be called by hand anyway, I just redeclared them to take 'internal' instead of 'text'. Also add code to ProcedureCreate() to enforce the restriction, as I should have done to start with :-( --- diff --git a/contrib/tsearch2/gendict/sql.IN b/contrib/tsearch2/gendict/sql.IN new file mode 100644 index 0000000000..044230b417 --- /dev/null +++ b/contrib/tsearch2/gendict/sql.IN @@ -0,0 +1,26 @@ +SET search_path = public; +BEGIN; + +HASINIT create function dinit_CFG_MODNAME(internal) +HASINIT returns internal +HASINIT as 'MODULE_PATHNAME' +HASINIT language 'C'; + +NOSNOWBALL create function dlexize_CFG_MODNAME(internal,internal,int4) +NOSNOWBALL returns internal +NOSNOWBALL as 'MODULE_PATHNAME' +NOSNOWBALL language 'C' +NOSNOWBALL with (isstrict); + +insert into pg_ts_dict select + 'CFG_MODNAME', +HASINIT (select oid from pg_proc where proname='dinit_CFG_MODNAME'), +NOINIT null, + null, +ISSNOWBALL (select oid from pg_proc where proname='snb_lexize'), +NOSNOWBALL (select oid from pg_proc where proname='dlexize_CFG_MODNAME'), + CFG_COMMENT +; + + +END; diff --git a/contrib/tsearch2/tsearch.sql.in b/contrib/tsearch2/tsearch.sql.in index bb5fc5a6a2..5a621d6ebf 100644 --- a/contrib/tsearch2/tsearch.sql.in +++ b/contrib/tsearch2/tsearch.sql.in @@ -44,7 +44,7 @@ CREATE FUNCTION set_curdict(text) with (isstrict); --built-in dictionaries -CREATE FUNCTION dex_init(text) +CREATE FUNCTION dex_init(internal) returns internal as 'MODULE_PATHNAME' language 'C'; @@ -63,7 +63,7 @@ insert into pg_ts_dict select 'Simple example of dictionary.' ; -CREATE FUNCTION snb_en_init(text) +CREATE FUNCTION snb_en_init(internal) returns internal as 'MODULE_PATHNAME' language 'C'; @@ -82,7 +82,7 @@ insert into pg_ts_dict select 'English Stemmer. Snowball.' ; -CREATE FUNCTION snb_ru_init(text) +CREATE FUNCTION snb_ru_init(internal) returns internal as 'MODULE_PATHNAME' language 'C'; @@ -95,7 +95,7 @@ insert into pg_ts_dict select 'Russian Stemmer. Snowball.' ; -CREATE FUNCTION spell_init(text) +CREATE FUNCTION spell_init(internal) returns internal as 'MODULE_PATHNAME' language 'C'; @@ -114,7 +114,7 @@ insert into pg_ts_dict select 'ISpell interface. Must have .dict and .aff files' ; -CREATE FUNCTION syn_init(text) +CREATE FUNCTION syn_init(internal) returns internal as 'MODULE_PATHNAME' language 'C'; diff --git a/contrib/tsearch2/untsearch.sql.in b/contrib/tsearch2/untsearch.sql.in new file mode 100644 index 0000000000..ed79b69bc2 --- /dev/null +++ b/contrib/tsearch2/untsearch.sql.in @@ -0,0 +1,65 @@ +BEGIN; + +--Be careful !!! +--script drops all indices, triggers and columns with types defined +--in tsearch2.sql + + +DROP OPERATOR CLASS gist_tsvector_ops USING gist CASCADE; + + +DROP OPERATOR || (tsvector, tsvector); +DROP OPERATOR @@ (tsvector, tsquery); +DROP OPERATOR @@ (tsquery, tsvector); + +DROP AGGREGATE stat(tsvector); + +DROP TABLE pg_ts_dict; +DROP TABLE pg_ts_parser; +DROP TABLE pg_ts_cfg; +DROP TABLE pg_ts_cfgmap; + +DROP TYPE tokentype CASCADE; +DROP TYPE tokenout CASCADE; +DROP TYPE tsvector CASCADE; +DROP TYPE tsquery CASCADE; +DROP TYPE gtsvector CASCADE; +DROP TYPE tsstat CASCADE; +DROP TYPE statinfo CASCADE; +DROP TYPE tsdebug CASCADE; + + +DROP FUNCTION lexize(oid, text) ; +DROP FUNCTION lexize(text, text); +DROP FUNCTION lexize(text); +DROP FUNCTION set_curdict(int); +DROP FUNCTION set_curdict(text); +DROP FUNCTION dex_init(internal); +DROP FUNCTION dex_lexize(internal,internal,int4); +DROP FUNCTION snb_en_init(internal); +DROP FUNCTION snb_lexize(internal,internal,int4); +DROP FUNCTION snb_ru_init(internal); +DROP FUNCTION spell_init(internal); +DROP FUNCTION spell_lexize(internal,internal,int4); +DROP FUNCTION syn_init(internal); +DROP FUNCTION syn_lexize(internal,internal,int4); +DROP FUNCTION set_curprs(int); +DROP FUNCTION set_curprs(text); +DROP FUNCTION prsd_start(internal,int4); +DROP FUNCTION prsd_getlexeme(internal,internal,internal); +DROP FUNCTION prsd_end(internal); +DROP FUNCTION prsd_lextype(internal); +DROP FUNCTION prsd_headline(internal,internal,internal); +DROP FUNCTION set_curcfg(int); +DROP FUNCTION set_curcfg(text); +DROP FUNCTION show_curcfg(); +DROP FUNCTION gtsvector_compress(internal); +DROP FUNCTION gtsvector_decompress(internal); +DROP FUNCTION gtsvector_penalty(internal,internal,internal); +DROP FUNCTION gtsvector_picksplit(internal, internal); +DROP FUNCTION gtsvector_union(bytea, internal); +DROP FUNCTION reset_tsearch(); +DROP FUNCTION tsearch2() CASCADE; +DROP FUNCTION _get_parser_from_curcfg(); + +END; diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index aa7f01d630..cba798d289 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -65,6 +65,8 @@ ProcedureCreate(const char *procedureName, const Oid *parameterTypes) { int i; + bool genericParam = false; + bool internalParam = false; Relation rel; HeapTuple tup; HeapTuple oldtup; @@ -94,29 +96,36 @@ ProcedureCreate(const char *procedureName, /* * Do not allow return type ANYARRAY or ANYELEMENT unless at least one - * argument is also ANYARRAY or ANYELEMENT + * input argument is ANYARRAY or ANYELEMENT. Also, do not allow + * return type INTERNAL unless at least one input argument is INTERNAL. */ - if (returnType == ANYARRAYOID || returnType == ANYELEMENTOID) + for (i = 0; i < parameterCount; i++) { - bool genericParam = false; - - for (i = 0; i < parameterCount; i++) + switch (parameterTypes[i]) { - if (parameterTypes[i] == ANYARRAYOID || - parameterTypes[i] == ANYELEMENTOID) - { + case ANYARRAYOID: + case ANYELEMENTOID: genericParam = true; break; - } + case INTERNALOID: + internalParam = true; + break; } - - if (!genericParam) - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("cannot determine result data type"), - errdetail("A function returning \"anyarray\" or \"anyelement\" must have at least one argument of either type."))); } + if ((returnType == ANYARRAYOID || returnType == ANYELEMENTOID) + && !genericParam) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("cannot determine result data type"), + errdetail("A function returning \"anyarray\" or \"anyelement\" must have at least one argument of either type."))); + + if (returnType == INTERNALOID && !internalParam) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("unsafe use of INTERNAL pseudo-type"), + errdetail("A function returning \"internal\" must have at least one \"internal\" argument."))); + /* Make sure we have a zero-padded param type array */ MemSet(typev, 0, FUNC_MAX_ARGS * sizeof(Oid)); if (parameterCount > 0)