{"record":{"id":"3e89018c3b60abd5","repo":"larksuite/cli","slug":"set-subject-value-must-not-contain-cr-or-lf-3e8901","errorCode":null,"errorMessage":"set_subject: value must not contain CR or LF","messagePattern":"set_subject: value must not contain CR or LF","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/mail/draft/patch.go","lineNumber":68,"sourceCode":"\tfor _, op := range patch.Ops {\n\t\tif err := applyOp(dctx, snapshot, op, patch.Options); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif bodyChangingOps[op.Op] {\n\t\t\thasBodyChange = true\n\t\t}\n\t}\n\tif err := postProcessInlineImages(dctx, snapshot, hasBodyChange); err != nil {\n\t\treturn err\n\t}\n\treturn refreshSnapshot(snapshot)\n}\n\nfunc applyOp(dctx *DraftCtx, snapshot *DraftSnapshot, op PatchOp, options PatchOptions) error {\n\tswitch op.Op {\n\tcase \"set_subject\":\n\t\tif strings.ContainsAny(op.Value, \"\\r\\n\") {\n\t\t\treturn fmt.Errorf(\"set_subject: value must not contain CR or LF\")\n\t\t}\n\t\tupsertHeader(&snapshot.Headers, \"Subject\", op.Value)\n\tcase \"set_recipients\":\n\t\treturn setRecipients(snapshot, op.Field, op.Addresses)\n\tcase \"add_recipient\":\n\t\treturn addRecipient(snapshot, op.Field, Address{Name: op.Name, Address: op.Address})\n\tcase \"remove_recipient\":\n\t\treturn removeRecipient(snapshot, op.Field, op.Address)\n\tcase \"set_reply_to\":\n\t\tupsertHeader(&snapshot.Headers, \"Reply-To\", formatAddressList(op.Addresses))\n\tcase \"clear_reply_to\":\n\t\tremoveHeader(&snapshot.Headers, \"Reply-To\")\n\tcase \"set_body\":\n\t\treturn setBody(snapshot, op.Value, options)\n\tcase \"set_reply_body\":\n\t\treturn setReplyBody(snapshot, op.Value, options)\n\tcase \"replace_body\":\n\t\treturn replaceBody(snapshot, op.BodyKind, op.Value, options)","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/mail/draft/patch.go#L50-L86","documentation":"applyOp validates that the value supplied for a 'set_subject' patch op contains no CR or LF characters. Header injection via newlines would split or forge additional headers in the outgoing draft, so the library rejects it outright.","triggerScenarios":"Calling Apply with a PatchOp{Op:\"set_subject\"} whose Value contains '\\r' or '\\n' (e.g. a subject pasted from a multi-line source or built from unsanitized user input).","commonSituations":"Copying an email subject from a text file or web form with trailing newline; user input injected into the subject field; CSV/JSON imports with embedded line breaks.","solutions":["Trim the subject with strings.TrimSpace before building the op.","Strip or replace CR/LF: strings.ReplaceAll(strings.ReplaceAll(s,\"\\r\",\" \"),\"\\n\",\" \").","Reject the input in your UI/API layer before constructing the patch.","If a multi-line subject is truly needed, fold it with proper RFC 2047 encoding rather than raw newlines."],"exampleFix":"// before\nops := []PatchOp{{Op: \"set_subject\", Value: rawSubject}}\n// after\nsubject := strings.TrimSpace(strings.ReplaceAll(strings.ReplaceAll(rawSubject, \"\\r\", \" \"), \"\\n\", \" \"))\nops := []PatchOp{{Op: \"set_subject\", Value: subject}}","handlingStrategy":"validation","validationCode":"func validSubject(s string) bool { return !strings.ContainsAny(s, \"\\r\\n\") }\n// before op: if !validSubject(subject) { return fmt.Errorf(\"subject contains newline\") }","typeGuard":"func safeHeaderValue(s string) (string, bool) {\n    s = strings.TrimSpace(s)\n    return s, !strings.ContainsAny(s, \"\\r\\n\")\n}","tryCatchPattern":"if err := Apply(ctx, dctx, ops, opts); err != nil {\n    if strings.Contains(err.Error(), \"CR or LF\") {\n        return fmt.Errorf(\"subject/value contains newline; sanitize input: %w\", err)\n    }\n    return err\n}","preventionTips":["TrimSpace all header-derived values before building PatchOps.","Sanitize user-supplied subjects at the UI/API boundary.","Treat \\r and \\n as forbidden characters in any header value.","Use encoding libraries for any multi-line header data."],"tags":["email","header-injection","validation"],"backgroundTag":"header-injection","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"}