github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/chat/msgchecker/plaintext_checker.go (about) 1 package msgchecker 2 3 import ( 4 "errors" 5 "fmt" 6 "regexp" 7 8 "github.com/keybase/client/go/protocol/chat1" 9 ) 10 11 var validTopicNameRegex = regexp.MustCompile(`^[0-9a-zA-Z_-]+$`) 12 13 type validateTopicNameRes int 14 15 const ( 16 validateTopicNameResOK validateTopicNameRes = 0 17 validateTopicNameResInvalidLength validateTopicNameRes = 1 18 validateTopicNameResInvalidChar validateTopicNameRes = 2 19 ) 20 21 func (r validateTopicNameRes) String() string { 22 switch r { 23 case validateTopicNameResInvalidChar: 24 return "invalid characters in channel name, please use alphanumeric, underscores, or dashes" 25 case validateTopicNameResInvalidLength: 26 return "invalid channel name length. Must be greater than 0 and less than or equal to 20" 27 case validateTopicNameResOK: 28 return "OK" 29 } 30 return "" 31 } 32 33 func validateTopicName(topicName string) validateTopicNameRes { 34 if len(topicName) == 0 || len(topicName) > TopicMaxLength { 35 return validateTopicNameResInvalidLength 36 } 37 if !validTopicNameRegex.MatchString(topicName) { 38 return validateTopicNameResInvalidChar 39 } 40 return validateTopicNameResOK 41 } 42 43 type MessagePlaintextLengthExceedingError struct { 44 ActualLength int 45 MaxLength int 46 DescriptibleItemName string 47 } 48 49 func (e MessagePlaintextLengthExceedingError) Error() string { 50 return fmt.Sprintf("%s of size %d bytes exceeds the maximum length of %d bytes", e.DescriptibleItemName, e.ActualLength, e.MaxLength) 51 } 52 53 func (e MessagePlaintextLengthExceedingError) IsImmediateFail() (chat1.OutboxErrorType, bool) { 54 return chat1.OutboxErrorType_TOOLONG, true 55 } 56 57 func plaintextFieldLengthChecker(descriptibleItemName string, actualLength int, maxLength int) error { 58 if actualLength > maxLength { 59 return MessagePlaintextLengthExceedingError{ 60 ActualLength: actualLength, 61 MaxLength: maxLength, 62 DescriptibleItemName: descriptibleItemName, 63 } 64 } 65 return nil 66 } 67 68 func checkMessagePlaintextLength(msg chat1.MessagePlaintext) error { 69 mtype, err := msg.MessageBody.MessageType() 70 if err != nil { 71 return err 72 } 73 74 textMsgLength := getMaxTextLength(msg.ClientHeader.Conv.TopicType) 75 switch mtype { 76 case chat1.MessageType_ATTACHMENT, 77 chat1.MessageType_DELETE, 78 chat1.MessageType_NONE, 79 chat1.MessageType_TLFNAME, 80 chat1.MessageType_ATTACHMENTUPLOADED, 81 chat1.MessageType_JOIN, 82 chat1.MessageType_PIN, 83 chat1.MessageType_LEAVE, 84 chat1.MessageType_SYSTEM, 85 chat1.MessageType_DELETEHISTORY, 86 chat1.MessageType_SENDPAYMENT, 87 chat1.MessageType_UNFURL: 88 return nil 89 case chat1.MessageType_TEXT: 90 return plaintextFieldLengthChecker("message", len(msg.MessageBody.Text().Body), textMsgLength) 91 case chat1.MessageType_FLIP: 92 return plaintextFieldLengthChecker("flip", len(msg.MessageBody.Flip().Text), textMsgLength) 93 case chat1.MessageType_EDIT: 94 return plaintextFieldLengthChecker("message edit", len(msg.MessageBody.Edit().Body), 95 textMsgLength) 96 case chat1.MessageType_REACTION: 97 return plaintextFieldLengthChecker("message reaction", len(msg.MessageBody.Reaction().Body), 98 ReactionMessageMaxLength) 99 case chat1.MessageType_HEADLINE: 100 return plaintextFieldLengthChecker("headline", len(msg.MessageBody.Headline().Headline), 101 HeadlineMaxLength) 102 case chat1.MessageType_METADATA: 103 if msg.ClientHeader.Conv.TopicType == chat1.TopicType_CHAT { 104 topicNameRes := validateTopicName(msg.MessageBody.Metadata().ConversationTitle) 105 if validateTopicNameResOK != topicNameRes { 106 return errors.New(topicNameRes.String()) 107 } 108 } 109 return nil 110 case chat1.MessageType_REQUESTPAYMENT: 111 return plaintextFieldLengthChecker("request payment note", 112 len(msg.MessageBody.Requestpayment().Note), RequestPaymentTextMaxLength) 113 default: 114 typ, err := msg.MessageBody.MessageType() 115 if err != nil { 116 return fmt.Errorf("unknown message type: %v", err) 117 } 118 return fmt.Errorf("unknown message type: %v", typ) 119 } 120 } 121 122 func CheckMessagePlaintext(msg chat1.MessagePlaintext) error { 123 return checkMessagePlaintextLength(msg) 124 }