Handle spaces in poll create better

This commit is contained in:
kate-signal 2025-10-22 16:18:35 -04:00 committed by GitHub
parent a7755d518b
commit 41baf24af5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 62 additions and 13 deletions

View File

@ -181,6 +181,9 @@ struct NewPollView: View {
if newText.count > characterLimit {
pollQuestion = String(newText.prefix(characterLimit))
}
if pollQuestion.stripped.isEmpty {
pollQuestion = ""
}
}
} header: {
Text(
@ -200,6 +203,9 @@ struct NewPollView: View {
if newText.count > characterLimit {
option.text = String(newText.prefix(characterLimit))
}
if option.text.stripped.isEmpty {
option.text = ""
}
}
.focused($focusedItemID, equals: option.id)
}
@ -284,8 +290,10 @@ struct NewPollView: View {
private func sendButtonPressed(sendButtonEnabled: Bool) {
if sendButtonEnabled {
viewModel.onSend(
pollOptions: pollOptions.map(\.text).filter { !$0.isEmpty },
question: pollQuestion,
pollOptions: pollOptions.map(\.text)
.filter { !$0.stripped.isEmpty }
.map { $0.stripped },
question: pollQuestion.stripped,
allowMultipleVotes: allowMultipleVotes
)
} else {
@ -299,7 +307,7 @@ struct NewPollView: View {
private func onChange() {
// Filter out all blank fields since user may have deleted a middle option.
var filteredPollOptions = pollOptions.filter({ !$0.text.isEmpty })
var filteredPollOptions = pollOptions.filter({ !$0.text.stripped.isEmpty })
if filteredPollOptions.count >= 10 {
return

View File

@ -1365,6 +1365,7 @@ extension AppSetup.GlobalsContinuation {
accountManager: tsAccountManager,
messageSenderJobQueue: messageSenderJobQueue,
disappearingMessagesConfigurationStore: disappearingMessagesConfigurationStore,
attachmentContentValidator: attachmentContentValidator,
db: db
)
let pollArchiver = BackupArchivePollArchiver(

View File

@ -32,6 +32,7 @@ public class PollMessageManager {
private let messageSenderJobQueue: MessageSenderJobQueue
private let accountManager: TSAccountManager
private let disappearingMessagesConfigurationStore: DisappearingMessagesConfigurationStore
private let attachmentContentValidator: AttachmentContentValidator
init(
pollStore: PollStore,
@ -40,6 +41,7 @@ public class PollMessageManager {
accountManager: TSAccountManager,
messageSenderJobQueue: MessageSenderJobQueue,
disappearingMessagesConfigurationStore: DisappearingMessagesConfigurationStore,
attachmentContentValidator: AttachmentContentValidator,
db: DB
) {
self.pollStore = pollStore
@ -49,6 +51,46 @@ public class PollMessageManager {
self.messageSenderJobQueue = messageSenderJobQueue
self.db = db
self.disappearingMessagesConfigurationStore = disappearingMessagesConfigurationStore
self.attachmentContentValidator = attachmentContentValidator
}
public func validateIncomingPollCreate(
pollCreate: SSKProtoDataMessagePollCreate,
tx: DBWriteTransaction
) throws -> ValidatedInlineMessageBody {
guard let question = pollCreate.question else {
throw OWSAssertionError("Poll missing question")
}
guard question.trimmedIfNeeded(maxByteCount: OWSMediaUtils.kOversizeTextMessageSizeThresholdBytes) == nil
&& question.count <= OWSPoll.Constants.maxCharacterLength
else {
throw OWSAssertionError("Poll question too large")
}
guard question.count > 0 else {
throw OWSAssertionError("Poll question empty")
}
guard pollCreate.options.count >= 2 else {
throw OWSAssertionError("Poll does not have enough options")
}
for option in pollCreate.options {
guard option.trimmedIfNeeded(maxByteCount: OWSMediaUtils.kOversizeTextMessageSizeThresholdBytes) == nil
&& option.count <= OWSPoll.Constants.maxCharacterLength
else {
throw OWSAssertionError("Poll option too large")
}
guard option.count > 0 else {
throw OWSAssertionError("Poll option empty")
}
}
return self.attachmentContentValidator.truncatedMessageBodyForInlining(
MessageBody(text: question, ranges: .empty),
tx: tx
)
}
public func processIncomingPollCreate(

View File

@ -1151,18 +1151,15 @@ public final class MessageReceiver {
}
let pollCreate = dataMessage.pollCreate
if let pollCreate, let question = pollCreate.question {
guard question.count <= OWSPoll.Constants.maxCharacterLength
&& question.trimmedIfNeeded(maxByteCount: OWSMediaUtils.kOversizeTextMessageSizeThresholdBytes) == nil
else {
owsFailDebug("Poll question too large")
if let pollCreate {
do {
body = try DependenciesBridge.shared.pollMessageManager.validateIncomingPollCreate(
pollCreate: pollCreate,
tx: tx)
} catch {
Logger.error("Error validating incoming poll create: \(error)")
return nil
}
body = DependenciesBridge.shared.attachmentContentValidator.truncatedMessageBodyForInlining(
MessageBody(text: question, ranges: .empty),
tx: tx
)
}
if let pollTerminate = dataMessage.pollTerminate{

View File

@ -27,6 +27,7 @@ struct PollManagerTest {
accountManager: mockTSAccountManager,
messageSenderJobQueue: MessageSenderJobQueue(appReadiness: AppReadinessMock()),
disappearingMessagesConfigurationStore: MockDisappearingMessagesConfigurationStore(),
attachmentContentValidator: AttachmentContentValidatorMock(),
db: db
)
let testPhone = E164("+16505550101")!