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

Commit 8af1624

Browse files
committed
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
1 parent dc816e5 commit 8af1624

File tree

3 files changed

+93
-3
lines changed

3 files changed

+93
-3
lines changed

src/backend/tsearch/spell.c

+22-3
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,8 @@ IsAffixFlagInUse(IspellDict *Conf, int affix, const char *affixflag)
458458
if (*affixflag == 0)
459459
return true;
460460

461+
Assert(affix < Conf->nAffixData);
462+
461463
flagcur = Conf->AffixData[affix];
462464

463465
while (*flagcur)
@@ -1160,13 +1162,17 @@ getAffixFlagSet(IspellDict *Conf, char *s)
11601162
(errcode(ERRCODE_CONFIG_FILE_ERROR),
11611163
errmsg("invalid affix alias \"%s\"", s)));
11621164

1163-
if (curaffix > 0 && curaffix <= Conf->nAffixData)
1165+
if (curaffix > 0 && curaffix < Conf->nAffixData)
11641166

11651167
/*
11661168
* Do not subtract 1 from curaffix because empty string was added
11671169
* in NIImportOOAffixes
11681170
*/
11691171
return Conf->AffixData[curaffix];
1172+
else if (curaffix > Conf->nAffixData)
1173+
ereport(ERROR,
1174+
(errcode(ERRCODE_CONFIG_FILE_ERROR),
1175+
errmsg("invalid affix alias \"%s\"", s)));
11701176
else
11711177
return VoidString;
11721178
}
@@ -1561,6 +1567,8 @@ MergeAffix(IspellDict *Conf, int a1, int a2)
15611567
{
15621568
char **ptr;
15631569

1570+
Assert(a1 < Conf->nAffixData && a2 < Conf->nAffixData);
1571+
15641572
/* Do not merge affix flags if one of affix flags is empty */
15651573
if (*Conf->AffixData[a1] == '\0')
15661574
return a2;
@@ -1603,9 +1611,10 @@ MergeAffix(IspellDict *Conf, int a1, int a2)
16031611
static uint32
16041612
makeCompoundFlags(IspellDict *Conf, int affix)
16051613
{
1606-
char *str = Conf->AffixData[affix];
1614+
Assert(affix < Conf->nAffixData);
16071615

1608-
return (getCompoundAffixFlagValue(Conf, str) & FF_COMPOUNDFLAGMASK);
1616+
return (getCompoundAffixFlagValue(Conf, Conf->AffixData[affix]) &
1617+
FF_COMPOUNDFLAGMASK);
16091618
}
16101619

16111620
/*
@@ -1725,6 +1734,16 @@ NISortDictionary(IspellDict *Conf)
17251734
(errcode(ERRCODE_CONFIG_FILE_ERROR),
17261735
errmsg("invalid affix alias \"%s\"",
17271736
Conf->Spell[i]->p.flag)));
1737+
if (curaffix < 0 || curaffix >= Conf->nAffixData)
1738+
ereport(ERROR,
1739+
(errcode(ERRCODE_CONFIG_FILE_ERROR),
1740+
errmsg("invalid affix alias \"%s\"",
1741+
Conf->Spell[i]->p.flag)));
1742+
if (*end != '\0' && !t_isdigit(end) && !t_isspace(end))
1743+
ereport(ERROR,
1744+
(errcode(ERRCODE_CONFIG_FILE_ERROR),
1745+
errmsg("invalid affix alias \"%s\"",
1746+
Conf->Spell[i]->p.flag)));
17281747
}
17291748
else
17301749
{

src/test/regress/expected/tsdicts.out

+34
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,40 @@ SELECT ts_lexize('hunspell_num', 'footballyklubber');
413413
{foot,ball,klubber}
414414
(1 row)
415415

416+
-- Test suitability of affix and dict files
417+
CREATE TEXT SEARCH DICTIONARY hunspell_err (
418+
Template=ispell,
419+
DictFile=ispell_sample,
420+
AffFile=hunspell_sample_long
421+
);
422+
ERROR: invalid affix alias "GJUS"
423+
CREATE TEXT SEARCH DICTIONARY hunspell_err (
424+
Template=ispell,
425+
DictFile=ispell_sample,
426+
AffFile=hunspell_sample_num
427+
);
428+
ERROR: invalid affix flag "SZ\"
429+
CREATE TEXT SEARCH DICTIONARY hunspell_invalid_1 (
430+
Template=ispell,
431+
DictFile=hunspell_sample_long,
432+
AffFile=ispell_sample
433+
);
434+
CREATE TEXT SEARCH DICTIONARY hunspell_invalid_2 (
435+
Template=ispell,
436+
DictFile=hunspell_sample_long,
437+
AffFile=hunspell_sample_num
438+
);
439+
CREATE TEXT SEARCH DICTIONARY hunspell_invalid_3 (
440+
Template=ispell,
441+
DictFile=hunspell_sample_num,
442+
AffFile=ispell_sample
443+
);
444+
CREATE TEXT SEARCH DICTIONARY hunspell_err (
445+
Template=ispell,
446+
DictFile=hunspell_sample_num,
447+
AffFile=hunspell_sample_long
448+
);
449+
ERROR: invalid affix alias "302,301,202,303"
416450
-- Synonym dictionary
417451
CREATE TEXT SEARCH DICTIONARY synonym (
418452
Template=synonym,

src/test/regress/sql/tsdicts.sql

+37
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,43 @@ SELECT ts_lexize('hunspell_num', 'footballklubber');
101101
SELECT ts_lexize('hunspell_num', 'ballyklubber');
102102
SELECT ts_lexize('hunspell_num', 'footballyklubber');
103103

104+
-- Test suitability of affix and dict files
105+
CREATE TEXT SEARCH DICTIONARY hunspell_err (
106+
Template=ispell,
107+
DictFile=ispell_sample,
108+
AffFile=hunspell_sample_long
109+
);
110+
111+
CREATE TEXT SEARCH DICTIONARY hunspell_err (
112+
Template=ispell,
113+
DictFile=ispell_sample,
114+
AffFile=hunspell_sample_num
115+
);
116+
117+
CREATE TEXT SEARCH DICTIONARY hunspell_invalid_1 (
118+
Template=ispell,
119+
DictFile=hunspell_sample_long,
120+
AffFile=ispell_sample
121+
);
122+
123+
CREATE TEXT SEARCH DICTIONARY hunspell_invalid_2 (
124+
Template=ispell,
125+
DictFile=hunspell_sample_long,
126+
AffFile=hunspell_sample_num
127+
);
128+
129+
CREATE TEXT SEARCH DICTIONARY hunspell_invalid_3 (
130+
Template=ispell,
131+
DictFile=hunspell_sample_num,
132+
AffFile=ispell_sample
133+
);
134+
135+
CREATE TEXT SEARCH DICTIONARY hunspell_err (
136+
Template=ispell,
137+
DictFile=hunspell_sample_num,
138+
AffFile=hunspell_sample_long
139+
);
140+
104141
-- Synonym dictionary
105142
CREATE TEXT SEARCH DICTIONARY synonym (
106143
Template=synonym,

0 commit comments

Comments
 (0)