Program: 142185
Project: 142185
Buggy source:
public static void migrateData(Context c,CommCareApp app,UserKeyRecord incomingSandbox,byte[] unwrappedOldKey,UserKeyRecord newSandbox,byte[] unwrappedNewKey) throws IOException {
  Logger.log(AndroidLogger.TYPE_MAINTENANCE,"String_Node_Str" + newSandbox.getUsername());
  File oldDb=c.getDatabasePath(CommCareUserOpenHelper.getDbName(incomingSandbox.getUuid()));
  File newDb=c.getDatabasePath(CommCareUserOpenHelper.getDbName(newSandbox.getUuid()));
  if (newDb.exists()) {
    if (!newDb.delete()) {
      throw new IOException("String_Node_Str" + newDb.getAbsolutePath() + "String_Node_Str");
    }
  }
  FileUtil.copyFile(oldDb,newDb);
  Logger.log(AndroidLogger.TYPE_MAINTENANCE,"String_Node_Str");
  String oldKeyEncoded=getSqlCipherEncodedKey(unwrappedOldKey);
  String newKeyEncoded=getSqlCipherEncodedKey(unwrappedNewKey);
  SQLiteDatabase rawDbHandle=SQLiteDatabase.openDatabase(newDb.getAbsolutePath(),oldKeyEncoded,null,SQLiteDatabase.OPEN_READWRITE);
  rawDbHandle.execSQL("String_Node_Str" + oldKeyEncoded + "String_Node_Str");
  rawDbHandle.execSQL("String_Node_Str" + newKeyEncoded + "String_Node_Str");
  rawDbHandle.close();
  Logger.log(AndroidLogger.TYPE_MAINTENANCE,"String_Node_Str");
  final SQLiteDatabase db=new CommCareUserOpenHelper(CommCareApplication._(),newSandbox.getUuid()).getWritableDatabase(newKeyEncoded);
  try {
    DbHelper dbh=new DbHelper(c){
      @Override public SQLiteDatabase getHandle(){
        return db;
      }
    }
;
    SqlStorage<DeviceReportRecord> reports=new SqlStorage<DeviceReportRecord>(DeviceReportRecord.STORAGE_KEY,DeviceReportRecord.class,dbh);
    for (    DeviceReportRecord r : reports) {
      File oldPath=new File(r.getFilePath());
      File newPath=FileUtil.getNewFileLocation(oldPath,newSandbox.getUuid(),true);
      FileUtil.copyFile(oldPath,newPath);
    }
    Logger.log(AndroidLogger.TYPE_MAINTENANCE,"String_Node_Str");
    ContentResolver cr=c.getContentResolver();
    SqlStorage<FormRecord> formRecords=new SqlStorage<FormRecord>(FormRecord.STORAGE_KEY,FormRecord.class,dbh);
    for (    FormRecord record : formRecords) {
      Uri instanceURI=record.getInstanceURI();
      if (instanceURI == null) {
        continue;
      }
      ContentValues values=new ContentValues();
      File oldForm;
{
        Cursor oldRecord=cr.query(instanceURI,new String[]{InstanceColumns.INSTANCE_FILE_PATH,InstanceColumns.DISPLAY_NAME,InstanceColumns.SUBMISSION_URI,InstanceColumns.JR_FORM_ID,InstanceColumns.STATUS,InstanceColumns.CAN_EDIT_WHEN_COMPLETE,InstanceColumns.LAST_STATUS_CHANGE_DATE,InstanceColumns.DISPLAY_SUBTEXT},null,null,null);
        if (!oldRecord.moveToFirst()) {
          throw new IOException("String_Node_Str" + instanceURI.toString());
        }
        values.put(InstanceColumns.DISPLAY_NAME,oldRecord.getString(oldRecord.getColumnIndex(InstanceColumns.DISPLAY_NAME)));
        values.put(InstanceColumns.SUBMISSION_URI,oldRecord.getString(oldRecord.getColumnIndex(InstanceColumns.SUBMISSION_URI)));
        values.put(InstanceColumns.JR_FORM_ID,oldRecord.getString(oldRecord.getColumnIndex(InstanceColumns.JR_FORM_ID)));
        values.put(InstanceColumns.STATUS,oldRecord.getString(oldRecord.getColumnIndex(InstanceColumns.STATUS)));
        values.put(InstanceColumns.CAN_EDIT_WHEN_COMPLETE,oldRecord.getString(oldRecord.getColumnIndex(InstanceColumns.CAN_EDIT_WHEN_COMPLETE)));
        values.put(InstanceColumns.LAST_STATUS_CHANGE_DATE,oldRecord.getLong(oldRecord.getColumnIndex(InstanceColumns.LAST_STATUS_CHANGE_DATE)));
        values.put(InstanceColumns.DISPLAY_SUBTEXT,oldRecord.getString(oldRecord.getColumnIndex(InstanceColumns.DISPLAY_SUBTEXT)));
        oldForm=new File(oldRecord.getString(oldRecord.getColumnIndex(InstanceColumns.INSTANCE_FILE_PATH)));
        oldRecord.close();
      }
      File oldFolder=oldForm.getParentFile();
      File newFolder=FileUtil.getNewFileLocation(oldFolder,newSandbox.getUuid(),true);
      FileUtil.copyFileDeep(oldFolder,newFolder);
      File newfileToWrite=null;
      for (      File f : newFolder.listFiles()) {
        if (f.getName().equals(oldForm.getName())) {
          newfileToWrite=f;
        }
      }
      values.put(InstanceColumns.INSTANCE_FILE_PATH,newfileToWrite.getAbsolutePath());
      Uri newUri=cr.insert(InstanceColumns.CONTENT_URI,values);
      record=record.updateStatus(newUri.toString(),record.getStatus());
      formRecords.write(record);
    }
  }
  finally {
    db.close();
  }
  Logger.log(AndroidLogger.TYPE_MAINTENANCE,"String_Node_Str");
  SqlStorage<UserKeyRecord> ukr=app.getStorage(UserKeyRecord.class);
  SQLiteDatabase ukrdb=ukr.getAccessLock();
  ukrdb.beginTransaction();
  try {
    incomingSandbox.setType(UserKeyRecord.TYPE_PENDING_DELETE);
    ukr.write(incomingSandbox);
    newSandbox.setType(UserKeyRecord.TYPE_NORMAL);
    ukr.write(newSandbox);
    ukrdb.setTransactionSuccessful();
  }
  finally {
    ukrdb.endTransaction();
  }
}

Fixed version (ground truth):
public static void migrateData(Context c,CommCareApp app,UserKeyRecord incomingSandbox,byte[] unwrappedOldKey,UserKeyRecord newSandbox,byte[] unwrappedNewKey) throws IOException {
  Logger.log(AndroidLogger.TYPE_MAINTENANCE,"String_Node_Str" + newSandbox.getUsername());
  File oldDb=c.getDatabasePath(CommCareUserOpenHelper.getDbName(incomingSandbox.getUuid()));
  File newDb=c.getDatabasePath(CommCareUserOpenHelper.getDbName(newSandbox.getUuid()));
  if (newDb.exists()) {
    if (!newDb.delete()) {
      throw new IOException("String_Node_Str" + newDb.getAbsolutePath() + "String_Node_Str");
    }
  }
  FileUtil.copyFile(oldDb,newDb);
  Logger.log(AndroidLogger.TYPE_MAINTENANCE,"String_Node_Str");
  String oldKeyEncoded=getSqlCipherEncodedKey(unwrappedOldKey);
  String newKeyEncoded=getSqlCipherEncodedKey(unwrappedNewKey);
  SQLiteDatabase rawDbHandle=SQLiteDatabase.openDatabase(newDb.getAbsolutePath(),oldKeyEncoded,null,SQLiteDatabase.OPEN_READWRITE);
  rawDbHandle.execSQL("String_Node_Str" + oldKeyEncoded + "String_Node_Str");
  rawDbHandle.execSQL("String_Node_Str" + newKeyEncoded + "String_Node_Str");
  rawDbHandle.close();
  Logger.log(AndroidLogger.TYPE_MAINTENANCE,"String_Node_Str");
  final SQLiteDatabase db=new CommCareUserOpenHelper(CommCareApplication._(),newSandbox.getUuid()).getWritableDatabase(newKeyEncoded);
  try {
    DbHelper dbh=new DbHelper(c){
      @Override public SQLiteDatabase getHandle(){
        return db;
      }
    }
;
    SqlStorage<DeviceReportRecord> reports=new SqlStorage<DeviceReportRecord>(DeviceReportRecord.STORAGE_KEY,DeviceReportRecord.class,dbh);
    for (    DeviceReportRecord r : reports) {
      File oldPath=new File(r.getFilePath());
      File newPath=FileUtil.getNewFileLocation(oldPath,newSandbox.getUuid(),true);
      FileUtil.copyFile(oldPath,newPath);
    }
    Logger.log(AndroidLogger.TYPE_MAINTENANCE,"String_Node_Str");
    ContentResolver cr=c.getContentResolver();
    SqlStorage<FormRecord> formRecords=new SqlStorage<FormRecord>(FormRecord.STORAGE_KEY,FormRecord.class,dbh);
    for (    FormRecord record : formRecords) {
      Uri instanceURI=record.getInstanceURI();
      if (instanceURI == null) {
        continue;
      }
      ContentValues values=new ContentValues();
      File oldForm;
{
        Cursor oldRecord=cr.query(instanceURI,new String[]{InstanceColumns.INSTANCE_FILE_PATH,InstanceColumns.DISPLAY_NAME,InstanceColumns.SUBMISSION_URI,InstanceColumns.JR_FORM_ID,InstanceColumns.STATUS,InstanceColumns.CAN_EDIT_WHEN_COMPLETE,InstanceColumns.LAST_STATUS_CHANGE_DATE,InstanceColumns.DISPLAY_SUBTEXT},null,null,null);
        if (!oldRecord.moveToFirst()) {
          throw new IOException("String_Node_Str" + instanceURI.toString());
        }
        values.put(InstanceColumns.DISPLAY_NAME,oldRecord.getString(oldRecord.getColumnIndex(InstanceColumns.DISPLAY_NAME)));
        values.put(InstanceColumns.SUBMISSION_URI,oldRecord.getString(oldRecord.getColumnIndex(InstanceColumns.SUBMISSION_URI)));
        values.put(InstanceColumns.JR_FORM_ID,oldRecord.getString(oldRecord.getColumnIndex(InstanceColumns.JR_FORM_ID)));
        values.put(InstanceColumns.STATUS,oldRecord.getString(oldRecord.getColumnIndex(InstanceColumns.STATUS)));
        values.put(InstanceColumns.CAN_EDIT_WHEN_COMPLETE,oldRecord.getString(oldRecord.getColumnIndex(InstanceColumns.CAN_EDIT_WHEN_COMPLETE)));
        values.put(InstanceColumns.LAST_STATUS_CHANGE_DATE,oldRecord.getLong(oldRecord.getColumnIndex(InstanceColumns.LAST_STATUS_CHANGE_DATE)));
        values.put(InstanceColumns.DISPLAY_SUBTEXT,oldRecord.getString(oldRecord.getColumnIndex(InstanceColumns.DISPLAY_SUBTEXT)));
        oldForm=new File(oldRecord.getString(oldRecord.getColumnIndex(InstanceColumns.INSTANCE_FILE_PATH)));
        oldRecord.close();
      }
      File oldFolder=oldForm.getParentFile();
      File newFolder=FileUtil.getNewFileLocation(oldFolder,newSandbox.getUuid(),true);
      FileUtil.copyFileDeep(oldFolder,newFolder);
      File newfileToWrite=null;
      for (      File f : newFolder.listFiles()) {
        if (f.getName().equals(oldForm.getName())) {
          newfileToWrite=f;
        }
      }
      values.put(InstanceColumns.INSTANCE_FILE_PATH,newfileToWrite.getAbsolutePath());
      Uri newUri=cr.insert(InstanceColumns.CONTENT_URI,values);
      record=record.updateInstanceAndStatus(newUri.toString(),record.getStatus());
      formRecords.write(record);
    }
  }
  finally {
    db.close();
  }
  Logger.log(AndroidLogger.TYPE_MAINTENANCE,"String_Node_Str");
  SqlStorage<UserKeyRecord> ukr=app.getStorage(UserKeyRecord.class);
  SQLiteDatabase ukrdb=ukr.getAccessLock();
  ukrdb.beginTransaction();
  try {
    incomingSandbox.setType(UserKeyRecord.TYPE_PENDING_DELETE);
    ukr.write(incomingSandbox);
    newSandbox.setType(UserKeyRecord.TYPE_NORMAL);
    ukr.write(newSandbox);
    ukrdb.setTransactionSuccessful();
  }
  finally {
    ukrdb.endTransaction();
  }
}