if( ix>=(sqlite3_uint64)LLONG_MAX ){
/* Get ix into signed i64 range. */
ix -= (sqlite3_uint64)LLONG_MAX;
- smBase += LLONG_MAX * smStep;
+ /* With 2's complement ALU, this next can be 1 step, but is split into
+ * 2 for UBSAN's satisfaction (and hypothetical 1's complement ALUs.) */
+ smBase += (LLONG_MAX/2) * smStep;
+ smBase += (LLONG_MAX - LLONG_MAX/2) * smStep;
+ }
+ /* Under UBSAN (or on 1's complement machines), must do this last term
+ * in steps to avoid the dreaded (and harmless) signed multiply overlow. */
+ if( ix>=2 ){
+ sqlite3_int64 ix2 = (sqlite3_int64)ix/2;
+ smBase += ix2*smStep;
+ ix -= ix2;
}
return smBase + ((sqlite3_int64)ix)*smStep;
}
** given initialized iBase, iTerm and iStep values. Sequence is
** initialized per given isReversing. Other members are computed.
*/
-void setupSequence( SequenceSpec *pss ){
+static void setupSequence( SequenceSpec *pss ){
pss->uSeqIndexMax = 0;
pss->isNotEOF = 0;
+ int bSameSigns = (pss->iBase < 0)==(pss->iTerm < 0);
if( pss->iTerm < pss->iBase ){
- sqlite3_uint64 nuspan = (sqlite3_uint64)(pss->iBase-pss->iTerm);
+ sqlite3_uint64 nuspan = 0;
+ if( bSameSigns ){
+ nuspan = (sqlite3_uint64)(pss->iBase - pss->iTerm);
+ }else{
+ /* Under UBSAN (or on 1's complement machines), must do this in steps.
+ * In this clause, iBase>=0 and iTerm<0 . */
+ nuspan = 1;
+ nuspan += pss->iBase;
+ nuspan += -(pss->iTerm+1);
+ }
if( pss->iStep<0 ){
pss->isNotEOF = 1;
if( nuspan==ULONG_MAX ){
}
}
}else if( pss->iTerm > pss->iBase ){
- sqlite3_uint64 puspan = (sqlite3_uint64)(pss->iTerm-pss->iBase);
+ sqlite3_uint64 puspan = 0;
+ if( bSameSigns ){
+ puspan = (sqlite3_uint64)(pss->iTerm - pss->iBase);
+ }else{
+ /* Under UBSAN (or on 1's complement machines), must do this in steps.
+ * In this clause, iTerm>=0 and iBase<0 . */
+ puspan = 1;
+ puspan += pss->iTerm;
+ puspan += -(pss->iBase+1);
+ }
if( pss->iStep>0 ){
pss->isNotEOF = 1;
pss->uSeqIndexMax = puspan/pss->iStep;
** Leave its state to either yield next value or be at EOF.
** Return whether there is a next value, or 0 at EOF.
*/
-int progressSequence( SequenceSpec *pss ){
+static int progressSequence( SequenceSpec *pss ){
if( !pss->isNotEOF ) return 0;
if( pss->isReversing ){
if( pss->uSeqIndexNow > 0 ){
}
/*
-** Return the rowid for the current row. In this implementation, the
-** first row returned is assigned rowid value 1, and each subsequent
-** row a value 1 more than that of the previous.
+** Return the rowid for the current row, logically equivalent to n+1 where
+** "n" is the ascending integer in the aforesaid production definition.
*/
static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
series_cursor *pCur = (series_cursor*)cur;
- *pRowid = ((sqlite3_int64)pCur->ss.uSeqIndexNow + 1);
+ sqlite3_uint64 n = pCur->ss.uSeqIndexNow;
+ *pRowid = (sqlite3_int64)((n<0xffffffffffffffff)? n+1 : 0);
return SQLITE_OK;
}
-C As\sevidenced\sby\s[forum:/forumpost/f3f546025a|forum\spost\sf3f546025a],\sthe\nnew\sRIGHT\sJOIN\srelated\srestriction\son\sthe\spush-down\soptimization\simplemented\nby\s[da3fba18742b6e0b]\salso\sneeds\sto\sapply\sto\sthe\sautomatic\sindex\n(a.k.a.\shash-join)\soptimization\sand\sto\sthe\sBloom\sfilter\soptimization.\nComputation\sof\sthe\srestriction\sis\snow\nmoved\sinto\sthe\ssqlite3ExprIsSingleTableConstraint()\sroutine.
-D 2023-05-15T02:06:35.229
+C Make\sgenerate_series()\scorrect\son\sones\scomplement\sALUs\sand\sacceptable\sto\sUBSAN.
+D 2023-05-15T03:48:48.598
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c
F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c
F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946
-F ext/misc/series.c 37d27377684d3ea14177540d2f2767163197611eaba905790c96abd4ab552cd3
+F ext/misc/series.c 387381db0fe3329e9ea7d46df87c98c25b95c39b11fa9999a24dcbe6b2779e52
F ext/misc/sha1.c 4011aef176616872b2a0d5bccf0ecfb1f7ce3fe5c3d107f3a8e949d8e1e3f08d
F ext/misc/shathree.c 543af7ce71d391cd3a9ab6924a6a1124efc63211fd0f2e240dc4b56077ba88ac
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P c5da16551619718bf649c517515261706843e11e131f0b99e1fd6927d0f7e238
-R 19526b8216d20a0f1da8af3749d5cbdb
-U drh
-Z 784c6c524217b70137b2b3907aa60981
+P 4902015dcf3869f08d9986e422faa231d9218a5e0fc59ba8df0f407e4eb3d605
+R 17307900605f9e82492f51004e8218f7
+U larrybr
+Z be454f9c1f92315357662a45ba347767
# Remove this line to create a well-formed Fossil manifest.