{"record":{"id":"19aa30d918fb2529","repo":"larksuite/cli","slug":"emlbuilder-display-name-contains-cr-or-lf-q","errorCode":null,"errorMessage":"emlbuilder: display name contains CR or LF: %q","messagePattern":"emlbuilder: display name contains CR or LF: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/mail/emlbuilder/builder.go","lineNumber":186,"sourceCode":"// validateHeaderName rejects any string that contains ':', CR (\\r), LF (\\n),\n// or non-printable ASCII characters, as required by RFC 5322 field-name syntax.\nfunc validateHeaderName(n string) error {\n\tif strings.ContainsAny(n, \":\\r\\n\") {\n\t\treturn fmt.Errorf(\"emlbuilder: header name contains ':', CR, or LF: %q\", n) //nolint:forbidigo // intermediate EML builder error; mail command layer wraps into typed ValidationError.\n\t}\n\tfor _, r := range n {\n\t\tif r < 0x21 || r > 0x7e {\n\t\t\treturn fmt.Errorf(\"emlbuilder: header name contains non-printable character: %q\", n) //nolint:forbidigo // intermediate EML builder error; mail command layer wraps into typed ValidationError.\n\t\t}\n\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 {","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/mail/emlbuilder/builder.go#L168-L204","documentation":"validateDisplayName rejects display names containing CR or LF, because mail.Address.String() encodes names in a quoted-string that CRLF would escape, allowing header injection into the generated EML. It runs for every address-setting setter (From, To, CC, BCC, ReplyTo, DispositionNotificationTo). Wrapped into a typed ValidationError by the mail command layer.","triggerScenarios":"Passing a display name to From/To/CC/BCC/ReplyTo/DispositionNotificationTo that contains '\\r' or '\\n', e.g. To(\"Alice\\r\\nBcc: victim@x.com\" <a@x.com>).","commonSituations":"Display names assembled from user profile fields or form input containing embedded newlines; data imported from CSV/Excel with multiline cells; log-formatted strings reused as names.","solutions":["Strip CR/LF from the display name before passing it (strings.ReplaceAll(name, \"\\n\", \"\") and same for \"\\r\").","Validate address book input at ingestion time to reject multiline display names.","If a line break is intended, remove it — RFC 5322 display names cannot contain raw newlines."],"exampleFix":"// before\nb.To(\"Alice\\nBcc: evil@x.com\" <alice@x.com>)\n// after\nname := strings.ReplaceAll(strings.ReplaceAll(raw, \"\\r\", \"\"), \"\\n\", \"\")\nb.To(name + \" <alice@x.com>\")","handlingStrategy":"validation","validationCode":"func safeDisplayName(name string) string {\n    return strings.Map(func(r rune) rune {\n        if r == '\\r' || r == '\\n' { return -1 }\n        return r\n    }, name)\n}\n// use: b.To(safeDisplayName(name) + \" <\" + addr + \">\")","typeGuard":null,"tryCatchPattern":"if err := b.To(display + \" <\" + addr + \">\"); err != nil {\n    var verr *ValidationError\n    if errors.As(err, &verr) { return fmt.Errorf(\"invalid display name %q: %w\", display, verr) }\n    return err\n}","preventionTips":["Strip CR/LF from every display name sourced from user profiles, forms, or imported data.","Validate address book entries at ingestion time (reject multiline names).","Never interpolate raw user input directly into To/From strings without a sanitizer step."],"tags":["email","header-injection","address-validation","eml"],"backgroundTag":"header-injection-crlf","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"}