{"record":{"id":"0db5268a70d93f17","repo":"larksuite/cli","slug":"emlbuilder-header-name-contains-non-printable-cha","errorCode":null,"errorMessage":"emlbuilder: header name contains non-printable character: %q","messagePattern":"emlbuilder: header name contains non-printable character: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/mail/emlbuilder/builder.go","lineNumber":176,"sourceCode":"\tcase r >= 0x202A && r <= 0x202E: // Bidi: LRE/RLE/PDF/LRO/RLO\n\t\treturn true\n\tcase r >= 0x2028 && r <= 0x2029: // line/paragraph separator\n\t\treturn true\n\tcase r >= 0x2066 && r <= 0x2069: // Bidi isolates: LRI/RLI/FSI/PDI\n\t\treturn true\n\t}\n\treturn false\n}\n\n// 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 {","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/mail/emlbuilder/builder.go#L158-L194","documentation":"validateHeaderName also rejects header names containing any character outside printable ASCII (below 0x21 or above 0x7e), since RFC 5322 field names must be printable ASCII. This keeps serialized headers byte-safe and prevents obfuscation or injection via exotic characters. Wrapped into a typed ValidationError by the mail command layer.","triggerScenarios":"Calling Builder.Header with a name containing spaces, tabs, non-ASCII (e.g. UTF-8 'X-Köln'), or control characters such as '\\t' or NUL.","commonSituations":"Header names copied with a trailing space; localized header names; names read from JSON/config that include BOM or non-ASCII characters; accidental tab between name and value.","solutions":["Use only printable ASCII characters (0x21-0x7e, no spaces) in the header name.","Trim whitespace with strings.TrimSpace before passing the name.","For non-ASCII metadata, move it into the header value (optionally RFC 2047 encoded) rather than the name."],"exampleFix":"// before\nb.Header(\"X-Kunde Name\", v)\n// after\nb.Header(\"X-Kunde-Name\", v)","handlingStrategy":"validation","validationCode":"func printableASCIIName(n string) bool {\n    if n == \"\" { return false }\n    for _, r := range n {\n        if r < 0x21 || r > 0x7e { return false }\n    }\n    return true\n}\n// check before b.Header(strings.TrimSpace(name), value)","typeGuard":null,"tryCatchPattern":"if err := b.Header(name, value); err != nil {\n    var verr *ValidationError\n    if errors.As(err, &verr) { log.Printf(\"invalid header name %q\", name) }\n    return err\n}","preventionTips":["Restrict custom header names to ^[!-~]+$ with no spaces (token characters only).","Move localized or descriptive data into the header value, not the name.","Strip BOM and trim names loaded from JSON/YAML config files."],"tags":["email","header-validation","ascii","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"}