static BEncodedDictionary DecodeDictionary(RawReader reader, bool strictDecoding) { int read; BEncodedString oldkey = null; var dictionary = new BEncodedDictionary(); while ((read = reader.ReadByte()) != -1 && read != 'e') { BEncodedString key = DecodeString(reader, read - '0'); // keys have to be BEncoded strings if (oldkey != null && oldkey.CompareTo(key) > 0) { if (strictDecoding) { throw new BEncodingException( $"Illegal BEncodedDictionary. The attributes are not ordered correctly. Old key: {oldkey}, New key: {key}"); } } oldkey = key; BEncodedValue value = Decode(reader); // the value is a BEncoded value dictionary.Add(key, value); } if (read != 'e') // remove the trailing 'e' { throw new BEncodingException("Invalid data found. Aborting"); } return(dictionary); }
static BEncodedDictionary DecodeDictionary(ref ReadOnlySpan <byte> buffer, bool strictDecoding) { BEncodedString oldkey = null; var dictionary = new BEncodedDictionary(); while (buffer.Length > 0) { if (buffer[0] == 'e') { buffer = buffer.Slice(1); return(dictionary); } var key = DecodeString(ref buffer); if (oldkey != null && oldkey.CompareTo(key) > 0) { if (strictDecoding) { throw new BEncodingException( $"Illegal BEncodedDictionary. The attributes are not ordered correctly. Old key: {oldkey}, New key: {key}"); } } oldkey = key; var value = Decode(ref buffer, strictDecoding); dictionary.Add(key, value); } throw new BEncodingException("Invalid data found. Aborting"); }
public static (BEncodedDictionary torrent, ReadOnlyMemory <byte> infohash) DecodeTorrent(ref ReadOnlySpan <byte> buffer) { if (buffer[0] != 'd') { throw new BEncodingException($"The root value was not a BEncodedDictionary"); } buffer = buffer.Slice(1); ReadOnlySpan <byte> infoBuffer = default; BEncodedString oldkey = null; Memory <byte> infoHash = null; var dictionary = new BEncodedDictionary(); while (buffer.Length > 0) { if (buffer[0] == 'e') { buffer = buffer.Slice(1); return(dictionary, infoHash); } var key = DecodeString(ref buffer); if (oldkey != null && oldkey.CompareTo(key) > 0) { throw new BEncodingException($"Illegal BEncodedDictionary. The attributes are not ordered correctly. Old key: {oldkey}, New key: {key}"); } if (InfoKey.Equals(key)) { infoBuffer = buffer; } oldkey = key; var value = Decode(ref buffer, false); dictionary.Add(key, value); if (InfoKey.Equals(key)) { using var hasher = SHA1.Create(); infoHash = new byte[hasher.HashSize / 8]; if (!hasher.TryComputeHash(infoBuffer.Slice(0, infoBuffer.Length - buffer.Length), infoHash.Span, out int written) || written != infoHash.Length) { throw new BEncodingException("Could not compute infohash for torrent."); } } } throw new BEncodingException("Invalid data found. Aborting"); }
static BEncodedDictionary DecodeDictionary(Stream reader, bool strictDecoding) { int read; BEncodedString oldkey = null; var dictionary = new BEncodedDictionary(); while ((read = reader.ReadByte()) != -1) { if (read == 'e') { return(dictionary); } if (read < '0' || read > '9') { throw new BEncodingException("Invalid key length"); } var key = DecodeString(reader, read - '0'); // keys have to be BEncoded strings if (oldkey != null && oldkey.CompareTo(key) > 0) { if (strictDecoding) { throw new BEncodingException( $"Illegal BEncodedDictionary. The attributes are not ordered correctly. Old key: {oldkey}, New key: {key}"); } } oldkey = key; var value = Decode(reader, strictDecoding); // the value is a BEncoded value dictionary.Add(key, value); } throw new BEncodingException("Invalid data found. Aborting"); }