Change tsearch2 to not use the unsafe practice of creating functions
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 3 May 2005 16:51:45 +0000 (16:51 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 3 May 2005 16:51:45 +0000 (16:51 +0000)
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 :-(

contrib/tsearch2/gendict/sql.IN
contrib/tsearch2/tsearch.sql.in
contrib/tsearch2/untsearch.sql.in
src/backend/catalog/pg_proc.c

index ff0d8423999f4810d69816baa9225daee7345fb2..044230b4173f8689953450454512cee85d3a251d 100644 (file)
@@ -1,7 +1,7 @@
 SET search_path = public;
 BEGIN;
 
-HASINIT create function dinit_CFG_MODNAME(text)
+HASINIT create function dinit_CFG_MODNAME(internal)
 HASINIT         returns internal
 HASINIT         as 'MODULE_PATHNAME'
 HASINIT         language 'C';
index bb5fc5a6a2cc72fb5e99a0b90faa0048da5b7fdf..5a621d6ebf43a5e724b29f506c35bbe1f5eb3f45 100644 (file)
@@ -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';
index e7cfcc6a879ac5066f119e2a18671b265e4f9834..ed79b69bc2ffa6b02356c3819ebe40d6c9d6d92e 100644 (file)
@@ -34,14 +34,14 @@ DROP FUNCTION lexize(text, text);
 DROP FUNCTION lexize(text);
 DROP FUNCTION set_curdict(int);
 DROP FUNCTION set_curdict(text);
-DROP FUNCTION dex_init(text);
+DROP FUNCTION dex_init(internal);
 DROP FUNCTION dex_lexize(internal,internal,int4);
-DROP FUNCTION snb_en_init(text);
+DROP FUNCTION snb_en_init(internal);
 DROP FUNCTION snb_lexize(internal,internal,int4);
-DROP FUNCTION snb_ru_init(text);
-DROP FUNCTION spell_init(text);
+DROP FUNCTION snb_ru_init(internal);
+DROP FUNCTION spell_init(internal);
 DROP FUNCTION spell_lexize(internal,internal,int4);
-DROP FUNCTION syn_init(text);
+DROP FUNCTION syn_init(internal);
 DROP FUNCTION syn_lexize(internal,internal,int4);
 DROP FUNCTION set_curprs(int);
 DROP FUNCTION set_curprs(text);
index fde65fd109ecb6a55f6bc3d1bc14d7bb05d571cf..7e797fbd4b0ce9c1a79b886f8f0f60bf62f08ec1 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.109 2003/10/03 19:26:49 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.109.2.1 2005/05/03 16:51:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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)