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.
This commit is contained in:
parent
2781b4bea7
commit
b34d6f03db
@ -599,6 +599,9 @@ addFlagValue(IspellDict *Conf, char *s, uint32 val)
|
|||||||
Conf->usecompound = true;
|
Conf->usecompound = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Import an affix file that follows MySpell or Hunspell format
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
NIImportOOAffixes(IspellDict *Conf, const char *filename)
|
NIImportOOAffixes(IspellDict *Conf, const char *filename)
|
||||||
{
|
{
|
||||||
@ -757,6 +760,10 @@ nextline:
|
|||||||
* import affixes
|
* import affixes
|
||||||
*
|
*
|
||||||
* Note caller must already have applied get_tsearch_config_filename
|
* Note caller must already have applied get_tsearch_config_filename
|
||||||
|
*
|
||||||
|
* This function is responsible for parsing ispell ("old format") affix files.
|
||||||
|
* If we realize that the file contains new-format commands, we pass off the
|
||||||
|
* work to NIImportOOAffixes(), which will re-read the whole file.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
NIImportAffixes(IspellDict *Conf, const char *filename)
|
NIImportAffixes(IspellDict *Conf, const char *filename)
|
||||||
@ -833,13 +840,6 @@ NIImportAffixes(IspellDict *Conf, const char *filename)
|
|||||||
|
|
||||||
while (*s && t_isspace(s))
|
while (*s && t_isspace(s))
|
||||||
s += pg_mblen(s);
|
s += pg_mblen(s);
|
||||||
oldformat = true;
|
|
||||||
|
|
||||||
/* allow only single-encoded flags */
|
|
||||||
if (pg_mblen(s) != 1)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_CONFIG_FILE_ERROR),
|
|
||||||
errmsg("multibyte flag character is not allowed")));
|
|
||||||
|
|
||||||
if (*s == '*')
|
if (*s == '*')
|
||||||
{
|
{
|
||||||
@ -855,26 +855,30 @@ NIImportAffixes(IspellDict *Conf, const char *filename)
|
|||||||
if (*s == '\\')
|
if (*s == '\\')
|
||||||
s++;
|
s++;
|
||||||
|
|
||||||
/* allow only single-encoded flags */
|
/*
|
||||||
if (pg_mblen(s) != 1)
|
* An old-format flag is a single ASCII character; we expect it to
|
||||||
ereport(ERROR,
|
* be followed by EOL, whitespace, or ':'. Otherwise this is a
|
||||||
(errcode(ERRCODE_CONFIG_FILE_ERROR),
|
* new-format flag command.
|
||||||
errmsg("multibyte flag character is not allowed")));
|
*/
|
||||||
|
if (*s && pg_mblen(s) == 1)
|
||||||
|
{
|
||||||
flag = *(unsigned char *) s;
|
flag = *(unsigned char *) s;
|
||||||
|
s++;
|
||||||
|
if (*s == '\0' || *s == '#' || *s == '\n' || *s == ':' ||
|
||||||
|
t_isspace(s))
|
||||||
|
{
|
||||||
|
oldformat = true;
|
||||||
goto nextline;
|
goto nextline;
|
||||||
}
|
}
|
||||||
if (STRNCMP(recoded, "COMPOUNDFLAG") == 0 || STRNCMP(recoded, "COMPOUNDMIN") == 0 ||
|
|
||||||
STRNCMP(recoded, "PFX") == 0 || STRNCMP(recoded, "SFX") == 0)
|
|
||||||
{
|
|
||||||
if (oldformat)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_CONFIG_FILE_ERROR),
|
|
||||||
errmsg("wrong affix file format for flag")));
|
|
||||||
tsearch_readline_end(&trst);
|
|
||||||
NIImportOOAffixes(Conf, filename);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
goto isnewformat;
|
||||||
|
}
|
||||||
|
if (STRNCMP(recoded, "COMPOUNDFLAG") == 0 ||
|
||||||
|
STRNCMP(recoded, "COMPOUNDMIN") == 0 ||
|
||||||
|
STRNCMP(recoded, "PFX") == 0 ||
|
||||||
|
STRNCMP(recoded, "SFX") == 0)
|
||||||
|
goto isnewformat;
|
||||||
|
|
||||||
if ((!suffixes) && (!prefixes))
|
if ((!suffixes) && (!prefixes))
|
||||||
goto nextline;
|
goto nextline;
|
||||||
|
|
||||||
@ -888,6 +892,16 @@ nextline:
|
|||||||
pfree(pstr);
|
pfree(pstr);
|
||||||
}
|
}
|
||||||
tsearch_readline_end(&trst);
|
tsearch_readline_end(&trst);
|
||||||
|
return;
|
||||||
|
|
||||||
|
isnewformat:
|
||||||
|
if (oldformat)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_CONFIG_FILE_ERROR),
|
||||||
|
errmsg("affix file contains both old-style and new-style commands")));
|
||||||
|
tsearch_readline_end(&trst);
|
||||||
|
|
||||||
|
NIImportOOAffixes(Conf, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1501,6 +1515,10 @@ CheckCompoundAffixes(CMPDAffix **ptr, char *word, int len, bool CheckInPlace)
|
|||||||
{
|
{
|
||||||
bool issuffix;
|
bool issuffix;
|
||||||
|
|
||||||
|
/* in case CompoundAffix is null: */
|
||||||
|
if (*ptr == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (CheckInPlace)
|
if (CheckInPlace)
|
||||||
{
|
{
|
||||||
while ((*ptr)->affix)
|
while ((*ptr)->affix)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user