Fix RS_isRegis() to agree exactly with RS_compile()'s idea of what's a valid
authorTom Lane
Mon, 21 Jan 2008 02:46:11 +0000 (02:46 +0000)
committerTom Lane
Mon, 21 Jan 2008 02:46:11 +0000 (02:46 +0000)
regis.  Correct the latter's oversight that a bracket-expression needs to be
terminated.  Reduce the ereports to elogs, since they are now not expected to
ever be hit (thus addressing Alvaro's original complaint).
In passing, const-ify the string argument to RS_compile.

src/backend/tsearch/regis.c
src/backend/tsearch/spell.c
src/include/tsearch/dicts/regis.h

index 4c35afd18d6eab5104fe00e8a6351d906c21f700..0fe0064fd1480545ed4f6ff76aa565802cdee732 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/tsearch/regis.c,v 1.3 2008/01/01 19:45:52 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/tsearch/regis.c,v 1.4 2008/01/21 02:46:10 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "tsearch/dicts/regis.h"
 #include "tsearch/ts_locale.h"
 
+#define RS_IN_ONEOF 1
+#define RS_IN_ONEOF_IN 2
+#define RS_IN_NONEOF   3
+#define RS_IN_WAIT 4
+
+
+/*
+ * Test whether a regex is of the subset supported here.
+ * Keep this in sync with RS_compile!
+ */
 bool
 RS_isRegis(const char *str)
 {
-   while (str && *str)
+   int         state = RS_IN_WAIT;
+   const char *c = str;
+
+   while (*c)
    {
-       if (t_isalpha(str) ||
-           t_iseq(str, '[') ||
-           t_iseq(str, ']') ||
-           t_iseq(str, '^'))
-           str += pg_mblen(str);
+       if (state == RS_IN_WAIT)
+       {
+           if (t_isalpha(c))
+               /* okay */ ;
+           else if (t_iseq(c, '['))
+               state = RS_IN_ONEOF;
+           else
+               return false;
+       }
+       else if (state == RS_IN_ONEOF)
+       {
+           if (t_iseq(c, '^'))
+               state = RS_IN_NONEOF;
+           else if (t_isalpha(c))
+               state = RS_IN_ONEOF_IN;
+           else
+               return false;
+       }
+       else if (state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF)
+       {
+           if (t_isalpha(c))
+               /* okay */ ;
+           else if (t_iseq(c, ']'))
+               state = RS_IN_WAIT;
+           else
+               return false;
+       }
        else
-           return false;
+           elog(ERROR, "internal error in RS_isRegis: state %d", state);
+       c += pg_mblen(c);
    }
-   return true;
-}
 
-#define RS_IN_ONEOF 1
-#define RS_IN_ONEOF_IN 2
-#define RS_IN_NONEOF   3
-#define RS_IN_WAIT 4
+   return (state == RS_IN_WAIT);
+}
 
 static RegisNode *
 newRegisNode(RegisNode *prev, int len)
@@ -50,11 +82,11 @@ newRegisNode(RegisNode *prev, int len)
 }
 
 void
-RS_compile(Regis *r, bool issuffix, char *str)
+RS_compile(Regis *r, bool issuffix, const char *str)
 {
    int         len = strlen(str);
    int         state = RS_IN_WAIT;
-   char       *c = (char *) str;
+   const char *c = str;
    RegisNode  *ptr = NULL;
 
    memset(r, 0, sizeof(Regis));
@@ -83,11 +115,8 @@ RS_compile(Regis *r, bool issuffix, char *str)
                ptr->type = RSF_ONEOF;
                state = RS_IN_ONEOF;
            }
-           else
-               ereport(ERROR,
-                       (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
-                        errmsg("invalid regis pattern: \"%s\"",
-                               str)));
+           else                /* shouldn't get here */
+               elog(ERROR, "invalid regis pattern: \"%s\"", str);
        }
        else if (state == RS_IN_ONEOF)
        {
@@ -102,11 +131,8 @@ RS_compile(Regis *r, bool issuffix, char *str)
                ptr->len = pg_mblen(c);
                state = RS_IN_ONEOF_IN;
            }
-           else
-               ereport(ERROR,
-                       (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
-                        errmsg("invalid regis pattern: \"%s\"",
-                               str)));
+           else                /* shouldn't get here */
+               elog(ERROR, "invalid regis pattern: \"%s\"", str);
        }
        else if (state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF)
        {
@@ -117,17 +143,17 @@ RS_compile(Regis *r, bool issuffix, char *str)
            }
            else if (t_iseq(c, ']'))
                state = RS_IN_WAIT;
-           else
-               ereport(ERROR,
-                       (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
-                        errmsg("invalid regis pattern: \"%s\"",
-                               str)));
+           else                /* shouldn't get here */
+               elog(ERROR, "invalid regis pattern: \"%s\"", str);
        }
        else
            elog(ERROR, "internal error in RS_compile: state %d", state);
        c += pg_mblen(c);
    }
 
+   if (state != RS_IN_WAIT)        /* shouldn't get here */
+       elog(ERROR, "invalid regis pattern: \"%s\"", str);
+
    ptr = r->node;
    while (ptr)
    {
index 00f9d3c477f81559bc799e03d5bdd2b55d947c4f..a2837d16831ec466dc4cf74803e7c4de93c940a1 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/tsearch/spell.c,v 1.10 2008/01/16 13:01:03 teodor Exp $
+ *   $PostgreSQL: pgsql/src/backend/tsearch/spell.c,v 1.11 2008/01/21 02:46:10 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -333,7 +333,7 @@ NIAddAffix(IspellDict *Conf, int flag, char flagflags, const char *mask, const c
        Affix->issimple = 0;
        Affix->isregis = 1;
        RS_compile(&(Affix->reg.regis), (type == FF_SUFFIX) ? true : false,
-                  (char *) ((mask && *mask) ? mask : VoidString));
+                  (mask && *mask) ? mask : VoidString);
    }
    else
    {
index b97ec25471bc57f97d0e856ccf55660e208cea1b..5c3c1794b84607ee631a48172a786f6b9beb911d 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/include/tsearch/dicts/regis.h,v 1.4 2008/01/01 19:45:59 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/tsearch/dicts/regis.h,v 1.5 2008/01/21 02:46:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -40,7 +40,7 @@ typedef struct Regis
 
 bool       RS_isRegis(const char *str);
 
-void       RS_compile(Regis *r, bool issuffix, char *str);
+void       RS_compile(Regis *r, bool issuffix, const char *str);
 void       RS_free(Regis *r);
 
 /*returns true if matches */