{"record":{"id":"99a6087156dee487","repo":"OpenNHP/opennhp","slug":"length-d-is-negative","errorCode":null,"errorMessage":"length %d is negative","messagePattern":"length (.+?) is negative","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nhp/core/ztdo/ztdo.go","lineNumber":664,"sourceCode":"\t\t}\n\n\t\trvalue.Set(newArray)\n\n\t} else {\n\t\tpanic(\"not support\")\n\t}\n}\n\n// encodeMetadataLength encodes a length continuation bit into the MSB of metadata length\nfunc encodeMetadataLength(length int, continuation bool) ([2]byte, error) {\n\tvar result [2]byte\n\n\tif length > MetadataChunkMaxSize {\n\t\treturn result, fmt.Errorf(\"length %d exceeds maximum encoded value (%d)\", length, MetadataChunkMaxSize)\n\t}\n\n\tif length < 0 {\n\t\treturn result, fmt.Errorf(\"length %d is negative\", length)\n\t}\n\n\t//nolint:gosec // G602: result is [2]byte array, indices 0 and 1 are always valid\n\tresult[0] = byte((length >> 8) & 0x7F)\n\tif continuation {\n\t\tresult[0] |= 0x80\n\t}\n\tresult[1] = byte(length & 0xFF)\n\n\tif littleEndian {\n\t\tresult[0], result[1] = result[1], result[0]\n\t}\n\n\treturn result, nil\n}\n\n// preprocessContinuation decodes a length continuation bit from the MSB of metadata length\nfunc preprocessContinuation(encoded []byte) (continuation bool) {","sourceCodeStart":646,"sourceCodeEnd":682,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/nhp/core/ztdo/ztdo.go#L646-L682","documentation":"encodeMetadataLength serializes a metadata chunk length into a 2-byte, 7-bit-per-byte encoding with a continuation flag for ztdo metadata. The library refuses values outside [0, MetadataChunkMaxSize] because negative lengths cannot be encoded and larger values overflow the encoded format. This guard prevents silent truncation or corrupted metadata frames.","triggerScenarios":"SetMetadata (or an anonymous helper it calls) is invoked with a metadata value whose serialized length is negative, which in practice means a length computation underflowed (e.g. len(x) minus an offset larger than the slice) before reaching encodeMetadataLength.","commonSituations":"A caller computed the metadata length from a slicing expression like len(data)-headerLen where the header was bigger than the data; a custom metadata encoder passed a signed int straight through with a bad arithmetic result; fuzzed or hostile input produced a negative computed size.","solutions":["Inspect the caller (SetMetadata) and fix the length arithmetic so it never produces a negative value before calling SetMetadata","Clamp or validate the metadata payload length before calling SetMetadata, e.g. if l < 0 { return fmt.Errorf(\"invalid metadata length %d\", l) }","Verify MetadataChunkMaxSize handling is separate from the negative check; both branches return the partial result and must be handled by the caller"],"exampleFix":"// before\nmetaLen := len(payload) - headerSize\npacket.SetMetadata(key, payload[:metaLen])\n// after\nmetaLen := len(payload) - headerSize\nif metaLen < 0 {\n    return fmt.Errorf(\"payload too short: %d bytes after %d-byte header\", len(payload), headerSize)\n}\npacket.SetMetadata(key, payload[:metaLen])","handlingStrategy":"validation","validationCode":"meta := []byte(value)\nif len(meta) < 0 || len(meta) > ztdo.MetadataChunkMaxSize {\n    return fmt.Errorf(\"metadata length %d out of [0,%d]\", len(meta), ztdo.MetadataChunkMaxSize)\n}","typeGuard":"func validMetaLen(n int) bool { return n >= 0 && n <= 4096 /* MetadataChunkMaxSize */ }","tryCatchPattern":"if err := pkt.SetMetadata(k, v); err != nil {\n    if strings.Contains(err.Error(), \"is negative\") || strings.Contains(err.Error(), \"exceeds maximum\") {\n        return fmt.Errorf(\"bad metadata %q: %w\", k, err)\n    }\n    return err\n}","preventionTips":["Never compute metadata length with subtraction that can underflow; check the subtraction result first","Validate serialized metadata size before SetMetadata","Add a unit test with empty and header-larger-than-payload inputs"],"tags":["go","encoding","metadata","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"6e04ca5ff03222a699c24205cd4bf8fee9af7ffe","analyzedAt":"2026-09-07T15:44:59.941Z","contentChangedAt":"2026-09-07T15:44:59.941Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}