Skip to content

It sorts dictionary entries incorrectly. #19

@issuefiler

Description

@issuefiler

Bug

bncode/bncode.js

Lines 370 to 372 in 704e8d5

function encodeDict (obj) {
var func = function (obj, pos) {
var keys = Object.keys(obj).sort()

     var keys = Object.keys(obj).sort()

This is not the correct way of sorting dictionary entries. The encoder is producing specification-incompliant octets that’ll be floating around in the wild, the network.


When you say “strings” in the context of Bencoding, you mean “binary strings,” or more specifically, “8-bit byte sequences.”

BEP 52 — The BitTorrent protocol specification version 2

Note that, in the context of bencoding, strings, including dictionary keys, are arbitrary byte sequences (uint8_t[]).

And Array.prototype.sort compares 16-bit units by default.

If compareFn is not supplied, all non-undefined array elements are sorted by converting them to strings and comparing strings in UTF-16 code units order.

The simple .sort() results in a different order (sorted_in_utf16) than the correct one (sorted_in_utf8). Observe:

const A = String.fromCodePoint(0xFF61);
const B = String.fromCodePoint(0x10002);
const sorted_in_utf8 = [A, B].sort((a, b) => Buffer.compare(Buffer.from(a), Buffer.from(b))); // [A, B]
const sorted_in_utf16 = [A, B].sort(); // [B, A]

The related issue

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions