Thanks for reporting the bug,
I reproduced this and verified the bug locally.
Attached patch adds a check to ensure the entire token is consumed (skipping trailing whitespace) after strtol(), matching the existing error-handling style in the same function. With the patch applied, the example above correctly fails with invalid affix flag "1x".I tested this manually: the malformed case above now errors, a normal valid case (COMPOUNDFLAG 1) still works as before, and the full regression suite passes (240/240). I haven't added a dedicated regression test for this yet, because I was not sure if my patch was correct or in the right direction. I'd be happy to implement changes and regression tests suggested.
Regards,
Samriddha
The following bug has been logged on the website:
Bug reference: 19704
Logged by: Qifan Liu
Email address: imchifan@163.com
PostgreSQL version: 18.6
Operating system: Linux/amd64
Description:
Creating an ispell text-search dictionary from an affix file containing
COMPOUNDFLAG 1x and FLAG num succeeds. PostgreSQL interprets the malformed
compound flag as numeric flag 1. This can cause subtle text-search behavior
in dictionaries installed from malformed affix files.
Steps to reproduce
------------------
Run as an operating-system user allowed to create files in PostgreSQL's
tsearch_data directory.
set -eu
sd=$(pg_config --sharedir)/tsearch_data
n=pg_numeric_compoundflag
printf 'SET UTF-8\nCOMPOUNDFLAG 1x\nFLAG num\n' > "$sd/$n.affix"
printf '2\nfoo/1\nbar/1\n' > "$sd/$n.dict"
psql -X -v ON_ERROR_STOP=1 -At postgres <<SQL
CREATE TEXT SEARCH DICTIONARY $n (
TEMPLATE = ispell,
DictFile = $n,
AffFile = $n
);
SELECT coalesce(array_to_string(ts_lexize('$n', 'foo'), ','), 'NULL');
SQL
Actual result
-------------
Dictionary creation succeeds, and the malformed COMPOUNDFLAG value is
treated as flag 1:
CREATE TEXT SEARCH DICTIONARY
foo
Expected result
---------------
Dictionary creation should fail with a configuration-file error because "1x"
is not a valid numeric flag. PostgreSQL should not accept the prefix "1",
discard the trailing "x", and subsequently lexize the entry as flag 1.
Additional information
----------------------
The issue was reproduced on PostgreSQL 20devel, PostgreSQL 18.6, and
PostgreSQL 17.11.
Inference: numeric flag conversion validates the converted prefix or range
but does not verify that conversion consumed the entire token.