mirror of
https://github.com/EFForg/rayhunter.git
synced 2026-06-01 02:33:35 -07:00
Fix malformed QMDL store writes
Fix https://github.com/EFForg/rayhunter/issues/199 Fix https://github.com/EFForg/rayhunter/issues/151 rayhunter updates manifest files using write **without truncation**. This means that if the new manifest is shorter than the old one, trailing bytes of the old data will persist in the new file. Switch over to atomic file writes so that this bug is fixed + rayhunter behaves correctly if it is killed mid-write. https://github.com/EFForg/rayhunter/pull/182 could be reverted as it seems to mostly be a workaround.
This commit is contained in:
committed by
Will Greenberg
parent
3c0716c877
commit
58f0071864
+18
-16
@@ -120,19 +120,17 @@ impl RecordingStore {
|
||||
fs::create_dir_all(&path)
|
||||
.await
|
||||
.map_err(RecordingStoreError::OpenDirError)?;
|
||||
let mut manifest_file = File::create(&manifest_path)
|
||||
.await
|
||||
.map_err(RecordingStoreError::WriteManifestError)?;
|
||||
let empty_manifest = Manifest {
|
||||
entries: Vec::new(),
|
||||
|
||||
let mut store = RecordingStore {
|
||||
path: manifest_path,
|
||||
manifest: Manifest {
|
||||
entries: Vec::new()
|
||||
},
|
||||
current_entry: None,
|
||||
};
|
||||
let empty_manifest_contents =
|
||||
toml::to_string_pretty(&empty_manifest).expect("failed to serialize manifest");
|
||||
manifest_file
|
||||
.write_all(empty_manifest_contents.as_bytes())
|
||||
.await
|
||||
.map_err(RecordingStoreError::WriteManifestError)?;
|
||||
RecordingStore::load(path).await
|
||||
|
||||
store.write_manifest().await?;
|
||||
Ok(store)
|
||||
}
|
||||
|
||||
async fn read_manifest<P>(path: P) -> Result<Manifest, RecordingStoreError>
|
||||
@@ -240,17 +238,21 @@ impl RecordingStore {
|
||||
}
|
||||
|
||||
async fn write_manifest(&mut self) -> Result<(), RecordingStoreError> {
|
||||
let mut manifest_file = File::options()
|
||||
.write(true)
|
||||
.open(self.path.join("manifest.toml"))
|
||||
let tmp_path = self.path.join("manifest.toml.new");
|
||||
let mut manifest_tmp_file = File::create(&tmp_path)
|
||||
.await
|
||||
.map_err(RecordingStoreError::WriteManifestError)?;
|
||||
|
||||
let manifest_contents =
|
||||
toml::to_string_pretty(&self.manifest).expect("failed to serialize manifest");
|
||||
manifest_file
|
||||
manifest_tmp_file
|
||||
.write_all(manifest_contents.as_bytes())
|
||||
.await
|
||||
.map_err(RecordingStoreError::WriteManifestError)?;
|
||||
|
||||
fs::rename(tmp_path, self.path.join("manifest.toml")).await
|
||||
.map_err(RecordingStoreError::WriteManifestError)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user