webtorrent/parse-torrent

Roundtripping torrent files through parse-torrent modifes announce lists

mmgoodnow opened this issue · 0 comments

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.