anacrolix / torrent

Full-featured BitTorrent client package and utilities
Mozilla Public License 2.0
5.51k stars 622 forks source link

decode bencode string to `[20]byte` or `infohash.T` #952

Closed trim21 closed 3 months ago

trim21 commented 3 months ago

I'm trying to decode scrape response, which looks like this

type scrapeResponse struct {
    Files map[metainfo.Hash]scrapeResponseFile `bencode:"files"`
}

type scrapeResponseFile struct {
    Complete   int `bencode:"complete"`
    Downloaded int `bencode:"downloaded"`
    Incomplete int `bencode:"incomplete"`
}

can we support decoding bencode string to byte array with length check?

anacrolix commented 3 months ago

I would be surprised if it doesn't already support that. It seems reasonable to allow it to any type that can unmarshal from bytes, or has UnmarshalText or UnmarshalBytes. There's https://pkg.go.dev/github.com/anacrolix/torrent/bencode#Unmarshaler, but those other methods should be checked for byte strings.

trim21 commented 3 months ago

I would be surprised if it doesn't already support that

I'm pretty sure it doesn't

package main

import (
    "github.com/anacrolix/torrent/bencode"
    "github.com/anacrolix/torrent/metainfo"
    "github.com/samber/lo"
)

type scrapeResponse struct {
    Files map[metainfo.Hash]scrapeResponseFile `bencode:"files"`
}

type scrapeResponseFile struct {
    Complete   int `bencode:"complete"`
    Downloaded int `bencode:"downloaded"`
    Incomplete int `bencode:"incomplete"`
}

func main() {
    var s scrapeResponse

    lo.Must0(bencode.Unmarshal([]byte("d5:filesd20:\x05a~F\xfd{c\xd1`\xb8\xd9\x89\xceM\xb9t\x1d\\\x0b\xded9:completedi1e10:downloadedi1eeee"), &s))
}
panic: reflect.Value.Convert: value of type string cannot be converted to type infohash.T [recovered]
    panic: reflect.Value.Convert: value of type string cannot be converted to type infohash.T
anacrolix commented 3 months ago

Thanks. Would you like to have a crack at a unit test/implementation?

trim21 commented 3 months ago

I'll try

anacrolix commented 3 months ago

Thanks for submitting this. The fix was not easy.

anacrolix commented 3 months ago

I forgot the tests, I've force pushed those, see the referenced commit.