{"record":{"id":"3ecd80927a4edbf4","repo":"larksuite/cli","slug":"emlbuilder-content-id-contains-control-character","errorCode":null,"errorMessage":"emlbuilder: content ID contains control character: %q","messagePattern":"emlbuilder: content ID contains control character: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/mail/emlbuilder/builder.go","lineNumber":196,"sourceCode":"\t}\n\treturn nil\n}\n\n// validateDisplayName rejects display names containing CR or LF, which could\n// escape the quoted-string encoding used by mail.Address.String() and inject headers.\nfunc validateDisplayName(name string) error {\n\tif strings.ContainsAny(name, \"\\r\\n\") {\n\t\treturn fmt.Errorf(\"emlbuilder: display name contains CR or LF: %q\", name) //nolint:forbidigo // intermediate EML builder error; mail command layer wraps into typed ValidationError.\n\t}\n\treturn nil\n}\n\n// validateCID rejects content IDs containing ASCII control characters (0x00–0x1F, 0x7F).\n// RFC 2045 Content-ID has the same syntax as Message-ID; control characters are never valid.\nfunc validateCID(cid string) error {\n\tfor _, r := range cid {\n\t\tif r < 0x20 || r == 0x7f {\n\t\t\treturn fmt.Errorf(\"emlbuilder: content ID contains control character: %q\", cid) //nolint:forbidigo // intermediate EML builder error; mail command layer wraps into typed ValidationError.\n\t\t}\n\t}\n\treturn nil\n}\n\n// From sets the From header. name may be empty.\nfunc (b Builder) From(name, addr string) Builder {\n\tif b.err != nil {\n\t\treturn b\n\t}\n\tif err := validateDisplayName(name); err != nil {\n\t\tb.err = err\n\t\treturn b\n\t}\n\tb.from = mail.Address{Name: name, Address: addr}\n\treturn b\n}\n","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/mail/emlbuilder/builder.go#L178-L214","documentation":"validateCID rejects content IDs containing ASCII control characters (0x00-0x1F and 0x7F), since RFC 2045 Content-ID shares Message-ID syntax where control characters are never valid. It is enforced when adding inline or other MIME parts so a malformed cid cannot corrupt the MIME structure. Wrapped into a typed ValidationError by the mail command layer.","triggerScenarios":"Calling AddInline or AddOtherPart with a cid string containing control characters (e.g. trailing '\\n' from a config read, or a NUL byte in binary-derived input).","commonSituations":"Content IDs read from files/lines without trimming the newline; cids generated by concatenating binary or template data; copy-pasted cid values with invisible control characters.","solutions":["Trim whitespace and remove control characters (strings.TrimFunc with unicode.IsControl) before passing the cid.","Use the returned reference from the attach call (generated cid) instead of a hand-built one.","Validate cids at input time to match a safe pattern such as <[^\\x00-\\x1f\\x7f]+@.+>."],"exampleFix":"// before\npart, _ := b.AddInline(data, \"image/png\", cidFromFile) // cid ends with '\\n'\n// after\ncid := strings.TrimSpace(cidFromFile)\npart, _ := b.AddInline(data, \"image/png\", cid)","handlingStrategy":"validation","validationCode":"func safeCID(cid string) bool {\n    for _, r := range cid {\n        if r < 0x20 || r == 0x7f { return false }\n    }\n    return len(cid) > 0\n}\n// check before b.AddInline(data, mime, cid)","typeGuard":null,"tryCatchPattern":"part, err := b.AddInline(img, \"image/png\", cid)\nif err != nil {\n    var verr *ValidationError\n    if errors.As(err, &verr) { return fmt.Errorf(\"bad cid %q: %w\", cid, verr) }\n    return err\n}","preventionTips":["Trim whitespace/newlines from cids read from files or config.","Prefer cids returned by the builder/attach API over hand-built ones.","Enforce a cid pattern like ^<[^\\x00-\\x1f\\x7f]+@[^\\x00-\\x1f\\x7f]+>$ at input time."],"tags":["email","mime","cid-validation","eml"],"backgroundTag":"mime-content-id-invalid","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}