Skip to content

Commit 21fa26b

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 ac6e875 commit 21fa26b

File tree

1 file changed

+44
-26
lines changed

1 file changed

+44
-26
lines changed

src/backend/tsearch/spell.c

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,9 @@ addFlagValue(IspellDict *Conf, char *s, uint32 val)
525525
Conf->usecompound = true;
526526
}
527527

528+
/*
529+
* Import an affix file that follows MySpell or Hunspell format
530+
*/
528531
static void
529532
NIImportOOAffixes(IspellDict *Conf, const char *filename)
530533
{
@@ -685,6 +688,10 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
685688
* import affixes
686689
*
687690
* Note caller must already have applied get_tsearch_config_filename
691+
*
692+
* This function is responsible for parsing ispell ("old format") affix files.
693+
* If we realize that the file contains new-format commands, we pass off the
694+
* work to NIImportOOAffixes(), which will re-read the whole file.
688695
*/
689696
void
690697
NIImportAffixes(IspellDict *Conf, const char *filename)
@@ -763,13 +770,6 @@ NIImportAffixes(IspellDict *Conf, const char *filename)
763770

764771
while (*s && t_isspace(s))
765772
s += pg_mblen(s);
766-
oldformat = true;
767-
768-
/* allow only single-encoded flags */
769-
if (pg_mblen(s) != 1)
770-
ereport(ERROR,
771-
(errcode(ERRCODE_CONFIG_FILE_ERROR),
772-
errmsg("multibyte flag character is not allowed")));
773773

774774
if (*s == '*')
775775
{
@@ -785,26 +785,30 @@ NIImportAffixes(IspellDict *Conf, const char *filename)
785785
if (*s == '\\')
786786
s++;
787787

788-
/* allow only single-encoded flags */
789-
if (pg_mblen(s) != 1)
790-
ereport(ERROR,
791-
(errcode(ERRCODE_CONFIG_FILE_ERROR),
792-
errmsg("multibyte flag character is not allowed")));
793-
794-
flag = *(unsigned char *) s;
795-
goto nextline;
796-
}
797-
if (STRNCMP(recoded, "COMPOUNDFLAG") == 0 || STRNCMP(recoded, "COMPOUNDMIN") == 0 ||
798-
STRNCMP(recoded, "PFX") == 0 || STRNCMP(recoded, "SFX") == 0)
799-
{
800-
if (oldformat)
801-
ereport(ERROR,
802-
(errcode(ERRCODE_CONFIG_FILE_ERROR),
803-
errmsg("wrong affix file format for flag")));
804-
tsearch_readline_end(&trst);
805-
NIImportOOAffixes(Conf, filename);
806-
return;
788+
/*
789+
* An old-format flag is a single ASCII character; we expect it to
790+
* be followed by EOL, whitespace, or ':'. Otherwise this is a
791+
* new-format flag command.
792+
*/
793+
if (*s && pg_mblen(s) == 1)
794+
{
795+
flag = *(unsigned char *) s;
796+
s++;
797+
if (*s == '\0' || *s == '#' || *s == '\n' || *s == ':' ||
798+
t_isspace(s))
799+
{
800+
oldformat = true;
801+
goto nextline;
802+
}
803+
}
804+
goto isnewformat;
807805
}
806+
if (STRNCMP(recoded, "COMPOUNDFLAG") == 0 ||
807+
STRNCMP(recoded, "COMPOUNDMIN") == 0 ||
808+
STRNCMP(recoded, "PFX") == 0 ||
809+
STRNCMP(recoded, "SFX") == 0)
810+
goto isnewformat;
811+
808812
if ((!suffixes) && (!prefixes))
809813
goto nextline;
810814

@@ -818,6 +822,16 @@ NIImportAffixes(IspellDict *Conf, const char *filename)
818822
pfree(pstr);
819823
}
820824
tsearch_readline_end(&trst);
825+
return;
826+
827+
isnewformat:
828+
if (oldformat)
829+
ereport(ERROR,
830+
(errcode(ERRCODE_CONFIG_FILE_ERROR),
831+
errmsg("affix file contains both old-style and new-style commands")));
832+
tsearch_readline_end(&trst);
833+
834+
NIImportOOAffixes(Conf, filename);
821835
}
822836

823837
static int
@@ -1436,6 +1450,10 @@ CheckCompoundAffixes(CMPDAffix **ptr, char *word, int len, bool CheckInPlace)
14361450
{
14371451
bool issuffix;
14381452

1453+
/* in case CompoundAffix is null: */
1454+
if (*ptr == NULL)
1455+
return -1;
1456+
14391457
if (CheckInPlace)
14401458
{
14411459
while ((*ptr)->affix)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy