From 47201f4955bfc9248948798caef8b6643a222994 Mon Sep 17 00:00:00 2001 From: Michelle Tang Date: Wed, 29 Oct 2025 09:54:40 -0400 Subject: [PATCH] Add various backup fixes for polls. --- .../backupTests/chat_item_poll_00.binproto | Bin 0 -> 937 bytes .../backupTests/chat_item_poll_01.binproto | Bin 0 -> 972 bytes .../backupTests/chat_item_poll_02.binproto | Bin 0 -> 1003 bytes .../backupTests/chat_item_poll_03.binproto | Bin 0 -> 1018 bytes .../backupTests/chat_item_poll_04.binproto | Bin 0 -> 1049 bytes .../backupTests/chat_item_poll_05.binproto | Bin 0 -> 1077 bytes .../backupTests/chat_item_poll_06.binproto | Bin 0 -> 1088 bytes .../backupTests/chat_item_poll_07.binproto | Bin 0 -> 1123 bytes .../backupTests/chat_item_poll_08.binproto | Bin 0 -> 1147 bytes .../backupTests/chat_item_poll_09.binproto | Bin 0 -> 941 bytes .../backupTests/chat_item_poll_10.binproto | Bin 0 -> 978 bytes .../backupTests/chat_item_poll_11.binproto | Bin 0 -> 1003 bytes .../backupTests/chat_item_poll_12.binproto | Bin 0 -> 1016 bytes .../backupTests/chat_item_poll_13.binproto | Bin 0 -> 1051 bytes .../backupTests/chat_item_poll_14.binproto | Bin 0 -> 1077 bytes ...hat_item_poll_terminate_update_00.binproto | Bin 0 -> 866 bytes ...hat_item_poll_terminate_update_01.binproto | Bin 0 -> 867 bytes ...em_standard_message_with_quote_00.binproto | Bin 642 -> 956 bytes ...em_standard_message_with_quote_01.binproto | Bin 1089 -> 1421 bytes ...em_standard_message_with_quote_02.binproto | Bin 1123 -> 1540 bytes ...em_standard_message_with_quote_03.binproto | Bin 973 -> 1290 bytes ...em_standard_message_with_quote_04.binproto | Bin 767 -> 1096 bytes ...em_standard_message_with_quote_05.binproto | Bin 1128 -> 1436 bytes ...em_standard_message_with_quote_06.binproto | Bin 653 -> 967 bytes ...em_standard_message_with_quote_07.binproto | Bin 1081 -> 1413 bytes ...em_standard_message_with_quote_08.binproto | Bin 932 -> 1349 bytes ...em_standard_message_with_quote_09.binproto | Bin 1052 -> 1369 bytes ...em_standard_message_with_quote_10.binproto | Bin 929 -> 1368 bytes ...em_standard_message_with_quote_11.binproto | Bin 1071 -> 1379 bytes ...em_standard_message_with_quote_12.binproto | Bin 956 -> 1270 bytes ...em_standard_message_with_quote_13.binproto | Bin 669 -> 998 bytes ...em_standard_message_with_quote_14.binproto | Bin 681 -> 1016 bytes .../backup/v2/ArchiveImportExportTests.kt | 5 +++++ .../securesms/backup/v2/ArchiveErrorCases.kt | 8 ++++++++ .../v2/exporters/ChatItemArchiveExporter.kt | 19 ++++++++++++++---- .../v2/importer/ChatItemArchiveImporter.kt | 1 + .../securesms/database/PollTables.kt | 6 +++--- .../messages/DataMessageProcessor.kt | 12 +++++++++++ app/src/main/protowire/Backup.proto | 1 + 39 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 app/src/androidTest/assets/backupTests/chat_item_poll_00.binproto create mode 100644 app/src/androidTest/assets/backupTests/chat_item_poll_01.binproto create mode 100644 app/src/androidTest/assets/backupTests/chat_item_poll_02.binproto create mode 100644 app/src/androidTest/assets/backupTests/chat_item_poll_03.binproto create mode 100644 app/src/androidTest/assets/backupTests/chat_item_poll_04.binproto create mode 100644 app/src/androidTest/assets/backupTests/chat_item_poll_05.binproto create mode 100644 app/src/androidTest/assets/backupTests/chat_item_poll_06.binproto create mode 100644 app/src/androidTest/assets/backupTests/chat_item_poll_07.binproto create mode 100644 app/src/androidTest/assets/backupTests/chat_item_poll_08.binproto create mode 100644 app/src/androidTest/assets/backupTests/chat_item_poll_09.binproto create mode 100644 app/src/androidTest/assets/backupTests/chat_item_poll_10.binproto create mode 100644 app/src/androidTest/assets/backupTests/chat_item_poll_11.binproto create mode 100644 app/src/androidTest/assets/backupTests/chat_item_poll_12.binproto create mode 100644 app/src/androidTest/assets/backupTests/chat_item_poll_13.binproto create mode 100644 app/src/androidTest/assets/backupTests/chat_item_poll_14.binproto create mode 100644 app/src/androidTest/assets/backupTests/chat_item_poll_terminate_update_00.binproto create mode 100644 app/src/androidTest/assets/backupTests/chat_item_poll_terminate_update_01.binproto diff --git a/app/src/androidTest/assets/backupTests/chat_item_poll_00.binproto b/app/src/androidTest/assets/backupTests/chat_item_poll_00.binproto new file mode 100644 index 0000000000000000000000000000000000000000..9825d75ed06f81de29754c0f18796c336de1ebbc GIT binary patch literal 937 zcmea}U=+CVYr*{QhEfXsyKEj#$*x#(ig%Lc-3T4SDnN=53x$z@T~eE!J@?C1T;m9#SLhTl_rk?tZezH8@o%F+$t_T-1YmD}2wTN(wQD2D?ZwdU*l8%qYRAz^K7!z-Tc+#)&b} zi80BEG1-GLfH8tGfiZ)zfU$zHfswI;k!cnqI|rjE0|Uc<5Q_=O`VVF?i!%IY_|GB4 z#=)q?#KFxb#KOU3#2_Oi#lfs3#w7sMfC8kLB$&Gxh1wZ8ScIAwf%05}=NK3q7#bj| z7=_S9m=vZyy7S-KOW}HKDP9!C>X?(6oSMWMoSRvaQKZQFsMaE=P{m(t?ma?MC~_DxOA%E%Mq;9wPavt-jXb|8xd&SHeH6c_=civu$N literal 0 HcmV?d00001 diff --git a/app/src/androidTest/assets/backupTests/chat_item_poll_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_poll_01.binproto new file mode 100644 index 0000000000000000000000000000000000000000..eb72e751637794fe7aea762bd8d06f3fc769ea78 GIT binary patch literal 972 zcmea}U=+CVYr*{QhEfXsyKEj#$*x#(ig%Lc-3T4SDnN=53x$z@T~eE!J@?C1T;m9#SLhTl_rk?tZezH8@o%F+$t_T-1YmD}2wTN(wQD2D?ZwdU*l8%qYRAz^K7!z-Tc+#)&b} zi80BEG1-GLfH8tGfiZ)zfU$zHfswI;k!cnqI|rjE0|Uc<5Q_=O`VVF?i!%IY_|GB4 z#=)q?#KFxb#KOU3#2_Oi#lfs3#w7sMfC8kLB$&Gxh1wZ8ScIAwf%05}=NK3q7#bj| z7=_S9m=vZyy7S-KOW}HKDP9!C>X?(6oSMWMoSRvaQKZQFsoNV$9~^@rcZJi}3Y#D$I3G z5nzMaE=P{m(t?ma?MC~_DxOA%E%Mq;9wPavt-jXb|8xd&SHeHP<3hv WaT4SDnN=53x$z@T~eE!J@?C1T;m9#SLhTl_rk?tZezH8@o%F+$t_T-1YmD}2wTN(wQD2D?ZwdU*l8%qYRAz^K7!z-Tc+#)&b} zi80BEG1-GLfH8tGfiZ)zfU$zHfswI;k!cnqI|rjE0|Uc<5Q_=O`VVF?i!%IY_|GB4 z#=)q?#KFxb#KOU3#2_Oi#lfs3#w7sMfC8kLB$&Gxh1wZ8ScIAwf%05}=NK3q7#bj| z7=_S9m=vZyy7S-KOW}HKDP9!C>X?(6oSMWMoSRvaQKZQFsw zxVW+t!#$lmoTGyLrL?%XTr-lLeN$7jGV+8tI9LVVEZKC89mryVvlt;PG@U5sC@^XX faT4SDnN=53x$z@T~eE!J@?C1T;m9#SLhTl_rk?tZezH8@o%F+$t_T-1YmD}2wTN(wQD2D?ZwdU*l8%qYRAz^K7!z-Tc+#)&b} zi80BEG1-GLfH8tGfiZ)zfU$zHfswI;k!cnqI|rjE0|Uc<5Q_=O`VVF?i!%IY_|GB4 z#=)q?#KFxb#KOU3#2_Oi#lfs3#w7sMfC8kLB$&Gxh1wZ8ScIAwf%05}=NK3q7#bj| z7=_S9m=vZyy7S-KOW}HKDP9!C>X?(6oSMWMoSRvaQKZQFs{F>>*EL}t51 z`1(5)<~pYcFiP=oab+ildpdbIM+NyyX>oD6W+XfNrlw|PT4SDnN=53x$z@T~eE!J@?C1T;m9#SLhTl_rk?tZezH8@o%F+$t_T-1YmD}2wTN(wQD2D?ZwdU*l8%qYRAz^K7!z-Tc+#)&b} zi80BEG1-GLfH8tGfiZ)zfU$zHfswI;k!cnqI|rjE0|Uc<5Q_=O`VVF?i!%IY_|GB4 z#=)q?#KFxb#KOU3#2_Oi#lfs3#w7sMfC8kLB$&Gxh1wZ8ScIAwf%05}=NK3q7#bj| z7=_S9m=vZyy7S-KOW}HKDP9!C>X?(6oSMWMoSRvaQKZQFsq7xfw$9lUO8a6h;cI`7mstUb77#L zYq)!nW0e#S7gu&-xTlkcb5xMOlol74YeurOZ)$2*MxGD{2dluFC7Z6X16eF^79)g( erjttMC@^XXaT4SDnN=53x$z@T~eE!J@?C1T;m9#SLhTl_rk?tZezH8@o%F+$t_T-1YmD}2wTN(wQD2D?ZwdU*l8%qYRAz^K7!z-Tc+#)&b} zi80BEG1-GLfH8tGfiZ)zfU$zHfswI;k!cnqI|rjE0|Uc<5Q_=O`VVF?i!%IY_|GB4 z#=)q?#KFxb#KOU3#2_Oi#lfs3#w7sMfC8kLB$&Gxh1wZ8ScIAwf%05}=NK3q7#bj| z7=_S9m=vZyy7S-KOW}HKDP9!C>X?(6oSMWMoSRvaQKZQFsRX{x{o5t`U5z#?$~BE$p$08=bG literal 0 HcmV?d00001 diff --git a/app/src/androidTest/assets/backupTests/chat_item_poll_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_poll_06.binproto new file mode 100644 index 0000000000000000000000000000000000000000..b6833761c5579ffaeb56b0130c3b2743541f73f2 GIT binary patch literal 1088 zcmea}U=+CVYr*{QhEfXsyKEj#$*x#(ig%Lc-3T4SDnN=53x$z@T~eE!J@?C1T;m9#SLhTl_rk?tZezH8@o%F+$t_T-1YmD}2wTN(wQD2D?ZwdU*l8%qYRAz^K7!z-Tc+#)&b} zi80BEG1-GLfH8tGfiZ)zfU$zHfswI;k!cnqI|rjE0|Uc<5Q_=O`VVF?i!%IY_|GB4 z#=)q?#KFxb#KOU3#2_Oi#lfs3#w7sMfC8kLB$&Gxh1wZ8ScIAwf%05}=NK3q7#bj| z7=_S9m=vZyy7S-KOW}HKDP9!C>X?(6oSMWMoSRvaQKZQFs!29VtuN*L3#CVI5i^ndVgC@=y5#)>Y+ literal 0 HcmV?d00001 diff --git a/app/src/androidTest/assets/backupTests/chat_item_poll_07.binproto b/app/src/androidTest/assets/backupTests/chat_item_poll_07.binproto new file mode 100644 index 0000000000000000000000000000000000000000..3da2215a8fac155f113f18485f3b9a6bcb902185 GIT binary patch literal 1123 zcmea}U=+CVYr*{QhEfXsyKEj#$*x#(ig%Lc-3T4SDnN=53x$z@T~eE!J@?C1T;m9#SLhTl_rk?tZezH8@o%F+$t_T-1YmD}2wTN(wQD2D?ZwdU*l8%qYRAz^K7!z-Tc+#)&b} zi80BEG1-GLfH8tGfiZ)zfU$zHfswI;k!cnqI|rjE0|Uc<5Q_=O`VVF?i!%IY_|GB4 z#=)q?#KFxb#KOU3#2_Oi#lfs3#w7sMfC8kLB$&Gxh1wZ8ScIAwf%05}=NK3q7#bj| z7=_S9m=vZyy7S-KOW}HKDP9!C>X?(6oSMWMoSRvaQKZQFsq24U^4qKedm<}hKm?~Gjj2GL}t51 z`1(5)<~pYcFiP=oab+ildpdbIM+NyyX>oD6W+XfNrlw|PT4SDnN=53x$z@T~eE!J@?C1T;m9#SLhTl_rk?tZezH8@o%F+$t_T-1YmD}2wTN(wQD2D?ZwdU*l8%qYRAz^K7!z-Tc+#)&b} zi80BEG1-GLfH8tGfiZ)zfU$zHfswI;k!cnqI|rjE0|Uc<5Q_=O`VVF?i!%IY_|GB4 z#=)q?#KFxb#KOU3#2_Oi#lfs3#w7sMfC8kLB$&Gxh1wZ8ScIAwf%05}=NK3q7#bj| z7=_S9m=vZyy7S-KOW}HKDP9!C>X?(6oSMWMoSRvaQKZQFshRptlD;~Twg$YgU6=0D#01;vW05TUqf&c&j literal 0 HcmV?d00001 diff --git a/app/src/androidTest/assets/backupTests/chat_item_poll_09.binproto b/app/src/androidTest/assets/backupTests/chat_item_poll_09.binproto new file mode 100644 index 0000000000000000000000000000000000000000..06ab5272a301b4def0099798aba3e9720687c204 GIT binary patch literal 941 zcmea}U=+CVYr*{QhEfXsyKEj#$*x#(ig%Lc-3T4SDnN=53x$z@T~eE!J@?C1T;m9#SLhTl_rk?tZezH8@o%F+$t_T-1YmD}2wTN(wQD2D?ZwdU*l8%qYRAz^K7!z-Tc+#)&b} zi80BEG1-GLfH8tGfiZ)zfU$zHfswI;k!cnqI|rjE0|Uc<5Q_=O`VVF?i!%IY_|GB4 z#=)q?#KFxb#KOU3#2_Oi#lfs3#w7sMfC8kLB$&Gxh1wZ8ScIAwf%05}=NK3q7#bj| z7=_S9m=vZyy7S-KOW}HKDP9!C>X?(6oSMWMoSRvaQKZQFs-@F zbxsjrl;Yvy%1#XTbnT4SDnN=53x$z@T~eE!J@?C1T;m9#SLhTl_rk?tZezH8@o%F+$t_T-1YmD}2wTN(wQD2D?ZwdU*l8%qYRAz^K7!z-Tc+#)&b} zi80BEG1-GLfH8tGfiZ)zfU$zHfswI;k!cnqI|rjE0|Uc<5Q_=O`VVF?i!%IY_|GB4 z#=)q?#KFxb#KOU3#2_Oi#lfs3#w7sMfC8kLB$&Gxh1wZ8ScIAwf%05}=NK3q7#bj| z7=_S9m=vZyy7S-KOW}HKDP9!C>X?(6oSMWMoSRvaQKZQFsqQCU^4qWedm<}hKm@pxpwxVW+t!#$lmoTGyLrL?%XTr-lLeN$7jGV+8tI9LVVEZKC89mryVvlt;P cRGkWpT7q0GALdVL0J>rS!xax+nkp~?0A^JWS^xk5 literal 0 HcmV?d00001 diff --git a/app/src/androidTest/assets/backupTests/chat_item_poll_11.binproto b/app/src/androidTest/assets/backupTests/chat_item_poll_11.binproto new file mode 100644 index 0000000000000000000000000000000000000000..891686ecc1973f5eccbc8a8895a448e6db3c3413 GIT binary patch literal 1003 zcmea}U=+CVYr*{QhEfXsyKEj#$*x#(ig%Lc-3T4SDnN=53x$z@T~eE!J@?C1T;m9#SLhTl_rk?tZezH8@o%F+$t_T-1YmD}2wTN(wQD2D?ZwdU*l8%qYRAz^K7!z-Tc+#)&b} zi80BEG1-GLfH8tGfiZ)zfU$zHfswI;k!cnqI|rjE0|Uc<5Q_=O`VVF?i!%IY_|GB4 z#=)q?#KFxb#KOU3#2_Oi#lfs3#w7sMfC8kLB$&Gxh1wZ8ScIAwf%05}=NK3q7#bj| z7=_S9m=vZyy7S-KOW}HKDP9!C>X?(6oSMWMoSRvaQKZQFsP*#bd4RzVu7<5AuKeVDCTGh ha27MTD5 literal 0 HcmV?d00001 diff --git a/app/src/androidTest/assets/backupTests/chat_item_poll_12.binproto b/app/src/androidTest/assets/backupTests/chat_item_poll_12.binproto new file mode 100644 index 0000000000000000000000000000000000000000..dbbcf80f5728308da5e2cc6a5a3cc27459abbb68 GIT binary patch literal 1016 zcmea}U=+CVYr*{QhEfXsyKEj#$*x#(ig%Lc-3T4SDnN=53x$z@T~eE!J@?C1T;m9#SLhTl_rk?tZezH8@o%F+$t_T-1YmD}2wTN(wQD2D?ZwdU*l8%qYRAz^K7!z-Tc+#)&b} zi80BEG1-GLfH8tGfiZ)zfU$zHfswI;k!cnqI|rjE0|Uc<5Q_=O`VVF?i!%IY_|GB4 z#=)q?#KFxb#KOU3#2_Oi#lfs3#w7sMfC8kLB$&Gxh1wZ8ScIAwf%05}=NK3q7#bj| z7=_S9m=vZyy7S-KOW}HKDP9!C>X?(6oSMWMoSRvaQKZQFs7fwAg@e<+U=3o(c+;iaA3Ii_&fv?kdUO8a6h;b4l7mstUb77#L zYq)!nW0e#S7gu&-xTlkcb5xMOlol74YeurOZ)$2*MxGD{2dluFC7Z6X16eF^79)g( Krju-Q6c_=Yz!|;( literal 0 HcmV?d00001 diff --git a/app/src/androidTest/assets/backupTests/chat_item_poll_13.binproto b/app/src/androidTest/assets/backupTests/chat_item_poll_13.binproto new file mode 100644 index 0000000000000000000000000000000000000000..c7cfe15c1004d7a6ec85fd160b713b29e833f6b0 GIT binary patch literal 1051 zcmea}U=+CVYr*{QhEfXsyKEj#$*x#(ig%Lc-3T4SDnN=53x$z@T~eE!J@?C1T;m9#SLhTl_rk?tZezH8@o%F+$t_T-1YmD}2wTN(wQD2D?ZwdU*l8%qYRAz^K7!z-Tc+#)&b} zi80BEG1-GLfH8tGfiZ)zfU$zHfswI;k!cnqI|rjE0|Uc<5Q_=O`VVF?i!%IY_|GB4 z#=)q?#KFxb#KOU3#2_Oi#lfs3#w7sMfC8kLB$&Gxh1wZ8ScIAwf%05}=NK3q7#bj| z7=_S9m=vZyy7S-KOW}HKDP9!C>X?(6oSMWMoSRvaQKZQFsqcGU^4qQedm<}hKm?CGjj2GL}t51 z`1(5)<~pYcFiP=oab+ildpdbIM+NyyX>oD6W+XfNrlw|PT4SDnN=53x$z@T~eE!J@?C1T;m9#SLhTl_rk?tZezH8@o%F+$t_T-1YmD}2wTN(wQD2D?ZwdU*l8%qYRAz^K7!z-Tc+#)&b} zi80BEG1-GLfH8tGfiZ)zfU$zHfswI;k!cnqI|rjE0|Uc<5Q_=O`VVF?i!%IY_|GB4 z#=)q?#KFxb#KOU3#2_Oi#lfs3#w7sMfC8kLB$&Gxh1wZ8ScIAwf%05}=NK3q7#bj| z7=_S9m=vZyy7S-KOW}HKDP9!C>X?(6oSMWMoSRvaQKZQFsPt8VdUa*&UG#f^m7e&FLJDs z;^E@TP7L>S@^Fp{@|V)$;&RPMcJ@t8&C19V;^1Hvc(Y{FHFhA21T4SDnN=53x$z@T~eE!J@?C1T;m9#SLhTl_rk?tZezH8@o%F+$t_T-1YmD}2wTN(wQD2D?ZwdU*l8%qYRAz^K7!z-Tc+#)&b} zi80BEG1-GLfH8tGfiZ)zfU$zHfswI;k!cnqI|rjE0|Uc<5Q_=O`VVF?i!%IY_|GB4 z#=)q?#KFxb#KOU3#2_Oi#lfs3#w7sMfC8kLB$&Gxh1wZ8ScIAwf%05}=NK3q7#bj| z7=_S9m=vZyy7S-KOW}HKDP9!C>X?(6oSMWMoSRvaQKZQFs)>r8_fszic>I6gn0{bqrw5NA?;dZd3T4SDnN=53x$z@T~eE!J@?C1T;m9#SLhTl_rk?tZezH8@o%F+$t_T-1YmD}2wTN(wQD2D?ZwdU*l8%qYRAz^K7!z-Tc+#)&b} zi80BEG1-GLfH8tGfiZ)zfU$zHfswI;k!cnqI|rjE0|Uc<5Q_=O`VVF?i!%IY_|GB4 z#=)q?#KFxb#KOU3#2_Oi#lfs3#w7sMfC8kLB$&Gxh1wZ8ScIAwf%05}=NK3q7#bj| z7=_S9m=vZyy7S-KOW}HKDP9!C>X?(6oSMWMoSRvaQKZQFstwcZ`t_N9w@UZ|BSeQ%j9EvDZ zF>2@tFj}y4NP)~_319>B8rJ9mjoLW?xSE7(!nv`0U ZUX+@rkdm34SfY@aqL7#jVwaTW0suk`BliFR diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_01.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_01.binproto index 6d7f20d88d52e75b170fb98cefa469ab1a217571..5135da028c1bd847d880e845825c9a619d625922 100644 GIT binary patch delta 670 zcmX@e(aXKzJ7awpqfk2|2dhvMBbNXJ12;DVg9AeY0~jz0p^GpnOnY?azqOYFi-03u z6vgb6pOnPvm7kYdT%^dVdoL&V{CfVsr;k2*b&@Yi;!tMhgqkUOYacJDf9yJ?`%zs5 z;|fM5D~5H9LaP}$xTKabaw$OEfSVLx)T$E_;NtU5)lqQF$xH@PKs%-6GD=DcimmkZ zQ!5g43vyERlJj%*6U!1y5{vY*3evUMIG6;OBv=d>twcZ`4hLC)@UZ|BSeQ%j9EvDZ zF>2@tFj}y4NP)~_319>&on+)-p3Kg4T>S@=(pM&syhO{(RkJo2I|*>C zzc}aZX9Iyn2WIw6GL&G9y2`}$eezc(9kmmTTwIyCiRr2OSp})-Qac&BwlOLpi8yR! z_4q6^*_~OwzL}BBfoWDA>y)cMdY_oi+0yHj_u$q3(q(^tr?u^JiI~!#UHFi_{uN7l zjM5|Luo^5|8dT{$N((t8jLU$PG>mb`14M2`JNG zGFUZx+uaX_Q3_{;MLJfrzAv`?zRmQ~{MX_kX*Q)nmI}xDWRpAoA5J#5I;^^UPFCLjGFaiJ*y~bMr delta 336 zcmeC>KFG1*JEH)H6dMPV080Sl8Ahd(j2ujpeVC7{e`Hd6#{?3Vn0a#L>kGzC0vziv z&UyRUKw!~!sFY{jCZc9fBeD>FASJyk!eAT?cT8za|dMkOQ>hc{9l z%Qz>L~Eeq~{#x%$z5M(G!-tJDoTf;cY50XZMCJ%u1Z)i5>w30U=IF8cYUv&t7eK zYiPj`r0}5e=)(LxmuB^FM)d9fxwm@Fj6+Q878JML<2zqi6vMsuj0U5S6PH6uX{JI> zX>v(vu|h$9aY<=TVqS?ter{$-36N1*q>x^klvtwcZ`4hLC)@UZ|BSeQ%j9EvDZ zF>2@tFj}y4NP)~_319>bG!^O=q)}J$PZp#Y)>Edwo&8sapH>{oh z_$SZ&fAZa@JOZzuzTAQy&1+}}EUXYcxd?|ZVf>DD}NSI47IX|yBHMu0Uq*S*^Aulr{Gsj4f gi{-=oNew{19X)*Q#UnEXMu^bFUI7+~V-O)G09zWc3IG5A delta 200 zcmZqSdCallJEH)H6dMPV080R4C$mx;GY8XVALbTD&1;NGml=WLj1sd>u6%vL*o&8o zg@Z+kLE!cDomUPRMr~u{O66b_V3C>}!z`(+@yJ7awpqfk2|2dhvMBbNXJ12;DVg9AeY0~jz0p^GpnOnY?azqOYFi-03u z6vgb6pOnPvm7kYdT%^dVdoL&V{CfVsr;k2*b&@Yi;!tMhgqkUOYacJDf9yJ?`%zs5 z;|fM5D~5H9LaP}$xTKabaw$OEfSVLx)T$E_;NtU5)lqQF$xH@PKs%-6GD=DcimmkZ zQ!5g43vyERlJj%*6U!1y5{vY*3evUMIG6;OBv=d>twcZ`4hLC)@UZ|BSeQ%j9EvDZ zF>2@tFj}y4NP)~_319>B7<-9v z@p7;TJnlJgY=wam69=Qfo9R2R959Uf$jEhp5y)jxI?l+&nOK^VnXjK)U@Wzhk!u^H z5?5w!VtT56RzYgI!!$;Zxh#_zndR%78Mz#K*3CYvz9+9IXYQt-|EBgAY-nuie%ml{ z0k>R@qk7SSFMQV*sxJQ(`-$%t*Brju&!W9kUhYi$VP>Y_cW%C8(TY%smmgPtWmn>> zaCVEx4NeSp4E0C}DAQmtST%dw-4BLQ3jUKSB}DCtE`GniQcPw03#m$;n)8}mTfB7( r)YPKwgGz-o7=>iGq!N>Xp`4qal30|gke8UNP?lO;l9^PRQ<@6^+pVbo delta 275 zcmV+u0qp*Y3e5+w_W=+H8U_dg5Cl*GrvW0Q0SE$kH0tf;S0T`Rfsq4^_ z{R0{=`2h;e0SEyQ1R}%%3JGC#WNB|NZE!OhwgC#W0U`=%ZDD6+FKTdQXFz}(NRbAU zMg$*!fB_0XsDhw3PK;J2)Yr{J`c953j3uBhh6(uoq08n#Uo#S5-4CjGAwO;XX{;An ze`jg>0GWuVW>61E)wY|libB@*7=e%G;RYfJcVS3Sa8Oi2VkiJG-Obg2?J+n5QXsZ! zSNTLh#q8>|*|4pbLg#3#G%a02{lvn);?ZP|JZd(_oKQB z#ubcARt)PHg;q0ia7is=915}k;bQ?NurQb4ITTT- zV${$PV6F{A5h%+j(f)GPtPRFqB3#@Y zECM|TFWg^Zs>C4hcKXgM2MnX8PR?briE`s|$xAFL%~dEYP0YzGE-Xz|$W2VoOH?RL z$^>yrQgd=jixmn|i;7c${G!Zah0MI<)Pj=yVuj+;#A2Z8l9J3~BS9{f5A!EA04+Uw L_}Ys{W(te|EaqH!<6UIdM6plx8aAlqQ#y7Aq9w7nhXgB<7VULg#3#G%a02{lvn);?ZP|JZd(_oKQB z#ubcARt)PHg;q0ia7is=91gMo;bQ?NurQb4ITTT- zV${$PV6>%RXPLPAC-X47sGVTs;>yfTOi$I%Do9P2+R4bZjZq0n#9=F| z$7h+zWz6#R&5T?QyzPk>p7X?C+#r_TdMfv-{|1XadEXq9DnmA1-Pvq93wj?lnYGKCKTPW!|Hir2I*DBK*gBp{Y+wBEIlB^Hg|k~kZg66-W2i?;K$!-! z!K&HY?tU}5(9cH?UwiS$Oo0(1G_hBJMdBDlhzS5EqqN8X delta 327 zcmbQk{eok|cSZpYDK-u!0hR#9CyYuD89A6H`!L^EYhYIT%LEi=l$d*R=;Pp5F7(!hyW6GK%)E_L!9?nP7i) zk+Qedzvfo<*&C0)Q~o~jZb6mw_rl~GkJd>1{d2#YU5T?i(IcQBAjBz2gW2Hj*{cn2 z4J{ag6l}I`IH>mMenX|}b&l#u%iWy5e7ZbsV#chbiS_^ZLhPjVG#G`{xm1gji!uvJ z5*1SOixpCfit>vT5(`RF^GXyFOG{F770OccG81!+1i4r~%%9W%420j?A0C-)qQD3d On%FDABJl?z!~_7SwSV#e diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_06.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_06.binproto index 3b3cec5a36fae73d594187a25ffa88e4a15fde49..e377d45ef8da47a16873076a54ccbbdc14898d88 100644 GIT binary patch delta 426 zcmeBWJtwcZ`4h30&@UZ|BSeQ%j9EvDZ zF>2@tFj}y4NP)~_319>D@6k37$rJiu9~&M*h_?qn}bE* zanFHcD-5(41l~{IdF6m%l-Xn-CP`TtE~&(1phI)>Qxc0(74i~u70ObJOEQy6b4qgo DtG-+? delta 110 zcmX@k-pjh-J0l;56dMPV080R)s**AX(_}AZMYS}g6rd2J#JrO$Utcix65-twcZ`4hLC)@UZ|BSeQ%j9EvDZ zF>2@tFj}y4NP)~_319>B7<-9v z@p7;T^c=i!e~GCP69=Qfhv_@7959Sp$HaAk5y)jxI?l+&nVFlIo~mDvmoBxFk!u^H z5*I`us~|PqVJoZ0XPL?N%<}ckj9d;(v+`J{T>a7e#B|PY3(hwSyQSkfcc^}9%N3!XP~Znk<887s{AMjftLpA56G z{6tGX&v5&4KR4a{d>>uwaK{LX{K~8bMlOeo;{T5Q+@mUQ(H5-i5GXD*AyzTz+T(AB zYU{qdT=`GcwAfYY!Lg#3#G%a02{lvn);?ZP|JZd(_oKQB z#ubcARt)PHg;q0ia7is=91gMo;bQ?NurQb4ITTT- zV${$PV6$V-=6%*Zv5Q3)!NRgjwQ zaDv@qE6-#@X8HOYE(eK8TUX62J9@foqkY%I#mzF-pEGZ6%L@PL;&AlMt1UM-teyV& zC(rzU^4+IA0~;gQ)U3XBk;iM;|W5`Q2Lg#3#G%a02{lvn);?ZP|JZd(_oKQB z#ubcARt)PHg;q0ia7is=91gMo;bQ?NurQb4ITTT- zV${$PV6mnluqX3K22}Uli%-qEERQ>YQqynj(j9l9o zm7pS71*z!{(-=MGvP=$OmalJSO}{>@LgZ1y8Kt{C%#`?bNFgMi}p@=xijsDnVEv$x%rMoD?%k+eq8yLU5T&4*)1YB zI5F5U)FUOJOoPE-)$DC|KNvUSh67S!!`fW>RTRX)XYeK&t`( delta 276 zcmcb~HHTxvcSZpYDK-u!0hR#9?~F=c7&(|G`!IjvU&y31j|nKuD6#P5%GVbr`?5$F z{9@!f$H>7bz@l`Nk&7!cH!(d`zdSXmKx!K!*Jef~s7O{pYPv&%w8uoY$x~V6>l+xk z99A?fF!$>TQ@e8gtn)9wKJ6aW1$u3qKmIK|{mdcWSSaBx|EdZ_``o{oYs4e#(=&fD z%qL5yilvLg#3#G%a02{lvn);?ZP|JZd(_oKQB z#ubcARt)PHg;q0ia7is=91gMo;bQ?NurQb4ITTT- zV${$PV6 z$x_VP^;ujFYLD(WRJva0sGhXk&FRah%hM)i%u1SA|Bug3TF>VG_CG(fr1&?TW8+;? z5ew%Tqr-y=9TU&lWIU;?e!aAIw1t+&j4@oLeCOUZviN{gS0@?xx0+ zwMwb->n4@BdvY&-<|M(W!6@X$<&u|JQktt!SelrVS?pa{nyLVFR$ih)X;LPLQ<9pK zQ(CN0kXlrn3gj1M7As`tC8rjYAl4 delta 171 zcmcb?wUB+ocSZpYDK-u!0hR#9Ym7>l89A6H`!HYRKhCIh1jrU(lvs3f~( Md;7y9vrQBj0gVYZg#Z8m diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_11.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_11.binproto index c38e6ba0591390b0e8a34f5201a75e3f43e2ce27..18c7bfec2b80f54e34d379ef3a3355302838c082 100644 GIT binary patch delta 635 zcmZ3_@tAAFcgFfIMxk~_4pyNiMlJyc25xQ!1_y=)1~6b0LKk6DnD*$-e`_xV76C`R zD2mxBKPidTD?cx_xJZ#z_g+r!`StvNPal2s>Lg#3#G%a02{lvn);?ZP|JZd(_oKQB z#ubcARt)PHg;q0ia7is=91gMo;bQ?NurQb4ITTT- zV${$PV6lk$ajvyaBG){&j;9ja7yo=uz5oEYpF>X8yq zron8mYWB9f9}J@uEDCN-KX9@_DrFx3tC&|(2h!qqsCv!cdw=ajXW#s@ZBwK)7=?tn z1e5dgic^zIQcFsU6!J1NGINXsxmZ5TpVR>K@zKNAUOX~WV1x)w>=j^!0xU{L7`Zqza}(23^$YUSrM5A0ZDv&Bf(T?4q^3K( zk@8r^5hdf}>1$OR3W@`deU+? zr!Su_Pn(!AD`{f=KR!EYJq<=7buQK7Lg#3#G%a02{lvn);?ZP|JZd(_oKQB z#ubcARt)PHg;q0ia7is=91gMo;bQ?NurQb4ITTT- zV${$PV6X?#<0lNi0fL$V<#sC`&Ca L$xJHEDa{1{?crVL delta 117 zcmeyyxrcqjcSZpYDK-u!0hR#9$4p8Om^hd=`!L5bhKDJI07V%kmYiJq`hu~S2p2a8 zi@@Wa1IJbvcrgfkoxbzR0mCRmE;bHE0TvA=A$2a*l+@zXqSCw)h4j*-)S~pF)I5ch T%;dxpg~Swv#AFb=q%;=*2P7n^ diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_13.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_13.binproto index ed25e6213b0319bad7597ddb2249a57814f5a0df..067f763b7204d68b0d1646a4601a51325871c72f 100644 GIT binary patch delta 506 zcmbQs`iyLg#3#G%a02{lvn);?ZP|JZd(_oKQB z#ubcARt)PHg;q0ia7is=To1AU;bQ?NurQb4ITTT- zV${$PV62a7<@!3+0`mY8}m0Tq6mzVpff!>D8~kS-PtW+68&m%PN1(p-hY(!`w1 z;=;gtPAw?OFIFfnO)LhgE-A?@ YHWK7w`7nP{1JLfHhp)YOWTwCf0Mfd3kN^Mx delta 175 zcmaFHK9_aFcgA`SDK-u!0hRzpVI@HjLxRzXje}8uQG#(2BSSl*QVSzclu=^o$(64! z7<-9v@p7;T^c=i!e~GCV6Hwi^={v6+FpP@l0%>B=U>0)Xa!4u7RLCh!E-5WmD9A4^ zDa}dDD^bYL%`7PaGD?dS(o2(4i_(iy^Ark8)iV_eauQ4O^HOsW;zoj8EFb1iY5>~% Md;7y9vrQBj0X$MRga7~l diff --git a/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_14.binproto b/app/src/androidTest/assets/backupTests/chat_item_standard_message_with_quote_14.binproto index b88dbd67183b385d9ba472cb8f64d07457ee8fd7..2c8d86c6e5e77b2d26a274e00575a46fa37f0689 100644 GIT binary patch delta 525 zcmZ3<`h$JLcgFfIMxk~_4pyNiMlJyc25xQ!1_y=)1~6b0LKk6DnD*$-e`_xV76C`R zD2mxBKPidTD?cx_xJZ#z_g+r!`StvNPal2s>Lg#3#G%a02{lvn);?ZP|JZd(_oKQB z#ubcARt)PHg;q0ia7is=To1AU;bQ?NurQb4ITTT- zV${$PV6P#+`_Vr zQK^{`sDx2s*~yi!FHBy@ES#3gB?45;B88$*gHcGGOSL$;D6^m>Q6V+ISRu8jD8EP{ zv7jV1uS6lSv?MiGp)55oGcnglkc;KR{7DT!Lw|37cx1MT0wY9dVlU7se;`6k02-w) AJ^%m! diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/backup/v2/ArchiveImportExportTests.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/backup/v2/ArchiveImportExportTests.kt index b9001228dd..6a4008aacb 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/backup/v2/ArchiveImportExportTests.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/backup/v2/ArchiveImportExportTests.kt @@ -211,6 +211,11 @@ class ArchiveImportExportTests { runTests { it.startsWith("chat_item_view_once_") } } +// @Test + fun chatItemPoll() { + runTests { it.startsWith("chat_item_poll_") } + } + // @Test fun notificationProfiles() { runTests { it.startsWith("notification_profile_") } diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ArchiveErrorCases.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ArchiveErrorCases.kt index c7446693c8..0c7d321da2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ArchiveErrorCases.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/ArchiveErrorCases.kt @@ -123,6 +123,14 @@ object ExportSkips { return log(sentTimestamp, "Poll terminate update was empty.") } + fun invalidPollQuestion(sentTimestamp: Long): String { + return log(sentTimestamp, "Poll question was invalid.") + } + + fun invalidPollOption(sentTimestamp: Long): String { + return log(sentTimestamp, "Poll option was invalid.") + } + fun individualChatUpdateInWrongTypeOfChat(sentTimestamp: Long): String { return log(sentTimestamp, "A chat update that only makes sense for individual chats was found in a different kind of chat.") } diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ChatItemArchiveExporter.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ChatItemArchiveExporter.kt index 74f2b7d903..d12caf267f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ChatItemArchiveExporter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/exporters/ChatItemArchiveExporter.kt @@ -117,6 +117,8 @@ private val TAG = Log.tag(ChatItemArchiveExporter::class.java) private val MAX_INLINED_BODY_SIZE = 128.kibiBytes.bytes.toInt() private val MAX_INLINED_BODY_SIZE_WITH_LONG_ATTACHMENT_POINTER = 2.kibiBytes.bytes.toInt() private val MAX_INLINED_QUOTE_BODY_SIZE = 2.kibiBytes.bytes.toInt() +private const val MAX_POLL_CHARACTER_LENGTH = 100 +private const val MAX_POLL_OPTIONS = 10 /** * An iterator for chat items with a clever performance twist: rather than do the extra queries one at a time (for reactions, @@ -386,7 +388,15 @@ class ChatItemArchiveExporter( extraData.pollsById[record.id] != null -> { val poll = extraData.pollsById[record.id]!! - builder.poll = poll.toRemotePollMessage() + if (poll.question.isEmpty() || poll.question.length > MAX_POLL_CHARACTER_LENGTH) { + Log.w(TAG, ExportSkips.invalidPollQuestion(record.dateSent)) + continue + } + if (poll.pollOptions.isEmpty() || poll.pollOptions.size > MAX_POLL_OPTIONS || poll.pollOptions.any { it.text.isEmpty() || it.text.length > MAX_POLL_CHARACTER_LENGTH }) { + Log.w(TAG, ExportSkips.invalidPollOption(record.dateSent)) + continue + } + builder.poll = poll.toRemotePollMessage(reactionRecords = extraData.reactionsById[record.id]) transformTimer.emit("poll") } @@ -492,7 +502,7 @@ class ChatItemArchiveExporter( val pollsFuture = executor.submitTyped { extraDataTimer.timeEvent("polls") { - db.pollTable.getPollsForMessages(messageIds) + db.pollTable.getPollsForMessages(messageIds = messageIds, includePending = false) } } @@ -1167,7 +1177,7 @@ private fun BackupMessageRecord.toRemoteGiftBadgeUpdate(): BackupGiftBadge? { ) } -private fun PollRecord.toRemotePollMessage(): Poll { +private fun PollRecord.toRemotePollMessage(reactionRecords: List?): Poll { return Poll( question = this.question, allowMultiple = this.allowMultipleVotes, @@ -1182,7 +1192,8 @@ private fun PollRecord.toRemotePollMessage(): Poll { ) } ) - } + }, + reactions = reactionRecords?.toRemote() ?: emptyList() ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/importer/ChatItemArchiveImporter.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/importer/ChatItemArchiveImporter.kt index 6abfb6deca..179db21afa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/importer/ChatItemArchiveImporter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/importer/ChatItemArchiveImporter.kt @@ -693,6 +693,7 @@ class ChatItemArchiveImporter( this.stickerMessage != null -> this.stickerMessage.reactions this.viewOnceMessage != null -> this.viewOnceMessage.reactions this.directStoryReplyMessage != null -> this.directStoryReplyMessage.reactions + this.poll != null -> this.poll.reactions else -> emptyList() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/PollTables.kt b/app/src/main/java/org/thoughtcrime/securesms/database/PollTables.kt index b75e16f71f..e3e82703a7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/PollTables.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/PollTables.kt @@ -607,7 +607,7 @@ class PollTables(context: Context?, databaseHelper: SignalDatabase?) : DatabaseT /** * Maps message ids to its associated poll (if it exists) */ - fun getPollsForMessages(messageIds: Collection): Map { + fun getPollsForMessages(messageIds: Collection, includePending: Boolean = true): Map { if (messageIds.isEmpty() || !Recipient.isSelfSet) { return emptyMap() } @@ -625,9 +625,9 @@ class PollTables(context: Context?, databaseHelper: SignalDatabase?) : DatabaseT val (pendingAdds, pendingRemoves) = getPendingVotes(pollId) val pollOptions = getPollOptions(pollId).map { option -> val voters = pollVotes[option.key] ?: emptyList() - val voteState = if (pendingAdds.contains(option.key)) { + val voteState = if (includePending && pendingAdds.contains(option.key)) { VoteState.PENDING_ADD - } else if (pendingRemoves.contains(option.key)) { + } else if (includePending && pendingRemoves.contains(option.key)) { VoteState.PENDING_REMOVE } else if (voters.any { it.id == self }) { VoteState.ADDED diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/DataMessageProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/messages/DataMessageProcessor.kt index cac927e098..707a999da6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/DataMessageProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/DataMessageProcessor.kt @@ -120,6 +120,8 @@ import kotlin.time.Duration.Companion.seconds object DataMessageProcessor { private const val BODY_RANGE_PROCESSING_LIMIT = 250 + private const val POLL_CHARACTER_LIMIT = 100 + private const val POLL_OPTIONS_LIMIT = 10 fun process( context: Context, @@ -1079,6 +1081,16 @@ object DataMessageProcessor { return null } + if (poll.question == null || poll.question!!.isEmpty() || poll.question!!.length > POLL_CHARACTER_LIMIT) { + warn(envelope.timestamp!!, "[handlePollCreate] Poll question is invalid.") + return null + } + + if (poll.options.isEmpty() || poll.options.size > POLL_OPTIONS_LIMIT || poll.options.any { it.isEmpty() || it.length > POLL_CHARACTER_LIMIT }) { + warn(envelope.timestamp!!, "[handlePollCreate] Poll option is invalid.") + return null + } + val pollMessage = IncomingMessage( type = MessageType.NORMAL, from = senderRecipient.id, diff --git a/app/src/main/protowire/Backup.proto b/app/src/main/protowire/Backup.proto index 306898922f..1d14e01826 100644 --- a/app/src/main/protowire/Backup.proto +++ b/app/src/main/protowire/Backup.proto @@ -824,6 +824,7 @@ message Poll { bool allowMultiple = 2; repeated PollOption options = 3; // At least two bool hasEnded = 4; + repeated Reaction reactions = 5; } message ChatUpdateMessage {