Skip to content

Ambiguous binary range key representation in /store/ranges #268

Description

@liaodn

Description

While inspecting the startKey and endKey values returned by /store/ranges, we found that the current text representation of binary keys is ambiguous.

The current implementation uses a mixed format:

  • Printable bytes are emitted directly as characters.
  • Non-printable bytes are emitted as 0xHH.
  • There is no delimiter or escaping rule between these representations.

As a result, different byte sequences can be encoded into exactly the same string.

For example:

Raw bytes:  00 00 00
API output: 0x000x000x00

A different byte sequence produces the same output:

Raw bytes:  30 78 30 30 00 00
Meaning:    ASCII string "0x00" followed by two 00 bytes
API output: 0x000x000x00

Although the original keys are different, their API representations are identical.

This prevents consumers from:

  • Reconstructing the original key bytes.
  • Reliably distinguishing range boundaries.
  • Detecting gaps or overlaps between ranges based on the API response.

The "0x00" portion consists of four valid printable characters and does not mean that the client sent a NUL byte. The trailing 00 bytes are separators used by the internal key format. The ambiguity is introduced by the endpoint's encoding logic, not by MQTT or client input.

Expected Behavior

Binary keys should use a unique and reversible text encoding. For example, each byte can be represented by exactly two lowercase hexadecimal characters:

00 00 00          -> 000000
30 78 30 30 00 00 -> 307830300000

Existing boundary semantics should remain unchanged:

  • An unset boundary returns null.
  • An empty byte sequence returns "".

Suggested Solution

Use Java HexFormat to encode the complete byte array consistently:

private String toHex(ByteString bs) {
    return HexFormat.of().formatHex(bs.toByteArray());
}

This changes the existing textual representation of startKey and endKey, so consumers relying on the old format will need to adapt.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions