Skip to content

Roundtripping torrent files through parse-torrent modifes announce lists #152

@mmgoodnow

Description

@mmgoodnow

What version of this package are you using?
11.0.8 (current version)

What operating system, Node.js, and npm version?
All versions of node

What happened?

decodeTorrentFile flattens the announce-list array, but the nesting inside announce-list has semantic meaning, per BEP 0012. Then encodeTorrentFile has to re-nest but it only has a shallow list so it has to just assume that each announce url had its own top-level element in the list, which is not necessarily the case.

The following script has a minimal reproduction.

import parseTorrent, {toTorrentFile} from 'parse-torrent';
const minimalBencodedMetafile = "d8:announce20:https://example1.com13:announce-listll20:https://example1.com20:https://example2.comee10:created by13:mktorrent 1.14:infod6:lengthi0e4:name7:foo.txt12:piece lengthi32768e6:pieces0:e8:url-listl12:example3.comee"
const decoded = await parseTorrent(Buffer.from(minimalBencodedMetafile));
const encoded = toTorrentFile(decoded);
const roundtripped = Buffer.from(encoded).toString('ascii');
console.log(minimalBencodedMetafile);
console.log(roundtripped);

The output of this script shows that there is an extra el in between the two announce urls after being roundtripped through parse-torrent, changing the shape of the announce tree from [[1, 2]] to [[1], [2]]. The relevant code is below

parse-torrent/index.js

Lines 155 to 160 in 4c0d4ae

if (Array.isArray(torrent['announce-list']) && torrent['announce-list'].length > 0) {
torrent['announce-list'].forEach(urls => {
urls.forEach(url => {
result.announce.push(arr2text(url))
})
})

parse-torrent/index.js

Lines 210 to 213 in 4c0d4ae

torrent['announce-list'] = (parsed.announce || []).map(url => {
if (!torrent.announce) torrent.announce = url
url = text2arr(url)
return [url]

What did you expect to happen?

I expected parse-torrent not to lose fidelity on the shape of the announce-list.

Are you willing to submit a pull request to fix this bug?

I plan to vendor this package into my app and fix it there. I am open to upstreaming the fix, although my fix is likely to be a breaking change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions