Skip to content
Snippets Groups Projects
Commit 43753c2c authored by Tom Lane's avatar Tom Lane
Browse files

Validate ispell dictionaries more carefully.

Using incorrect, or just mismatched, dictionary and affix files
could result in a crash, due to failure to cross-check offsets
obtained from the file.  Add necessary validation, as well as
some Asserts for future-proofing.

Per bug #16050 from Alexander Lakhin.  Back-patch to 9.6 where the
problem was introduced.

Arthur Zakirov, per initial investigation by Tomas Vondra

Discussion: https://postgr.es/m/16050-024ae722464ab604@postgresql.org
Discussion: https://postgr.es/m/20191013012610.2p2fp3zzpoav7jzf@development
parent 7963c4c4
No related branches found
Tags
No related merge requests found
...@@ -458,6 +458,8 @@ IsAffixFlagInUse(IspellDict *Conf, int affix, const char *affixflag) ...@@ -458,6 +458,8 @@ IsAffixFlagInUse(IspellDict *Conf, int affix, const char *affixflag)
if (*affixflag == 0) if (*affixflag == 0)
return true; return true;
Assert(affix < Conf->nAffixData);
flagcur = Conf->AffixData[affix]; flagcur = Conf->AffixData[affix];
while (*flagcur) while (*flagcur)
...@@ -1160,13 +1162,17 @@ getAffixFlagSet(IspellDict *Conf, char *s) ...@@ -1160,13 +1162,17 @@ getAffixFlagSet(IspellDict *Conf, char *s)
(errcode(ERRCODE_CONFIG_FILE_ERROR), (errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("invalid affix alias \"%s\"", s))); errmsg("invalid affix alias \"%s\"", s)));
if (curaffix > 0 && curaffix <= Conf->nAffixData) if (curaffix > 0 && curaffix < Conf->nAffixData)
/* /*
* Do not subtract 1 from curaffix because empty string was added * Do not subtract 1 from curaffix because empty string was added
* in NIImportOOAffixes * in NIImportOOAffixes
*/ */
return Conf->AffixData[curaffix]; return Conf->AffixData[curaffix];
else if (curaffix > Conf->nAffixData)
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("invalid affix alias \"%s\"", s)));
else else
return VoidString; return VoidString;
} }
...@@ -1561,6 +1567,8 @@ MergeAffix(IspellDict *Conf, int a1, int a2) ...@@ -1561,6 +1567,8 @@ MergeAffix(IspellDict *Conf, int a1, int a2)
{ {
char **ptr; char **ptr;
Assert(a1 < Conf->nAffixData && a2 < Conf->nAffixData);
/* Do not merge affix flags if one of affix flags is empty */ /* Do not merge affix flags if one of affix flags is empty */
if (*Conf->AffixData[a1] == '\0') if (*Conf->AffixData[a1] == '\0')
return a2; return a2;
...@@ -1603,9 +1611,10 @@ MergeAffix(IspellDict *Conf, int a1, int a2) ...@@ -1603,9 +1611,10 @@ MergeAffix(IspellDict *Conf, int a1, int a2)
static uint32 static uint32
makeCompoundFlags(IspellDict *Conf, int affix) makeCompoundFlags(IspellDict *Conf, int affix)
{ {
char *str = Conf->AffixData[affix]; Assert(affix < Conf->nAffixData);
return (getCompoundAffixFlagValue(Conf, str) & FF_COMPOUNDFLAGMASK); return (getCompoundAffixFlagValue(Conf, Conf->AffixData[affix]) &
FF_COMPOUNDFLAGMASK);
} }
/* /*
...@@ -1725,6 +1734,16 @@ NISortDictionary(IspellDict *Conf) ...@@ -1725,6 +1734,16 @@ NISortDictionary(IspellDict *Conf)
(errcode(ERRCODE_CONFIG_FILE_ERROR), (errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("invalid affix alias \"%s\"", errmsg("invalid affix alias \"%s\"",
Conf->Spell[i]->p.flag))); Conf->Spell[i]->p.flag)));
if (curaffix < 0 || curaffix >= Conf->nAffixData)
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("invalid affix alias \"%s\"",
Conf->Spell[i]->p.flag)));
if (*end != '\0' && !t_isdigit(end) && !t_isspace(end))
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("invalid affix alias \"%s\"",
Conf->Spell[i]->p.flag)));
} }
else else
{ {
......
...@@ -413,6 +413,40 @@ SELECT ts_lexize('hunspell_num', 'footballyklubber'); ...@@ -413,6 +413,40 @@ SELECT ts_lexize('hunspell_num', 'footballyklubber');
{foot,ball,klubber} {foot,ball,klubber}
(1 row) (1 row)
-- Test suitability of affix and dict files
CREATE TEXT SEARCH DICTIONARY hunspell_err (
Template=ispell,
DictFile=ispell_sample,
AffFile=hunspell_sample_long
);
ERROR: invalid affix alias "GJUS"
CREATE TEXT SEARCH DICTIONARY hunspell_err (
Template=ispell,
DictFile=ispell_sample,
AffFile=hunspell_sample_num
);
ERROR: invalid affix flag "SZ\"
CREATE TEXT SEARCH DICTIONARY hunspell_invalid_1 (
Template=ispell,
DictFile=hunspell_sample_long,
AffFile=ispell_sample
);
CREATE TEXT SEARCH DICTIONARY hunspell_invalid_2 (
Template=ispell,
DictFile=hunspell_sample_long,
AffFile=hunspell_sample_num
);
CREATE TEXT SEARCH DICTIONARY hunspell_invalid_3 (
Template=ispell,
DictFile=hunspell_sample_num,
AffFile=ispell_sample
);
CREATE TEXT SEARCH DICTIONARY hunspell_err (
Template=ispell,
DictFile=hunspell_sample_num,
AffFile=hunspell_sample_long
);
ERROR: invalid affix alias "302,301,202,303"
-- Synonym dictionary -- Synonym dictionary
CREATE TEXT SEARCH DICTIONARY synonym ( CREATE TEXT SEARCH DICTIONARY synonym (
Template=synonym, Template=synonym,
......
...@@ -101,6 +101,43 @@ SELECT ts_lexize('hunspell_num', 'footballklubber'); ...@@ -101,6 +101,43 @@ SELECT ts_lexize('hunspell_num', 'footballklubber');
SELECT ts_lexize('hunspell_num', 'ballyklubber'); SELECT ts_lexize('hunspell_num', 'ballyklubber');
SELECT ts_lexize('hunspell_num', 'footballyklubber'); SELECT ts_lexize('hunspell_num', 'footballyklubber');
-- Test suitability of affix and dict files
CREATE TEXT SEARCH DICTIONARY hunspell_err (
Template=ispell,
DictFile=ispell_sample,
AffFile=hunspell_sample_long
);
CREATE TEXT SEARCH DICTIONARY hunspell_err (
Template=ispell,
DictFile=ispell_sample,
AffFile=hunspell_sample_num
);
CREATE TEXT SEARCH DICTIONARY hunspell_invalid_1 (
Template=ispell,
DictFile=hunspell_sample_long,
AffFile=ispell_sample
);
CREATE TEXT SEARCH DICTIONARY hunspell_invalid_2 (
Template=ispell,
DictFile=hunspell_sample_long,
AffFile=hunspell_sample_num
);
CREATE TEXT SEARCH DICTIONARY hunspell_invalid_3 (
Template=ispell,
DictFile=hunspell_sample_num,
AffFile=ispell_sample
);
CREATE TEXT SEARCH DICTIONARY hunspell_err (
Template=ispell,
DictFile=hunspell_sample_num,
AffFile=hunspell_sample_long
);
-- Synonym dictionary -- Synonym dictionary
CREATE TEXT SEARCH DICTIONARY synonym ( CREATE TEXT SEARCH DICTIONARY synonym (
Template=synonym, Template=synonym,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment