Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 716e8b8

Browse files
committed
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.
1 parent f7108ce commit 716e8b8

File tree

3 files changed

+61
-35
lines changed

3 files changed

+61
-35
lines changed

src/backend/tsearch/regis.c

+57-31
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/tsearch/regis.c,v 1.3 2008/01/01 19:45:52 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/tsearch/regis.c,v 1.4 2008/01/21 02:46:10 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -17,26 +17,58 @@
1717
#include "tsearch/dicts/regis.h"
1818
#include "tsearch/ts_locale.h"
1919

20+
#define RS_IN_ONEOF 1
21+
#define RS_IN_ONEOF_IN 2
22+
#define RS_IN_NONEOF 3
23+
#define RS_IN_WAIT 4
24+
25+
26+
/*
27+
* Test whether a regex is of the subset supported here.
28+
* Keep this in sync with RS_compile!
29+
*/
2030
bool
2131
RS_isRegis(const char *str)
2232
{
23-
while (str && *str)
33+
int state = RS_IN_WAIT;
34+
const char *c = str;
35+
36+
while (*c)
2437
{
25-
if (t_isalpha(str) ||
26-
t_iseq(str, '[') ||
27-
t_iseq(str, ']') ||
28-
t_iseq(str, '^'))
29-
str += pg_mblen(str);
38+
if (state == RS_IN_WAIT)
39+
{
40+
if (t_isalpha(c))
41+
/* okay */ ;
42+
else if (t_iseq(c, '['))
43+
state = RS_IN_ONEOF;
44+
else
45+
return false;
46+
}
47+
else if (state == RS_IN_ONEOF)
48+
{
49+
if (t_iseq(c, '^'))
50+
state = RS_IN_NONEOF;
51+
else if (t_isalpha(c))
52+
state = RS_IN_ONEOF_IN;
53+
else
54+
return false;
55+
}
56+
else if (state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF)
57+
{
58+
if (t_isalpha(c))
59+
/* okay */ ;
60+
else if (t_iseq(c, ']'))
61+
state = RS_IN_WAIT;
62+
else
63+
return false;
64+
}
3065
else
31-
return false;
66+
elog(ERROR, "internal error in RS_isRegis: state %d", state);
67+
c += pg_mblen(c);
3268
}
33-
return true;
34-
}
3569

36-
#define RS_IN_ONEOF 1
37-
#define RS_IN_ONEOF_IN 2
38-
#define RS_IN_NONEOF 3
39-
#define RS_IN_WAIT 4
70+
return (state == RS_IN_WAIT);
71+
}
4072

4173
static RegisNode *
4274
newRegisNode(RegisNode *prev, int len)
@@ -50,11 +82,11 @@ newRegisNode(RegisNode *prev, int len)
5082
}
5183

5284
void
53-
RS_compile(Regis *r, bool issuffix, char *str)
85+
RS_compile(Regis *r, bool issuffix, const char *str)
5486
{
5587
int len = strlen(str);
5688
int state = RS_IN_WAIT;
57-
char *c = (char *) str;
89+
const char *c = str;
5890
RegisNode *ptr = NULL;
5991

6092
memset(r, 0, sizeof(Regis));
@@ -83,11 +115,8 @@ RS_compile(Regis *r, bool issuffix, char *str)
83115
ptr->type = RSF_ONEOF;
84116
state = RS_IN_ONEOF;
85117
}
86-
else
87-
ereport(ERROR,
88-
(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
89-
errmsg("invalid regis pattern: \"%s\"",
90-
str)));
118+
else /* shouldn't get here */
119+
elog(ERROR, "invalid regis pattern: \"%s\"", str);
91120
}
92121
else if (state == RS_IN_ONEOF)
93122
{
@@ -102,11 +131,8 @@ RS_compile(Regis *r, bool issuffix, char *str)
102131
ptr->len = pg_mblen(c);
103132
state = RS_IN_ONEOF_IN;
104133
}
105-
else
106-
ereport(ERROR,
107-
(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
108-
errmsg("invalid regis pattern: \"%s\"",
109-
str)));
134+
else /* shouldn't get here */
135+
elog(ERROR, "invalid regis pattern: \"%s\"", str);
110136
}
111137
else if (state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF)
112138
{
@@ -117,17 +143,17 @@ RS_compile(Regis *r, bool issuffix, char *str)
117143
}
118144
else if (t_iseq(c, ']'))
119145
state = RS_IN_WAIT;
120-
else
121-
ereport(ERROR,
122-
(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
123-
errmsg("invalid regis pattern: \"%s\"",
124-
str)));
146+
else /* shouldn't get here */
147+
elog(ERROR, "invalid regis pattern: \"%s\"", str);
125148
}
126149
else
127150
elog(ERROR, "internal error in RS_compile: state %d", state);
128151
c += pg_mblen(c);
129152
}
130153

154+
if (state != RS_IN_WAIT) /* shouldn't get here */
155+
elog(ERROR, "invalid regis pattern: \"%s\"", str);
156+
131157
ptr = r->node;
132158
while (ptr)
133159
{

src/backend/tsearch/spell.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/tsearch/spell.c,v 1.10 2008/01/16 13:01:03 teodor Exp $
10+
* $PostgreSQL: pgsql/src/backend/tsearch/spell.c,v 1.11 2008/01/21 02:46:10 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -333,7 +333,7 @@ NIAddAffix(IspellDict *Conf, int flag, char flagflags, const char *mask, const c
333333
Affix->issimple = 0;
334334
Affix->isregis = 1;
335335
RS_compile(&(Affix->reg.regis), (type == FF_SUFFIX) ? true : false,
336-
(char *) ((mask && *mask) ? mask : VoidString));
336+
(mask && *mask) ? mask : VoidString);
337337
}
338338
else
339339
{

src/include/tsearch/dicts/regis.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
88
*
9-
* $PostgreSQL: pgsql/src/include/tsearch/dicts/regis.h,v 1.4 2008/01/01 19:45:59 momjian Exp $
9+
* $PostgreSQL: pgsql/src/include/tsearch/dicts/regis.h,v 1.5 2008/01/21 02:46:11 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -40,7 +40,7 @@ typedef struct Regis
4040

4141
bool RS_isRegis(const char *str);
4242

43-
void RS_compile(Regis *r, bool issuffix, char *str);
43+
void RS_compile(Regis *r, bool issuffix, const char *str);
4444
void RS_free(Regis *r);
4545

4646
/*returns true if matches */

0 commit comments

Comments
 (0)