Commit 716e8b83 authored by Tom Lane's avatar Tom Lane

Fix RS_isRegis() to agree exactly with RS_compile()'s idea of what's a valid

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.
parent f7108ce0
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -17,26 +17,58 @@ ...@@ -17,26 +17,58 @@
#include "tsearch/dicts/regis.h" #include "tsearch/dicts/regis.h"
#include "tsearch/ts_locale.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 bool
RS_isRegis(const char *str) RS_isRegis(const char *str)
{ {
while (str && *str) int state = RS_IN_WAIT;
const char *c = str;
while (*c)
{ {
if (t_isalpha(str) || if (state == RS_IN_WAIT)
t_iseq(str, '[') || {
t_iseq(str, ']') || if (t_isalpha(c))
t_iseq(str, '^')) /* okay */ ;
str += pg_mblen(str); 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 else
return false; elog(ERROR, "internal error in RS_isRegis: state %d", state);
c += pg_mblen(c);
} }
return true;
}
#define RS_IN_ONEOF 1 return (state == RS_IN_WAIT);
#define RS_IN_ONEOF_IN 2 }
#define RS_IN_NONEOF 3
#define RS_IN_WAIT 4
static RegisNode * static RegisNode *
newRegisNode(RegisNode *prev, int len) newRegisNode(RegisNode *prev, int len)
...@@ -50,11 +82,11 @@ newRegisNode(RegisNode *prev, int len) ...@@ -50,11 +82,11 @@ newRegisNode(RegisNode *prev, int len)
} }
void void
RS_compile(Regis *r, bool issuffix, char *str) RS_compile(Regis *r, bool issuffix, const char *str)
{ {
int len = strlen(str); int len = strlen(str);
int state = RS_IN_WAIT; int state = RS_IN_WAIT;
char *c = (char *) str; const char *c = str;
RegisNode *ptr = NULL; RegisNode *ptr = NULL;
memset(r, 0, sizeof(Regis)); memset(r, 0, sizeof(Regis));
...@@ -83,11 +115,8 @@ RS_compile(Regis *r, bool issuffix, char *str) ...@@ -83,11 +115,8 @@ RS_compile(Regis *r, bool issuffix, char *str)
ptr->type = RSF_ONEOF; ptr->type = RSF_ONEOF;
state = RS_IN_ONEOF; state = RS_IN_ONEOF;
} }
else else /* shouldn't get here */
ereport(ERROR, elog(ERROR, "invalid regis pattern: \"%s\"", str);
(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
errmsg("invalid regis pattern: \"%s\"",
str)));
} }
else if (state == RS_IN_ONEOF) else if (state == RS_IN_ONEOF)
{ {
...@@ -102,11 +131,8 @@ RS_compile(Regis *r, bool issuffix, char *str) ...@@ -102,11 +131,8 @@ RS_compile(Regis *r, bool issuffix, char *str)
ptr->len = pg_mblen(c); ptr->len = pg_mblen(c);
state = RS_IN_ONEOF_IN; state = RS_IN_ONEOF_IN;
} }
else else /* shouldn't get here */
ereport(ERROR, elog(ERROR, "invalid regis pattern: \"%s\"", str);
(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
errmsg("invalid regis pattern: \"%s\"",
str)));
} }
else if (state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF) else if (state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF)
{ {
...@@ -117,17 +143,17 @@ RS_compile(Regis *r, bool issuffix, char *str) ...@@ -117,17 +143,17 @@ RS_compile(Regis *r, bool issuffix, char *str)
} }
else if (t_iseq(c, ']')) else if (t_iseq(c, ']'))
state = RS_IN_WAIT; state = RS_IN_WAIT;
else else /* shouldn't get here */
ereport(ERROR, elog(ERROR, "invalid regis pattern: \"%s\"", str);
(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
errmsg("invalid regis pattern: \"%s\"",
str)));
} }
else else
elog(ERROR, "internal error in RS_compile: state %d", state); elog(ERROR, "internal error in RS_compile: state %d", state);
c += pg_mblen(c); c += pg_mblen(c);
} }
if (state != RS_IN_WAIT) /* shouldn't get here */
elog(ERROR, "invalid regis pattern: \"%s\"", str);
ptr = r->node; ptr = r->node;
while (ptr) while (ptr)
{ {
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 ...@@ -333,7 +333,7 @@ NIAddAffix(IspellDict *Conf, int flag, char flagflags, const char *mask, const c
Affix->issimple = 0; Affix->issimple = 0;
Affix->isregis = 1; Affix->isregis = 1;
RS_compile(&(Affix->reg.regis), (type == FF_SUFFIX) ? true : false, RS_compile(&(Affix->reg.regis), (type == FF_SUFFIX) ? true : false,
(char *) ((mask && *mask) ? mask : VoidString)); (mask && *mask) ? mask : VoidString);
} }
else else
{ {
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * 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 ...@@ -40,7 +40,7 @@ typedef struct Regis
bool RS_isRegis(const char *str); 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); void RS_free(Regis *r);
/*returns true if matches */ /*returns true if matches */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment