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

Lines changed: 22 additions & 3 deletions
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

Lines changed: 34 additions & 0 deletions
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

Lines changed: 37 additions & 0 deletions
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)
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