{"record":{"id":"2fbe2c467de00c3d","repo":"basecamp/fizzy","slug":"invalid-additional-info-info","errorCode":null,"errorMessage":"Invalid additional info: #{info}","messagePattern":"Invalid additional info: #(.+?)","errorType":"exception","errorClass":"ActionPack::WebAuthn::InvalidCborError","httpStatus":null,"severity":"error","filePath":"lib/action_pack/web_authn/cbor_decoder.rb","lineNumber":237,"sourceCode":"        mantissa == 0 ? Float::INFINITY : Float::NAN\n      else\n        Math.ldexp(mantissa + 1024, exponent - 25)\n      end\n\n      sign == 1 ? -value : value\n    end\n\n    def read_argument\n      case info = additional_info\n      when SIMPLE_VALUE_RANGE then info\n      when SINGLE_BYTE_VALUE_FOLLOWS then read_byte\n      when TWO_BYTE_VALUE_FOLLOWS then read_bytes(2).pack(\"C*\").unpack1(\"n\")\n      when FOUR_BYTE_VALUE_FOLLOWS then read_bytes(4).pack(\"C*\").unpack1(\"N\")\n      when EIGHT_BYTE_VALUE_FOLLOWS then read_bytes(8).pack(\"C*\").unpack1(\"Q>\")\n      when RESERVED_VALUE_RANGE\n        raise ActionPack::WebAuthn::InvalidCborError, \"Reserved additional info: #{info}\"\n      else\n        raise ActionPack::WebAuthn::InvalidCborError, \"Invalid additional info: #{info}\"\n      end\n    end\n\n    def additional_info(consume: true)\n      byte = consume ? read_byte : peek\n      byte & 0b00011111\n    end\n\n    def indefinite_length?\n      read_byte if additional_info(consume: false) == INDEFINITE_LENGTH_MAJOR_TYPE\n    end\n\n    def break_code?\n      read_byte if peek == BREAK_CODE\n    end\n\n    def read_bytes(length)\n      raise ActionPack::WebAuthn::InvalidCborError, \"Unexpected end of input\" if @position + length > @bytes.length","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/basecamp/fizzy/blob/7aabe7458060d8a1759a53b7ede39e74e6c0b20d/lib/action_pack/web_authn/cbor_decoder.rb#L219-L255","documentation":"read_argument's else-branch fires for additional-info 31 — the indefinite-length/break marker — used where a definite argument is required (for example a positive-integer header 0x1F, or an argument byte of 0xFF leaking into an integer/text context). RFC 8949 allows info 31 only for streaming strings/arrays/maps, so anywhere else it is a protocol violation and InvalidCborError is raised.","triggerScenarios":"Bytes like 0x1F, 0x3F, 0x5F (typed headers with break-info), or a 0xFF break code appearing where the parser expects a length argument — typical when a definite/indefinite concatenation is mixed up or the buffer is misaligned by one byte.","commonSituations":"Merging a hand-written indefinite-length item with definite-length items; off-by-one slicing that shifts headers; fuzzed payloads; decoders fed the CBOR sequence's second item mid-item of the first.","solutions":["Hex-dump around the failure offset: a header ending in 0x1F or a stray 0xFF in length position confirms misalignment.","Emit the payload from a conformant encoder; do not concatenate partial items.","Validate the byte layout in tests against a golden vector from RFC 8949's appendix.","Rescue InvalidCborError centrally and reject the payload — misaligned CBOR cannot be recovered."],"exampleFix":"# before\ncombined = indefinite_chunk + definite_chunk # misaligned concatenation\nActionPack::WebAuthn::CborDecoder.decode(combined)\n\n# after — decode each item as its own complete CBOR sequence item\n[chunk_a, chunk_b].each { |c| ActionPack::WebAuthn::CborDecoder.decode(c) }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"begin\n  value = ActionPack::WebAuthn::CborDecoder.decode(bytes)\nrescue ActionPack::WebAuthn::InvalidCborError => e\n  render json: { error: 'malformed CBOR payload' }, status: :bad_request\nend","preventionTips":["Close every indefinite-length item with 0xFF and never mix partial indefinite streams with definite items.","Round-trip test custom encoders against the decoder.","Hex-dump failures: header low-bits of 0x1F or stray 0xFF in length position mean misalignment."],"tags":["cbor","malformed-data","rfc8949","byte-alignment"],"backgroundTag":"cbor-malformed-data","analyzedSha":"7aabe7458060d8a1759a53b7ede39e74e6c0b20d","analyzedAt":"2026-08-21T18:33:25.349Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}