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

Commit 1cf54b0

Browse files
committed
Improve ispell dictionary's defenses against bad affix files.
Don't crash if an ispell dictionary definition contains flags but not any compound affixes. (This isn't a security issue since only superusers can install affix files, but still it's a bad thing.) Also, be more careful about detecting whether an affix-file FLAG command is old-format (ispell) or new-format (myspell/hunspell). And change the error message about mixed old-format and new-format commands into something intelligible. Per bug #11770 from Emre Hasegeli. Back-patch to all supported branches.
1 parent 6d12cc1 commit 1cf54b0

File tree

1 file changed

+44
-26
lines changed

1 file changed

+44
-26
lines changed

src/backend/tsearch/spell.c

+44-26
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,9 @@ addFlagValue(IspellDict *Conf, char *s, uint32 val)
599599
Conf->usecompound = true;
600600
}
601601

602+
/*
603+
* Import an affix file that follows MySpell or Hunspell format
604+
*/
602605
static void
603606
NIImportOOAffixes(IspellDict *Conf, const char *filename)
604607
{
@@ -757,6 +760,10 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
757760
* import affixes
758761
*
759762
* Note caller must already have applied get_tsearch_config_filename
763+
*
764+
* This function is responsible for parsing ispell ("old format") affix files.
765+
* If we realize that the file contains new-format commands, we pass off the
766+
* work to NIImportOOAffixes(), which will re-read the whole file.
760767
*/
761768
void
762769
NIImportAffixes(IspellDict *Conf, const char *filename)
@@ -833,13 +840,6 @@ NIImportAffixes(IspellDict *Conf, const char *filename)
833840

834841
while (*s && t_isspace(s))
835842
s += pg_mblen(s);
836-
oldformat = true;
837-
838-
/* allow only single-encoded flags */
839-
if (pg_mblen(s) != 1)
840-
ereport(ERROR,
841-
(errcode(ERRCODE_CONFIG_FILE_ERROR),
842-
errmsg("multibyte flag character is not allowed")));
843843

844844
if (*s == '*')
845845
{
@@ -855,26 +855,30 @@ NIImportAffixes(IspellDict *Conf, const char *filename)
855855
if (*s == '\\')
856856
s++;
857857

858-
/* allow only single-encoded flags */
859-
if (pg_mblen(s) != 1)
860-
ereport(ERROR,
861-
(errcode(ERRCODE_CONFIG_FILE_ERROR),
862-
errmsg("multibyte flag character is not allowed")));
863-
864-
flag = *(unsigned char *) s;
865-
goto nextline;
866-
}
867-
if (STRNCMP(recoded, "COMPOUNDFLAG") == 0 || STRNCMP(recoded, "COMPOUNDMIN") == 0 ||
868-
STRNCMP(recoded, "PFX") == 0 || STRNCMP(recoded, "SFX") == 0)
869-
{
870-
if (oldformat)
871-
ereport(ERROR,
872-
(errcode(ERRCODE_CONFIG_FILE_ERROR),
873-
errmsg("wrong affix file format for flag")));
874-
tsearch_readline_end(&trst);
875-
NIImportOOAffixes(Conf, filename);
876-
return;
858+
/*
859+
* An old-format flag is a single ASCII character; we expect it to
860+
* be followed by EOL, whitespace, or ':'. Otherwise this is a
861+
* new-format flag command.
862+
*/
863+
if (*s && pg_mblen(s) == 1)
864+
{
865+
flag = *(unsigned char *) s;
866+
s++;
867+
if (*s == '\0' || *s == '#' || *s == '\n' || *s == ':' ||
868+
t_isspace(s))
869+
{
870+
oldformat = true;
871+
goto nextline;
872+
}
873+
}
874+
goto isnewformat;
877875
}
876+
if (STRNCMP(recoded, "COMPOUNDFLAG") == 0 ||
877+
STRNCMP(recoded, "COMPOUNDMIN") == 0 ||
878+
STRNCMP(recoded, "PFX") == 0 ||
879+
STRNCMP(recoded, "SFX") == 0)
880+
goto isnewformat;
881+
878882
if ((!suffixes) && (!prefixes))
879883
goto nextline;
880884

@@ -888,6 +892,16 @@ NIImportAffixes(IspellDict *Conf, const char *filename)
888892
pfree(pstr);
889893
}
890894
tsearch_readline_end(&trst);
895+
return;
896+
897+
isnewformat:
898+
if (oldformat)
899+
ereport(ERROR,
900+
(errcode(ERRCODE_CONFIG_FILE_ERROR),
901+
errmsg("affix file contains both old-style and new-style commands")));
902+
tsearch_readline_end(&trst);
903+
904+
NIImportOOAffixes(Conf, filename);
891905
}
892906

893907
static int
@@ -1501,6 +1515,10 @@ CheckCompoundAffixes(CMPDAffix **ptr, char *word, int len, bool CheckInPlace)
15011515
{
15021516
bool issuffix;
15031517

1518+
/* in case CompoundAffix is null: */
1519+
if (*ptr == NULL)
1520+
return -1;
1521+
15041522
if (CheckInPlace)
15051523
{
15061524
while ((*ptr)->affix)

0 commit comments

Comments
 (0)