diff --git a/internal/chatlog/wechat/service.go b/internal/chatlog/wechat/service.go index 680f13e..e14810f 100644 --- a/internal/chatlog/wechat/service.go +++ b/internal/chatlog/wechat/service.go @@ -311,9 +311,8 @@ func (s *Service) DecryptDBFile(dbFile string) error { outputFile.Write(data) } if s.conf.GetWalEnabled() { - if err := s.syncWalFiles(dbFile, output); err != nil { - log.Debug().Err(err).Msgf("failed to sync wal files for %s", dbFile) - } + // Remove WAL files if they exist to prevent SQLite from reading encrypted WALs + s.removeWalFiles(output) } return nil } @@ -324,14 +323,24 @@ func (s *Service) DecryptDBFile(dbFile string) error { log.Debug().Msgf("Decrypted %s to %s", dbFile, output) if s.conf.GetWalEnabled() { - if err := s.syncWalFiles(dbFile, output); err != nil { - log.Debug().Err(err).Msgf("failed to sync wal files for %s", dbFile) - } + // Remove WAL files if they exist to prevent SQLite from reading encrypted WALs + s.removeWalFiles(output) } return nil } +func (s *Service) removeWalFiles(dbFile string) { + walFile := dbFile + "-wal" + shmFile := dbFile + "-shm" + if err := os.Remove(walFile); err != nil && !os.IsNotExist(err) { + log.Debug().Err(err).Msgf("failed to remove wal file %s", walFile) + } + if err := os.Remove(shmFile); err != nil && !os.IsNotExist(err) { + log.Debug().Err(err).Msgf("failed to remove shm file %s", shmFile) + } +} + func (s *Service) getDebounceTime() time.Duration { debounce := s.conf.GetAutoDecryptDebounce() if debounce <= 0 { @@ -405,65 +414,6 @@ func isWalFile(path string) bool { return strings.HasSuffix(path, ".db-wal") || strings.HasSuffix(path, ".db-shm") } -func (s *Service) syncWalFiles(dbFile, output string) error { - walSrc := dbFile + "-wal" - walDst := output + "-wal" - if err := syncAuxFile(walSrc, walDst); err != nil { - return err - } - shmSrc := dbFile + "-shm" - shmDst := output + "-shm" - if err := syncAuxFile(shmSrc, shmDst); err != nil { - return err - } - return nil -} - -func syncAuxFile(src, dst string) error { - if _, err := os.Stat(src); err != nil { - if os.IsNotExist(err) { - if err := os.Remove(dst); err != nil && !os.IsNotExist(err) { - return err - } - return nil - } - return err - } - if err := util.PrepareDir(filepath.Dir(dst)); err != nil { - return err - } - return copyFileAtomic(src, dst) -} - -func copyFileAtomic(src, dst string) error { - input, err := os.Open(src) - if err != nil { - return err - } - defer input.Close() - - temp := dst + ".tmp" - output, err := os.Create(temp) - if err != nil { - return err - } - if _, err := io.Copy(output, input); err != nil { - output.Close() - os.Remove(temp) - return err - } - if err := output.Sync(); err != nil { - output.Close() - os.Remove(temp) - return err - } - if err := output.Close(); err != nil { - os.Remove(temp) - return err - } - return os.Rename(temp, dst) -} - func (s *Service) DecryptDBFiles() error { dbGroup, err := filemonitor.NewFileGroup("wechat", s.conf.GetDataDir(), `.*\.db$`, []string{"fts"}) if err != nil { @@ -663,9 +613,8 @@ func (s *Service) IncrementalDecryptDBFile(dbFile string) (bool, error) { s.mutex.Unlock() } - if err := s.syncWalFiles(dbFile, output); err != nil { - return true, err - } + // Remove WAL files if they exist to prevent SQLite from reading encrypted WALs + s.removeWalFiles(output) if applied { return true, nil diff --git a/internal/wechatdb/datasource/dbm/dbm.go b/internal/wechatdb/datasource/dbm/dbm.go index 77bc5b1..c55ed85 100644 --- a/internal/wechatdb/datasource/dbm/dbm.go +++ b/internal/wechatdb/datasource/dbm/dbm.go @@ -131,12 +131,6 @@ func (d *DBManager) OpenDB(path string) (*sql.DB, error) { log.Err(err).Msgf("获取临时拷贝文件 %s 失败", path) return nil, err } - if d.walEnabled { - if err := d.syncWalFiles(path, tempPath); err != nil { - log.Err(err).Msgf("同步 WAL 文件失败: %s", path) - return nil, err - } - } } db, err = sql.Open("sqlite3", tempPath) if err != nil { @@ -187,58 +181,6 @@ func (d *DBManager) Close() error { return d.fm.Stop() } -func (d *DBManager) syncWalFiles(dbPath, tempPath string) error { - if err := syncAuxFile(dbPath+"-wal", tempPath+"-wal"); err != nil { - return err - } - if err := syncAuxFile(dbPath+"-shm", tempPath+"-shm"); err != nil { - return err - } - return nil -} - -func syncAuxFile(src, dst string) error { - if _, err := os.Stat(src); err != nil { - if os.IsNotExist(err) { - if err := os.Remove(dst); err != nil && !os.IsNotExist(err) { - return err - } - return nil - } - return err - } - return copyFileAtomic(src, dst) -} - -func copyFileAtomic(src, dst string) error { - input, err := os.Open(src) - if err != nil { - return err - } - defer input.Close() - - temp := dst + ".tmp" - output, err := os.Create(temp) - if err != nil { - return err - } - if _, err := io.Copy(output, input); err != nil { - output.Close() - os.Remove(temp) - return err - } - if err := output.Sync(); err != nil { - output.Close() - os.Remove(temp) - return err - } - if err := output.Close(); err != nil { - os.Remove(temp) - return err - } - return os.Rename(temp, dst) -} - func normalizeDBPath(path string) string { if strings.HasSuffix(path, "-wal") || strings.HasSuffix(path, "-shm") { return strings.TrimSuffix(strings.TrimSuffix(path, "-wal"), "-shm")