@@ -1361,14 +1361,24 @@ fn authorize_migration_writer(context: rusqlite::hooks::AuthContext<'_>) -> Auth
13611361 pragma_name,
13621362 pragma_value,
13631363 }
1364- if !is_migration_read_pragma ( pragma_name, pragma_value)
1364+ if !is_allowed_migration_pragma ( pragma_name, pragma_value)
13651365 ) {
13661366 Authorization :: Deny
13671367 } else {
13681368 Authorization :: Allow
13691369 }
13701370}
13711371
1372+ fn is_allowed_migration_pragma ( pragma_name : & str , pragma_value : Option < & str > ) -> bool {
1373+ is_migration_read_pragma ( pragma_name, pragma_value)
1374+ || matches ! (
1375+ pragma_value,
1376+ Some ( value)
1377+ if pragma_name. eq_ignore_ascii_case( "auto_vacuum" )
1378+ && ( value. eq_ignore_ascii_case( "incremental" ) || value == "2" )
1379+ )
1380+ }
1381+
13721382fn is_migration_read_pragma ( pragma_name : & str , pragma_value : Option < & str > ) -> bool {
13731383 const ARGUMENT_SAFE : & [ & str ] = & [
13741384 "foreign_key_check" ,
@@ -1745,6 +1755,21 @@ mod tests {
17451755 assert ! ( matches!( error, MigrationSqlError :: AuthorityDenied ( _) ) ) ;
17461756 }
17471757
1758+ #[ test]
1759+ fn writer_actor_allows_only_incremental_auto_vacuum_configuration ( ) {
1760+ let fixture = fixture ( 'a' , 'a' ) ;
1761+ let channel = MigrationSqlHandle :: attach ( & fixture. writer , & fixture. readers ) . unwrap ( ) ;
1762+
1763+ channel
1764+ . execute_batch ( "PRAGMA auto_vacuum = INCREMENTAL" . to_owned ( ) )
1765+ . expect ( "repeat safe incremental auto-vacuum" ) ;
1766+ let error = channel
1767+ . execute_batch ( "PRAGMA auto_vacuum = NONE" . to_owned ( ) )
1768+ . unwrap_err ( ) ;
1769+
1770+ assert ! ( matches!( error, MigrationSqlError :: Sqlite { .. } ) ) ;
1771+ }
1772+
17481773 #[ test]
17491774 fn ordinary_transaction_cannot_request_an_unbounded_schema_step ( ) {
17501775 let fixture = fixture ( 'a' , 'a' ) ;
0 commit comments