diff --git a/internal/db/migrations/2023120800.sql b/internal/db/migrations/2023120800.sql new file mode 100644 index 0000000..d6bb410 --- /dev/null +++ b/internal/db/migrations/2023120800.sql @@ -0,0 +1,7 @@ +/* change the string delimeter from comma to Unit Separator, to allow commas */ +/* to be used in polls and the like */ +UPDATE reactions SET reaction = REPLACE(reaction, ',', X'1F'); +UPDATE polls SET opt_emojis = REPLACE(opt_emojis, ',', X'1F'); +UPDATE polls SET opt_text = REPLACE(opt_text, ',', X'1F'); +UPDATE reaction_role_categories SET emoji = REPLACE(emoji, ',', X'1F'); +UPDATE reaction_role_categories SET roles = REPLACE(roles, ',', X'1F'); \ No newline at end of file diff --git a/internal/db/polls.go b/internal/db/polls.go index 3b2029f..51cf5c5 100644 --- a/internal/db/polls.go +++ b/internal/db/polls.go @@ -56,6 +56,10 @@ func GetPoll(msgID string) (*Poll, error) { } func AddPollOptionText(msgID string, text string) error { + if strings.Contains(text, "\x1F") { + return errors.New("option string cannot contain unit separator") + } + var optText string err := db.QueryRow("SELECT opt_text FROM polls WHERE msg_id = ?", msgID).Scan(&optText) if err != nil { @@ -65,11 +69,15 @@ func AddPollOptionText(msgID string, text string) error { splitText := splitOptions(optText) splitText = append(splitText, text) - _, err = db.Exec("UPDATE polls SET opt_text = ? WHERE msg_id = ?", strings.Join(splitText, ","), msgID) + _, err = db.Exec("UPDATE polls SET opt_text = ? WHERE msg_id = ?", strings.Join(splitText, "\x1F"), msgID) return err } func AddPollOptionEmoji(msgID string, emoji string) error { + if strings.Contains(emoji, "\x1F") { + return errors.New("emoji string cannot contain unit separator") + } + var optEmojis string err := db.QueryRow("SELECT opt_emojis FROM polls WHERE msg_id = ?", msgID).Scan(&optEmojis) if err != nil { @@ -82,7 +90,7 @@ func AddPollOptionEmoji(msgID string, emoji string) error { } splitEmojis = append(splitEmojis, emoji) - _, err = db.Exec("UPDATE polls SET opt_emojis = ? WHERE msg_id = ?", strings.Join(splitEmojis, ","), msgID) + _, err = db.Exec("UPDATE polls SET opt_emojis = ? WHERE msg_id = ?", strings.Join(splitEmojis, "\x1F"), msgID) return err } @@ -119,5 +127,5 @@ func splitOptions(s string) []string { if s == "" { return nil } - return strings.Split(s, ",") + return strings.Split(s, "\x1F") } diff --git a/internal/db/roles.go b/internal/db/roles.go index 802bb9a..fc24f36 100644 --- a/internal/db/roles.go +++ b/internal/db/roles.go @@ -19,6 +19,7 @@ package db import ( + "errors" "slices" "strings" @@ -41,8 +42,8 @@ func AddReactionRoleCategory(channelID string, rrc ReactionRoleCategory) error { channelID, rrc.Name, rrc.Description, - strings.Join(rrc.Emoji, ","), - strings.Join(rrc.Roles, ","), + strings.Join(rrc.Emoji, "\x1F"), + strings.Join(rrc.Roles, "\x1F"), ) return err } @@ -74,6 +75,10 @@ func DeleteReactionRoleCategory(channelID, name string) error { } func AddReactionRole(channelID, category, emoji string, role *discordgo.Role) error { + if strings.Contains(category, "\x1F") || strings.Contains(emoji, "\x1F") { + return errors.New("reaction roles cannot contain unit separator") + } + var oldEmoji, oldRoles string err := db.QueryRow("SELECT emoji, roles FROM reaction_role_categories WHERE name = ? AND channel_id = ?", category, channelID).Scan(&oldEmoji, &oldRoles) if err != nil { @@ -86,8 +91,8 @@ func AddReactionRole(channelID, category, emoji string, role *discordgo.Role) er _, err = db.Exec( "UPDATE reaction_role_categories SET emoji = ?, roles = ? WHERE name = ? AND channel_id = ?", - strings.Join(splitEmoji, ","), - strings.Join(splitRoles, ","), + strings.Join(splitEmoji, "\x1F"), + strings.Join(splitRoles, "\x1F"), category, channelID, ) @@ -111,8 +116,8 @@ func DeleteReactionRole(channelID, category string, role *discordgo.Role) error _, err = db.Exec( "UPDATE reaction_role_categories SET emoji = ?, roles = ? WHERE name = ? AND channel_id = ?", - strings.Join(splitEmoji, ","), - strings.Join(splitRoles, ","), + strings.Join(splitEmoji, "\x1F"), + strings.Join(splitRoles, "\x1F"), category, channelID, ) diff --git a/internal/systems/reactions/commands.go b/internal/systems/reactions/commands.go index cddb113..99d7a0c 100644 --- a/internal/systems/reactions/commands.go +++ b/internal/systems/reactions/commands.go @@ -77,6 +77,8 @@ func reactionsAddCmd(s *discordgo.Session, i *discordgo.InteractionCreate) error if err := validateEmoji(reaction.Reaction); err != nil { return err } + // Use the correct delimeter for the DB + reaction.Reaction = strings.ReplaceAll(reaction.Reaction, ",", "\x1F") } err := db.AddReaction(i.GuildID, reaction) @@ -140,6 +142,8 @@ func validateEmoji(s string) error { return fmt.Errorf("invalid reaction emoji: %s", emojiStr) } } + } else if strings.Contains(s, "\x1F") { + return fmt.Errorf("emoji string cannot contain unit separator") } else { if _, ok := emoji.Parse(s); !ok { return fmt.Errorf("invalid reaction emoji: %s", s)