]> granicus.if.org Git - postgresql/commitdiff
Fix RS_isRegis() to agree exactly with RS_compile()'s idea of what's a valid
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 21 Jan 2008 02:46:11 +0000 (02:46 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
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 */