{"record":{"id":"aad7e51e029fd2b6","repo":"pion/webrtc","slug":"w-unreasonable-comment-count","errorCode":null,"errorMessage":"%w: unreasonable comment count","messagePattern":"%w: unreasonable comment count","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/media/oggreader/oggreader.go","lineNumber":445,"sourceCode":"\t\treturn \"\", 0, fmt.Errorf(\"%w: payload too short for vendor string\", errBadOpusTagsSignature)\n\t}\n\tvendorLen := int(vendorLen32)\n\n\tvendorStart := headerMagicLen + u32Size\n\tvendorEnd := vendorStart + vendorLen\n\tif vendorEnd+u32Size > len(payload) {\n\t\treturn \"\", 0, fmt.Errorf(\"%w: payload too short for vendor+comment count\", errBadOpusTagsSignature)\n\t}\n\n\tvendor := string(payload[vendorStart:vendorEnd])\n\n\treturn vendor, vendorEnd, nil\n}\n\nfunc parseUserComments(payload []byte, vendorEnd, u32Size int) ([]UserComment, error) {\n\tuserCommentCount32 := binary.LittleEndian.Uint32(payload[vendorEnd : vendorEnd+u32Size])\n\tif int(userCommentCount32) > (len(payload)-vendorEnd)/u32Size {\n\t\treturn nil, fmt.Errorf(\"%w: unreasonable comment count\", errBadOpusTagsSignature)\n\t}\n\tuserCommentCount := int(userCommentCount32)\n\n\tpos := vendorEnd + u32Size\n\tuserComments := make([]UserComment, userCommentCount)\n\n\tfor i := range userComments {\n\t\tcomment, nextPos, err := parseSingleUserComment(payload, pos, u32Size, i)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tuserComments[i] = comment\n\t\tpos = nextPos\n\t}\n\n\treturn userComments, nil\n}\n","sourceCodeStart":427,"sourceCodeEnd":463,"githubUrl":"https://github.com/pion/webrtc/blob/8c25dc09fa9e7c09aac4309ead88093d760432b0/pkg/media/oggreader/oggreader.go#L427-L463","documentation":"This error is returned by parseUserComments (called from ParseOpusTags) when the OpusTags header declares a user comment count that cannot possibly fit in the remaining payload. The count is a little-endian uint32 read from the payload; if count > (len(payload)-vendorEnd)/u32Size, there are not even enough bytes for per-comment length fields, so the header is corrupt or malicious.","triggerScenarios":"Calling ParseOpusTags on a payload whose 4-byte comment count field (after the vendor string) is larger than the number of remaining bytes divided by u32Size — i.e. a truncated, corrupted, or maliciously crafted OpusTags packet.","commonSituations":"Parsing truncated Ogg Opus files (incomplete downloads), hand-edited or corrupted metadata, fuzzed/malicious input claiming billions of comments, or feeding a non-OpusTags packet to ParseOpusTags.","solutions":["Verify the input file is complete and uncorrupted (re-download or re-encode the source).","Validate the OpusTags header structure before parsing: check the 'OpusTags' magic, vendor length, and comment count against the payload length.","Use errors.Is(err, errBadOpusTagsSignature) to detect this class of malformed-header error and reject the file.","If the input comes from untrusted sources, sanitize/re-encode metadata with a known-good tool (e.g. opustags, ffmpeg) before parsing."],"exampleFix":"// before: parsing raw possibly-truncated payload\ncomments, err := ParseOpusTags(payload)\n// after: pre-validate count field against payload size\nif len(payload) < 8+4 { return errors.New(\"payload too short\") }\ncount := binary.LittleEndian.Uint32(payload[len(payload)-4:])\nif int(count) > (len(payload)-8-4)/4 { return errors.New(\"unreasonable comment count\") }\ncomments, err := ParseOpusTags(payload)","handlingStrategy":"validation","validationCode":"func hasReasonableCommentCount(payload []byte, vendorEnd, u32Size int) bool {\n    if vendorEnd+u32Size > len(payload) { return false }\n    count := int(binary.LittleEndian.Uint32(payload[vendorEnd : vendorEnd+u32Size]))\n    return count <= (len(payload)-vendorEnd)/u32Size\n}","typeGuard":null,"tryCatchPattern":"comments, err := ParseOpusTags(payload)\nif err != nil {\n    if errors.Is(err, errBadOpusTagsSignature) {\n        return fmt.Errorf(\"malformed OpusTags header: %w\", err)\n    }\n    return err\n}","preventionTips":["Only parse complete, checksum-verified files from trusted sources.","Never trust the comment count field of untrusted input without bounding it against payload size.","Fuzz-test your ingest path with corrupted OpusTags packets.","Re-encode suspect files with a standard tool before parsing metadata."],"tags":["go","ogg","opus","malformed-header","input-validation"],"backgroundTag":"invalid-opus-tags-header","analyzedSha":"8c25dc09fa9e7c09aac4309ead88093d760432b0","analyzedAt":"2026-09-03T21:56:56.182Z","contentChangedAt":"2026-09-03T21:56:56.182Z","schemaVersion":2},"datasetVersion":"2026-09-11T07:07:21.782Z"}