Package dev.relism.flash.http2.hpack
Class HpackIntegers
java.lang.Object
dev.relism.flash.http2.hpack.HpackIntegers
RFC 7541 §5.1 prefix-coded integer encode/decode. An Overflow safety (
RFC 7541 places no upper bound on the number of continuation octets — a hostile peer can encode
an arbitrarily large integer (conceptually up to 2^64 and beyond) in a handful of bytes.
N-bit prefix holds values
0..2^N-2 directly; the sentinel 2^N-1 means "the real value is at least this large, keep
reading continuation octets" — each contributes 7 bits, low-to-high, with the high bit as a
continue flag.
Overflow safety (HPACK bomb)
RFC 7541 places no upper bound on the number of continuation octets — a hostile peer can encode
an arbitrarily large integer (conceptually up to 2^64 and beyond) in a handful of bytes. decode(byte[], int, int, int) rejects any integer needing more than MAX_CONTINUATION_OCTETS continuation
octets, and independently rejects one that would exceed Integer.MAX_VALUE even within
that octet budget — belt-and-suspenders, since with the octet cap in place the second check is
not expected to ever fire on a real input. Both throw the preallocated Http2Exception.COMPRESSION_ERROR singleton — zero allocation on this hot rejection path (see
that exception's own Javadoc for why reusing a singleton here is safe).-
Method Summary
Modifier and TypeMethodDescriptionstatic longdecode(byte[] buf, int pos, int limit, int prefixBits) Decodes a prefix-coded integer starting atbuf[pos], where the lowprefixBitsbits ofbuf[pos]carry the prefix (any higher bits — e.g. a representation's leading flag bits — are the caller's concern and are masked off here).static voidencode(ByteWriter out, int prefixByteFlags, int prefixBits, int value) Encodesvalueas a prefix-coded integer intoprefixByteFlags | encoded value, writing intoout.
-
Method Details
-
decode
public static long decode(byte[] buf, int pos, int limit, int prefixBits) Decodes a prefix-coded integer starting atbuf[pos], where the lowprefixBitsbits ofbuf[pos]carry the prefix (any higher bits — e.g. a representation's leading flag bits — are the caller's concern and are masked off here).limitis the exclusive end of the region this integer may read from (typically the end of the current HPACK block) — reading past it means a truncated/malformed encoding, not "need more input", since by the time this runs the whole block is already contiguous in memory (RFC 9113 §6.10: CONTINUATION frames are never interleaved with other frames).- Returns:
Pairs.pack(int, int)(value,newPos) — the decoded value in the high 32 bits, the position just past the last consumed byte in the low 32 bits- Throws:
Http2Exception-COMPRESSION_ERRORon truncation, on exceedingMAX_CONTINUATION_OCTETS, or on a value that would exceedInteger.MAX_VALUE
-
encode
Encodesvalueas a prefix-coded integer intoprefixByteFlags | encoded value, writing intoout.prefixByteFlagscarries whatever high bits the representation needs (e.g.0x80for an Indexed Header Field) already shifted into position — this method only ever sets the lowprefixBitsbits of the first byte.
-