From 5f8b6a782de3d9fc89c071ecafdf9e375f89a0ad Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 21 Sep 2026 11:14:14 +0000 Subject: [PATCH] Fix truncation of 64-bit integer values passed to the fts3 snippet() function. Report [bugs:/info/2026-09-21T02:41:49Z | 2026-09-21T02:41:49Z]. FossilOrigin-Name: b0919c9687f01240c89171e1607816b603450e5bed37c468860298b2ccc11a81 --- ext/fts3/fts3.c | 11 +++++++---- ext/fts3/fts3_snippet.c | 5 ++--- manifest | 18 +++++++++--------- manifest.uuid | 2 +- test/fts3snippet.test | 24 ++++++++++++++++++++++++ 5 files changed, 43 insertions(+), 17 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 12b2cba469..ada95abd2d 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -3728,8 +3728,8 @@ static void fts3SnippetFunc( const char *zStart = ""; const char *zEnd = ""; const char *zEllipsis = "..."; - int iCol = -1; - int nToken = 15; /* Default number of tokens in snippet */ + i64 iCol = -1; + i64 nToken = 15; /* Default number of tokens in snippet */ /* There must be at least one argument passed to this function (otherwise ** the non-overloaded version would have been called instead of this one). @@ -3745,9 +3745,9 @@ static void fts3SnippetFunc( pTab = (Fts3Table *)pCsr->base.pVtab; switch( nVal ){ - case 6: nToken = sqlite3_value_int(apVal[5]); + case 6: nToken = sqlite3_value_int64(apVal[5]); /* no break */ deliberate_fall_through - case 5: iCol = sqlite3_value_int(apVal[4]); + case 5: iCol = sqlite3_value_int64(apVal[4]); /* no break */ deliberate_fall_through case 4: zEllipsis = (const char*)sqlite3_value_text(apVal[3]); /* no break */ deliberate_fall_through @@ -3760,6 +3760,9 @@ static void fts3SnippetFunc( }else if( nToken==0 || iCol>=pTab->nColumn ){ sqlite3_result_text(pContext, "", -1, SQLITE_STATIC); }else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){ + if( iCol<0 ) iCol = -1; + if( nToken<-64 ) nToken = -64; + if( nToken>64 ) nToken = 64; sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken); } } diff --git a/ext/fts3/fts3_snippet.c b/ext/fts3/fts3_snippet.c index 1144a4d37f..8ff8c18f39 100644 --- a/ext/fts3/fts3_snippet.c +++ b/ext/fts3/fts3_snippet.c @@ -1471,9 +1471,8 @@ void sqlite3Fts3Snippet( return; } - /* Limit the snippet length to 64 tokens. */ - if( nToken<-64 ) nToken = -64; - if( nToken>+64 ) nToken = +64; + /* The snippet length should already have been limited to 64 tokens. */ + assert( nToken>=-64 && nToken<=64 ); for(nSnippet=1; 1; nSnippet++){ diff --git a/manifest b/manifest index ea2a3967d8..ae732d3b85 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\stest\scases\sfor\sthe\ssqlite3.oo1.Stmt.get()\soverloads\swhich\stake\sboth\sa\sclient-specified\stype\sID\sand\san\sarray\sor\sobject\starget. -D 2026-09-21T07:29:41.487 +C Fix\struncation\sof\s64-bit\sinteger\svalues\spassed\sto\sthe\sfts3\ssnippet()\sfunction.\sReport\s[bugs:/info/2026-09-21T02:41:49Z\s|\s2026-09-21T02:41:49Z]. +D 2026-09-21T11:14:14.628 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -80,7 +80,7 @@ F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c F ext/fts3/README.syntax b72477722e9b4fe43f8403227d790a1c94221bfad15c27863a4b36d1052e892b F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 2e56a160b5da3c274b06a7a59b0757ad6f29ddf5cff0ab9a440dcd935cfe9569 +F ext/fts3/fts3.c f04765cdc086bcfe36d6a603ae36590f32fc24ab94c0b3ce27e1bc1966303fc3 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h 277f32f304e82f4397fc2a74793c0a95318b7abb9670b519e4805a00946cbd9b F ext/fts3/fts3_aux.c c5d0a3726cf938070317f2e7620b69cd9dd81dc0e1d920d8ff52128a396ba3d6 @@ -89,7 +89,7 @@ F ext/fts3/fts3_hash.c d9dba473741445789330c7513d4f65737c92df23c3212784312931641 F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116 F ext/fts3/fts3_porter.c 024417020c57dd1ab39816f5fe6cf45222a857b78a1f6412f040ada1ceabd4ff -F ext/fts3/fts3_snippet.c 69d1e4011a3becbf179e62aadf40e78bb40818a3f705fbac25ba277c14df6df4 +F ext/fts3/fts3_snippet.c 0b4a4c7705ab93d2713961ec0c929b0ba6fed44e5ddf3f09048e60318071b4a2 F ext/fts3/fts3_term.c 6a96027ad364001432545fe43322b6af04ed28bb5619ec51af1f59d0710d6d69 F ext/fts3/fts3_test.c cc329471e573f95a6ea9fbca87e89dcfa1d355591c80172ffcd759ac521d25d8 F ext/fts3/fts3_tokenize_vtab.c 66eba6c2baa04b2b15e80d68341b8fd0b4d3831f6b2edb33916a2906ff2d4389 @@ -1216,7 +1216,7 @@ F test/fts3query.test 45806a302921b245a9dba5d85c9d51fb98b3f137eea6e6bf6eae4883e0 F test/fts3rank.test cd99bc83a3c923c8d52afd90d86979cf05fc41849f892faeac3988055ef37b99 F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0 F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e -F test/fts3snippet.test 86486f9c797aa1b81c7397d98fb7ec4e55dfca8724365fc415413dfa829ebc8a +F test/fts3snippet.test 453a2a42d44949ef4603f76197cdb31d6676574250fac04770f61f349b98166f F test/fts3snippet2.test 3e5c98b29af10b58a2555920a20488be94b58b3503841aca0cdcacdb153614ac F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca F test/fts3tok1.test a663f4cac22a9505400bc22aacb818d7055240409c28729669ea7d4cc2120d15 @@ -2221,8 +2221,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P aadf42e021fc55d457836c7cda68f3d22dcaae72a7bbc105c3c727b3eb5c4657 -R 5f19445cdc85bcb9e032194fc9872608 -U stephan -Z 882f6aea4d00f4e9ed34a196e90e88a5 +P 24bddf2aff01962a35c42422e322c12582ea77e2c7ddd5f8754d12c454ce8a1d +R 0dca8303df31dd4bdc36b1ab4335fc7a +U dan +Z 5a14fcf0b658febd6f60e566c2e8f471 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9ed019a356..19f703f1e5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24bddf2aff01962a35c42422e322c12582ea77e2c7ddd5f8754d12c454ce8a1d +b0919c9687f01240c89171e1607816b603450e5bed37c468860298b2ccc11a81 diff --git a/test/fts3snippet.test b/test/fts3snippet.test index f6c88235ff..b1fd45fb7c 100644 --- a/test/fts3snippet.test +++ b/test/fts3snippet.test @@ -561,6 +561,22 @@ do_test 4.3 { }] } {64} +# The 6th argument to snippet() is the approximate number of tokens to +# use in the returned snippet. Test that this still works as expected +# (the absolute value is silently capped at 64) if the value passed in +# is too large to be represented as a 32-bit integer. +do_test 4.4 { + llength [db one { + SELECT snippet(t4, '', '', '', 0, 4294967297) FROM t4 WHERE t4 MATCH 'E' + }] +} {64} + +do_test 4.5 { + llength [db one { + SELECT snippet(t4, '', '', '', 0, -4294967297) FROM t4 WHERE t4 MATCH 'E' + }] +} {64} + #------------------------------------------------------------------------- # Request a snippet from a query with more than 64 phrases. # @@ -611,5 +627,13 @@ do_snip_test 6.2 two -1 5 {one {two} three A} do_snip_test 6.3 two 3 5 {one {two} three D} do_snip_test 6.4 two 4 5 {} +# The 5th argument to snippet() is a column index. A negative value means +# any column may be used, and a value greater than or equal to the number +# of columns in the table means there is no such column and the result is +# an empty string. Test that this is still true if the value passed in is +# too large to be represented as a 32-bit integer. +do_snip_test 6.5 two -4294967293 5 {one {two} three A} +do_snip_test 6.6 two 4294967299 5 {} + set sqlite_fts3_enable_parentheses 0 finish_test