11extern crate alloc;
22
3-
43use alloc:: format;
5- use alloc:: string:: { String } ;
4+ use alloc:: string:: String ;
65use alloc:: vec:: Vec ;
76use core:: ffi:: c_int;
87use core:: slice;
@@ -34,7 +33,8 @@ fn powersync_validate_checkpoint_impl(
3433 let db = ctx. db_handle ( ) ;
3534
3635 // language=SQLite
37- let statement = db. prepare_v2 ( "WITH
36+ let statement = db. prepare_v2 (
37+ "WITH
3838bucket_list(bucket, lower_op_id, checksum) AS (
3939 SELECT
4040 json_extract(json_each.value, '$.bucket') as bucket,
@@ -57,22 +57,25 @@ FROM bucket_list
5757 bucket_list.bucket = oplog.bucket AND
5858 oplog.op_id <= CAST(json_extract(?1, '$.last_op_id') as INTEGER) AND
5959 oplog.op_id > bucket_list.lower_op_id
60- GROUP BY bucket_list.bucket" ) ?;
60+ GROUP BY bucket_list.bucket" ,
61+ ) ?;
6162
6263 statement. bind_text ( 1 , data, sqlite:: Destructor :: STATIC ) ?;
6364
6465 let mut failures: Vec < String > = alloc:: vec![ ] ;
6566
6667 while statement. step ( ) ? == ResultCode :: ROW {
6768 let name = statement. column_text ( 0 ) ?;
69+ // checksums with column_int are wrapped to i32 by SQLite
6870 let add_checksum = statement. column_int ( 1 ) ?;
6971 let oplog_checksum = statement. column_int ( 2 ) ?;
7072 let _count = statement. column_int ( 3 ) ?;
7173 let _last_op_id = statement. column_int64 ( 4 ) ?;
7274 let _last_applied_op = statement. column_int64 ( 5 ) ?;
7375 let expected_checksum = statement. column_int ( 6 ) ?;
7476
75- let checksum = oplog_checksum + add_checksum;
77+ // wrapping add is like +, but safely overflows
78+ let checksum = oplog_checksum. wrapping_add ( add_checksum) ;
7679
7780 if checksum != expected_checksum {
7881 failures. push ( String :: from ( name) ) ;
@@ -87,7 +90,11 @@ GROUP BY bucket_list.bucket")?;
8790 Ok ( json:: to_string ( & result) ?)
8891}
8992
90- create_sqlite_text_fn ! ( powersync_validate_checkpoint, powersync_validate_checkpoint_impl, "powersync_validate_checkpoint" ) ;
93+ create_sqlite_text_fn ! (
94+ powersync_validate_checkpoint,
95+ powersync_validate_checkpoint_impl,
96+ "powersync_validate_checkpoint"
97+ ) ;
9198
9299pub fn register ( db : * mut sqlite:: sqlite3 ) -> Result < ( ) , ResultCode > {
93100 db. create_function_v2 (
@@ -103,5 +110,3 @@ pub fn register(db: *mut sqlite::sqlite3) -> Result<(), ResultCode> {
103110
104111 Ok ( ( ) )
105112}
106-
107-
0 commit comments