Mark Info::infohash
as potentially lossy
`Info::infohash` will discard fields not present in the `Info` struct, and can thus produce an erronous infohash. To try to prevent this function from being called in those circumstances, rename it to `Info::infohash_lossy`, and add a comment explaining why it is dangerous. Embarassingly, `Info::infohash` was called in `TorrentSummary::from_input`, and thus transitively by the torrent show subcommand, where it is definitely not safe, since torrent show is intended to be used with arbitrary torrents. This is now fixed. There was also a build failure caused by a cache issue, so change the cache keys to invalidate the caches. type: fixed
This commit is contained in:
parent
dbb0eac96d
commit
7ca9ed62d5
6
.github/workflows/build.yaml
vendored
6
.github/workflows/build.yaml
vendored
|
@ -49,19 +49,19 @@ jobs:
|
|||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.cargo/registry
|
||||
key: ${{ runner.os }}-cargo-registry
|
||||
key: ${{ runner.os }}-cargo-registry-v0
|
||||
|
||||
- name: Cache cargo index
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.cargo/git
|
||||
key: ${{ runner.os }}-cargo-index
|
||||
key: ${{ runner.os }}-cargo-index-v0
|
||||
|
||||
- name: Cache cargo build
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: target
|
||||
key: ${{ runner.os }}-cargo-build-target
|
||||
key: ${{ runner.os }}-cargo-build-target-v0
|
||||
|
||||
- name: Install Stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
|
|
11
src/info.rs
11
src/info.rs
|
@ -34,7 +34,16 @@ impl Info {
|
|||
self.mode.content_size()
|
||||
}
|
||||
|
||||
pub(crate) fn infohash(&self) -> Result<Infohash> {
|
||||
/// This function is potentially lossy. If an arbitrary torrent info
|
||||
/// dictionary is deserialized into an `Info` struct, extra fields not present
|
||||
/// on the struct will be discarded. If `infohash_lossy` is then called on
|
||||
/// the resultant struct, those fields will not contribute to the infohash,
|
||||
/// which will thus be different from that of the original torrent.
|
||||
///
|
||||
/// It will not be lossy if no extra fields are present in the original
|
||||
/// torrent. So, it is safe to call on torrents that have just been created
|
||||
/// and are still in memory, and thus are known to have no extra fields.
|
||||
pub(crate) fn infohash_lossy(&self) -> Result<Infohash> {
|
||||
let encoded = bendy::serde::ser::to_bytes(self).context(error::InfoSerialize)?;
|
||||
Ok(Infohash::from_bencoded_info_dict(&encoded))
|
||||
}
|
||||
|
|
|
@ -9,8 +9,9 @@ pub(crate) struct MagnetLink {
|
|||
}
|
||||
|
||||
impl MagnetLink {
|
||||
pub(crate) fn from_metainfo(metainfo: &Metainfo) -> Result<MagnetLink> {
|
||||
let mut link = Self::with_infohash(metainfo.infohash()?);
|
||||
/// See `Info::infohash_lossy` for details on when this function is lossy.
|
||||
pub(crate) fn from_metainfo_lossy(metainfo: &Metainfo) -> Result<MagnetLink> {
|
||||
let mut link = Self::with_infohash(metainfo.infohash_lossy()?);
|
||||
|
||||
link.set_name(metainfo.info.name.clone());
|
||||
|
||||
|
|
|
@ -114,8 +114,9 @@ impl Metainfo {
|
|||
})
|
||||
}
|
||||
|
||||
pub(crate) fn infohash(&self) -> Result<Infohash> {
|
||||
self.info.infohash()
|
||||
/// See `Info::infohash_lossy` for details on when this function is lossy.
|
||||
pub(crate) fn infohash_lossy(&self) -> Result<Infohash> {
|
||||
self.info.infohash_lossy()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -454,11 +454,13 @@ impl Create {
|
|||
}
|
||||
|
||||
if self.show {
|
||||
TorrentSummary::from_metainfo(metainfo.clone())?.write(env)?;
|
||||
// We just created this torrent, so no extra fields have been discarded.
|
||||
TorrentSummary::from_metainfo_lossy(metainfo.clone())?.write(env)?;
|
||||
}
|
||||
|
||||
if self.print_magnet_link {
|
||||
let mut link = MagnetLink::from_metainfo(&metainfo)?;
|
||||
// We just created this torrent, so no extra fields have been discarded.
|
||||
let mut link = MagnetLink::from_metainfo_lossy(&metainfo)?;
|
||||
for peer in self.peers {
|
||||
link.add_peer(peer);
|
||||
}
|
||||
|
|
|
@ -15,17 +15,20 @@ impl TorrentSummary {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_metainfo(metainfo: Metainfo) -> Result<Self> {
|
||||
/// See `Info::infohash_lossy` for details on when this function is lossy.
|
||||
pub(crate) fn from_metainfo_lossy(metainfo: Metainfo) -> Result<Self> {
|
||||
let bytes = metainfo.serialize()?;
|
||||
let size = Bytes(bytes.len().into_u64());
|
||||
let infohash = metainfo.infohash()?;
|
||||
let infohash = metainfo.infohash_lossy()?;
|
||||
Ok(Self::new(metainfo, infohash, size))
|
||||
}
|
||||
|
||||
pub(crate) fn from_input(input: &Input) -> Result<Self> {
|
||||
let metainfo = Metainfo::from_input(input)?;
|
||||
let infohash = Infohash::from_input(input)?;
|
||||
let size = Bytes(input.data().len().into_u64());
|
||||
|
||||
Ok(Self::from_metainfo(metainfo)?)
|
||||
Ok(Self::new(metainfo, infohash, size))
|
||||
}
|
||||
|
||||
pub(crate) fn write(&self, env: &mut Env) -> Result<()> {
|
||||
|
|
Loading…
Reference in New Issue
Block a user