`save_cached_bundle` wrote in place with `std::fs::write`, which truncates the file before the first byte of the replacement is written. Any kill in that window leaves an empty or half-written `bundle_tokens.json`, which parses as nothing, so the tokens are gone and the next launch pays a full live extraction: a ~7 MB bundle.js fetch behind a 45s timeout, up to three attempts. The window is not rare. `refresh_bundle_if_changed` rewrites the whole file on every launch that finds the version unchanged, purely to touch `fetched_at`, so a warm cache is destroyed and rebuilt each time the app starts. The bytes now land in a sibling temp file that is flushed and renamed over the target, so a reader sees either the previous cache or the new one. The replacement is owner-only where writing in place left it at whatever the umask allowed; these are app-level values scraped from a public bundle rather than user credentials, so that is tidiness rather than a fix for a vulnerability.
48 lines
1018 B
TOML
48 lines
1018 B
TOML
[package]
|
|
name = "qbz-qobuz"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
license.workspace = true
|
|
description = "Qobuz API client for QBZ"
|
|
|
|
[dependencies]
|
|
qbz-models = { path = "../qbz-models" }
|
|
qbz-cmaf = { path = "../qbz-cmaf" }
|
|
|
|
# Async
|
|
tokio = { workspace = true }
|
|
futures-util = { workspace = true }
|
|
|
|
# HTTP
|
|
reqwest = { workspace = true }
|
|
|
|
# Serialization
|
|
serde = { workspace = true }
|
|
serde_json = { workspace = true }
|
|
|
|
# Crypto (for Qobuz auth)
|
|
md-5 = { workspace = true }
|
|
base64 = { workspace = true }
|
|
|
|
# Time
|
|
chrono = { workspace = true }
|
|
|
|
# Filesystem (bundle-token cache location, atomic replacement of it)
|
|
dirs = "6"
|
|
tempfile = "3"
|
|
|
|
# Regex
|
|
regex = { workspace = true }
|
|
|
|
# Logging
|
|
log = { workspace = true }
|
|
|
|
# Error handling
|
|
thiserror = { workspace = true }
|
|
anyhow = { workspace = true }
|
|
|
|
[dev-dependencies]
|
|
# Used only by examples/lyrics_probe.rs (read-only live probe of the lyrics
|
|
# endpoint): loads the saved OAuth token / credentials for login.
|
|
qbz-credentials = { path = "../qbz-credentials" }
|