P3KI / bendy

A rust library for encoding and decoding bencode with enforced cannonicalization rules.
BSD 3-Clause "New" or "Revised" License
77 stars 14 forks source link

NestingTooDeep with any torrent file #26

Closed ghost closed 5 years ago

ghost commented 5 years ago

I'm trying to parse torrent files, I've tried a dozen and with any of them i get the NestingTooDeep error, here's my code:

use bendy::decoding::FromBencode;
use bendy::encoding::AsString;
use std::fs::File;
use std::io::prelude::Read;

fn main() {
    let mut fc = Vec::new(); // file content
    let mut file = File::open("test.torrent").expect("Unable to read file.");
    file.read_to_end(&mut fc).expect("Unable to read");
    let example = AsString::from_bencode(&fc).expect("Unable to bendecode");
    println!("{:#?}", example.0);
}
ghost commented 5 years ago

sorry, just found the examples directory

thequux commented 5 years ago

I'm glad that you managed to solve your problem, but in case somebody else comes along needing help:

AsString resolved to AsString<Vec<u8>>, which is a vector of bytes represented as a byte string (e.g. 3:foo). Thus, the call to from_bencode expected the encoded data to only contain a single string.

BitTorrent files have a dictionary as their top-level element, which means that the first token the parser found was a d. Ideally, we'd return a type error here; however, the state tracker (which validates that the bencoded data is well-formed) refuses to open a new nesting level because when it was created, AsString<Vec<u8>> told it that it should never see any nesting at all. Thus, it immediately returns a NestingTooDeep error before AsString has a chance to realize that it saw a dictionary instead of a byte string.

I hope that this helps whoever might be digging through old bugs looking for an answer to their problem!