@@ -880,7 +880,14 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
880880 sqlite3 * db = ctx -> pBt -> db ;
881881 const char * db_filename = sqlite3_db_filename (db , "main" );
882882 char * migrated_db_filename = sqlite3_mprintf ("%s-migrated" , db_filename );
883+ char * query_sqlite_master = "SELECT count(*) from sqlite_master;" ;
884+ char * pragma_hmac_off = "PRAGMA cipher_use_hmac = OFF;" ;
885+ char * pragma_4k_kdf_iter = "PRAGMA kdf_iter = 4000;" ;
883886 char * key = ctx -> read_ctx -> pass ;
887+ int upgrade_1x_format = 0 ;
888+ int upgrade_4k_format = 0 ;
889+ sqlite3 * test ;
890+ char * err = 0 ;
884891 static const unsigned char aCopy [] = {
885892 BTREE_SCHEMA_VERSION , 1 , /* Add one to the old schema cookie */
886893 BTREE_DEFAULT_CACHE_SIZE , 0 , /* Preserve the default page cache size */
@@ -890,15 +897,49 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
890897 };
891898
892899 if (db_filename ){
900+
893901 char * attach_command = sqlite3_mprintf ("ATTACH DATABASE '%s-migrated' as migrate KEY '%s';" ,
894902 db_filename , key );
903+
904+ int rc = sqlcipher_check_connection (db_filename , key , "" );
905+ if (rc == SQLITE_OK ){
906+ // no upgrade required
907+ goto exit ;
908+ }
909+
910+ // check for 1x format
911+ rc = sqlcipher_check_connection (db_filename , key , pragma_hmac_off );
912+ if (rc == SQLITE_OK ) {
913+ upgrade_1x_format = 1 ;
914+ }
915+
916+ // check for 4k format
917+ rc = sqlcipher_check_connection (db_filename , key , pragma_4k_kdf_iter );
918+ if (rc == SQLITE_OK ) {
919+ upgrade_4k_format = 1 ;
920+ }
921+
922+ // check both 1x and 4k together
923+ char * pragma_1x_and_4k = sqlite3_mprintf ("%s%s" , pragma_hmac_off ,
924+ pragma_4k_kdf_iter );
925+ rc = sqlcipher_check_connection (db_filename , key , pragma_1x_and_4k );
926+ sqlite3_free (pragma_1x_and_4k );
927+ if (rc == SQLITE_OK ) {
928+ upgrade_1x_format = 1 ;
929+ upgrade_4k_format = 1 ;
930+ }
931+
895932 const char * commands [] = {
896- "PRAGMA kdf_iter = '4000';" ,
933+ upgrade_4k_format == 1 ? pragma_4k_kdf_iter : "" ,
934+ upgrade_1x_format == 1 ? pragma_hmac_off : "" ,
897935 attach_command ,
898936 "SELECT sqlcipher_export('migrate');" ,
899937 };
900938 for (command_idx = 0 ; command_idx < ArraySize (commands ); command_idx ++ ){
901939 const char * command = commands [command_idx ];
940+ if (strcmp (command , "" ) == 0 ){
941+ continue ;
942+ }
902943 rc = sqlite3_exec (db , command , NULL , NULL , NULL );
903944 if (rc != SQLITE_OK ){
904945 break ;
@@ -978,5 +1019,47 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
9781019 return rc ;
9791020}
9801021
1022+ int sqlcipher_check_connection (char * filename , char * key , char * sql ) {
1023+ int rc ;
1024+ sqlite3 * db ;
1025+ char * errMsg ;
1026+ sqlite3_stmt * statement ;
1027+ int status = SQLITE_ERROR ;
1028+ char * query_sqlite_master = "SELECT count(*) FROM sqlite_master;" ;
1029+
1030+ rc = sqlite3_open (filename , & db );
1031+ if (rc != SQLITE_OK ){
1032+ goto cleanup ;
1033+ }
1034+ rc = sqlite3_key (db , key , (int )strlen (key ));
1035+ if (rc != SQLITE_OK ){
1036+ goto cleanup ;
1037+ }
1038+ rc = sqlite3_exec (db , sql , NULL , NULL , NULL );
1039+ if (rc != SQLITE_OK ){
1040+ goto cleanup ;
1041+ }
1042+ rc = sqlite3_prepare (db , query_sqlite_master , -1 , & statement , NULL );
1043+ if (rc != SQLITE_OK ){
1044+ goto cleanup ;
1045+ }
1046+ if (sqlite3_step (statement ) == SQLITE_ROW ){
1047+ status = SQLITE_OK ;
1048+ }
1049+ goto cleanup ;
1050+
1051+ cleanup :
1052+ if (statement ){
1053+ sqlite3_finalize (statement );
1054+ }
1055+ if (db ){
1056+ sqlite3_close (db );
1057+ }
1058+
1059+ exit :
1060+ return status ;
1061+
1062+ }
1063+
9811064#endif
9821065/* END SQLCIPHER */
0 commit comments