From f28fb1ac85765c2a6c3acffbf69571341e9db1d2 Mon Sep 17 00:00:00 2001 From: Andrey Rachitskiy Date: Thu, 10 Sep 2026 18:08:27 +0500 Subject: [PATCH] Reject out-of-range Hunspell AF alias counts. NIImportOOAffixes() parsed the AF alias count with atoi(). A value such as 4294967297 overflows a 32-bit int to 1 and was accepted when the wrapped count matched the number of alias lines. Parse the count with strtol() and reject overflow, non-numeric input, and values that cannot be incremented to reserve the empty flag-set slot. Author: Andrey Rachitskiy --- src/backend/tsearch/Makefile | 3 ++- src/backend/tsearch/dicts/hunspell_afoverflow.affix | 5 +++++ src/backend/tsearch/dicts/hunspell_afoverflow.dict | 1 + src/backend/tsearch/spell.c | 11 +++++++++-- src/test/regress/expected/tsdicts.out | 7 +++++++ src/test/regress/sql/tsdicts.sql | 7 +++++++ 6 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 src/backend/tsearch/dicts/hunspell_afoverflow.affix create mode 100644 src/backend/tsearch/dicts/hunspell_afoverflow.dict diff --git a/src/backend/tsearch/Makefile b/src/backend/tsearch/Makefile index 4a436150109..64d4ad0b0d8 100644 --- a/src/backend/tsearch/Makefile +++ b/src/backend/tsearch/Makefile @@ -18,7 +18,8 @@ DICTFILES=synonym_sample.syn thesaurus_sample.ths \ hunspell_sample.affix \ ispell_sample.affix ispell_sample.dict \ hunspell_sample_long.affix hunspell_sample_long.dict \ - hunspell_sample_num.affix hunspell_sample_num.dict + hunspell_sample_num.affix hunspell_sample_num.dict \ + hunspell_afoverflow.affix hunspell_afoverflow.dict # Local paths to dictionaries files DICTFILES_PATH=$(addprefix dicts/,$(DICTFILES)) diff --git a/src/backend/tsearch/dicts/hunspell_afoverflow.affix b/src/backend/tsearch/dicts/hunspell_afoverflow.affix new file mode 100644 index 00000000000..64a3cd2b89c --- /dev/null +++ b/src/backend/tsearch/dicts/hunspell_afoverflow.affix @@ -0,0 +1,5 @@ +SET UTF-8 +AF 4294967297 +AF A +PFX A Y 1 +PFX A 0 re . diff --git a/src/backend/tsearch/dicts/hunspell_afoverflow.dict b/src/backend/tsearch/dicts/hunspell_afoverflow.dict new file mode 100644 index 00000000000..dcf874345d9 --- /dev/null +++ b/src/backend/tsearch/dicts/hunspell_afoverflow.dict @@ -0,0 +1 @@ +book/1 diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c index f2c6e064218..b2624eba62b 100644 --- a/src/backend/tsearch/spell.c +++ b/src/backend/tsearch/spell.c @@ -1382,13 +1382,20 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename) /* First line is the number of aliases */ if (!Conf->useFlagAliases) { + char *end; + long naliases; + Conf->useFlagAliases = true; - naffix = atoi(sflag); - if (naffix <= 0) + errno = 0; + naliases = strtol(sflag, &end, 10); + if (sflag == end || errno == ERANGE || + naliases <= 0 || naliases >= INT_MAX) ereport(ERROR, (errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("invalid number of flag vector aliases"))); + naffix = (int) naliases; + /* Also reserve place for empty flag set */ naffix++; diff --git a/src/test/regress/expected/tsdicts.out b/src/test/regress/expected/tsdicts.out index 0bbf2ff4ca2..01a873b682c 100644 --- a/src/test/regress/expected/tsdicts.out +++ b/src/test/regress/expected/tsdicts.out @@ -447,6 +447,13 @@ CREATE TEXT SEARCH DICTIONARY hunspell_err ( AffFile=hunspell_sample_long ); ERROR: invalid affix alias "302,301,202,303" +-- Over-wide AF alias count (4294967297) must be rejected. +CREATE TEXT SEARCH DICTIONARY hunspell_afoverflow ( + Template=ispell, + DictFile=hunspell_afoverflow, + AffFile=hunspell_afoverflow +); +ERROR: invalid number of flag vector aliases -- Synonym dictionary CREATE TEXT SEARCH DICTIONARY synonym ( Template=synonym, diff --git a/src/test/regress/sql/tsdicts.sql b/src/test/regress/sql/tsdicts.sql index cf08410bb2d..d2dd76698b0 100644 --- a/src/test/regress/sql/tsdicts.sql +++ b/src/test/regress/sql/tsdicts.sql @@ -138,6 +138,13 @@ CREATE TEXT SEARCH DICTIONARY hunspell_err ( AffFile=hunspell_sample_long ); +-- Over-wide AF alias count (4294967297) must be rejected. +CREATE TEXT SEARCH DICTIONARY hunspell_afoverflow ( + Template=ispell, + DictFile=hunspell_afoverflow, + AffFile=hunspell_afoverflow +); + -- Synonym dictionary CREATE TEXT SEARCH DICTIONARY synonym ( Template=synonym, -- 2.53.0