1
1
extern crate alloc;
2
2
3
-
4
3
use alloc:: format;
5
- use alloc:: string:: { String } ;
4
+ use alloc:: string:: String ;
6
5
use alloc:: vec:: Vec ;
7
6
use core:: ffi:: c_int;
8
7
use core:: slice;
@@ -34,7 +33,8 @@ fn powersync_validate_checkpoint_impl(
34
33
let db = ctx. db_handle ( ) ;
35
34
36
35
// language=SQLite
37
- let statement = db. prepare_v2 ( "WITH
36
+ let statement = db. prepare_v2 (
37
+ "WITH
38
38
bucket_list(bucket, lower_op_id, checksum) AS (
39
39
SELECT
40
40
json_extract(json_each.value, '$.bucket') as bucket,
@@ -57,22 +57,25 @@ FROM bucket_list
57
57
bucket_list.bucket = oplog.bucket AND
58
58
oplog.op_id <= CAST(json_extract(?1, '$.last_op_id') as INTEGER) AND
59
59
oplog.op_id > bucket_list.lower_op_id
60
- GROUP BY bucket_list.bucket" ) ?;
60
+ GROUP BY bucket_list.bucket" ,
61
+ ) ?;
61
62
62
63
statement. bind_text ( 1 , data, sqlite:: Destructor :: STATIC ) ?;
63
64
64
65
let mut failures: Vec < String > = alloc:: vec![ ] ;
65
66
66
67
while statement. step ( ) ? == ResultCode :: ROW {
67
68
let name = statement. column_text ( 0 ) ?;
69
+ // checksums with column_int are wrapped to i32 by SQLite
68
70
let add_checksum = statement. column_int ( 1 ) ?;
69
71
let oplog_checksum = statement. column_int ( 2 ) ?;
70
72
let _count = statement. column_int ( 3 ) ?;
71
73
let _last_op_id = statement. column_int64 ( 4 ) ?;
72
74
let _last_applied_op = statement. column_int64 ( 5 ) ?;
73
75
let expected_checksum = statement. column_int ( 6 ) ?;
74
76
75
- let checksum = oplog_checksum + add_checksum;
77
+ // wrapping add is like +, but safely overflows
78
+ let checksum = oplog_checksum. wrapping_add ( add_checksum) ;
76
79
77
80
if checksum != expected_checksum {
78
81
failures. push ( String :: from ( name) ) ;
@@ -87,7 +90,11 @@ GROUP BY bucket_list.bucket")?;
87
90
Ok ( json:: to_string ( & result) ?)
88
91
}
89
92
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
+ ) ;
91
98
92
99
pub fn register ( db : * mut sqlite:: sqlite3 ) -> Result < ( ) , ResultCode > {
93
100
db. create_function_v2 (
@@ -103,5 +110,3 @@ pub fn register(db: *mut sqlite::sqlite3) -> Result<(), ResultCode> {
103
110
104
111
Ok ( ( ) )
105
112
}
106
-
107
-
0 commit comments