try to detect invalid nick (w/ emoji) in MUCs

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/entities/MucOptions.java     |  1 
src/main/java/eu/siacs/conversations/parser/PresenceParser.java   | 47 
src/main/java/eu/siacs/conversations/ui/ConversationFragment.java |  2 
src/main/res/values/strings.xml                                   |  1 
4 files changed, 37 insertions(+), 14 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/parser/PresenceParser.java πŸ”—

@@ -72,10 +72,7 @@ public class PresenceParser extends AbstractParser implements
 								|| ((codes.isEmpty() || codes.contains(MucOptions.STATUS_CODE_ROOM_CREATED)) && jid.equals(item.getAttributeAsJid("jid")))) {
 							mucOptions.setOnline();
 							mucOptions.setSelf(user);
-							if (mucOptions.onRenameListener != null) {
-								mucOptions.onRenameListener.onSuccess();
-								mucOptions.onRenameListener = null;
-							}
+							invokeRenameListener(mucOptions, true);
 						}
 						boolean isNew = mucOptions.updateUser(user);
 						final AxolotlService axolotlService = conversation.getAccount().getAxolotlService();
@@ -143,27 +140,50 @@ public class PresenceParser extends AbstractParser implements
 					}
 				}
 			} else if (type.equals("error")) {
-				Element error = packet.findChild("error");
-				if (error != null && error.hasChild("conflict")) {
+				final Element error = packet.findChild("error");
+				if (error == null) {
+					return;
+				}
+				if (error.hasChild("conflict")) {
 					if (mucOptions.online()) {
-						if (mucOptions.onRenameListener != null) {
-							mucOptions.onRenameListener.onFailure();
-							mucOptions.onRenameListener = null;
-						}
+						invokeRenameListener(mucOptions, false);
 					} else {
 						mucOptions.setError(MucOptions.Error.NICK_IN_USE);
 					}
-				} else if (error != null && error.hasChild("not-authorized")) {
+				} else if (error.hasChild("not-authorized")) {
 					mucOptions.setError(MucOptions.Error.PASSWORD_REQUIRED);
-				} else if (error != null && error.hasChild("forbidden")) {
+				} else if (error.hasChild("forbidden")) {
 					mucOptions.setError(MucOptions.Error.BANNED);
-				} else if (error != null && error.hasChild("registration-required")) {
+				} else if (error.hasChild("registration-required")) {
 					mucOptions.setError(MucOptions.Error.MEMBERS_ONLY);
+				} else {
+					final String text = error.findChildContent("text");
+					if (text != null && text.contains("attribute 'to'")) {
+						if (mucOptions.online()) {
+							invokeRenameListener(mucOptions, false);
+						} else {
+							mucOptions.setError(MucOptions.Error.INVALID_NICK);
+						}
+					} else {
+						mucOptions.setError(MucOptions.Error.UNKNOWN);
+						Log.d(Config.LOGTAG, "unknown error in conference: " + packet);
+					}
 				}
 			}
 		}
 	}
 
+	private static void invokeRenameListener(final MucOptions options, boolean success) {
+		if (options.onRenameListener != null) {
+			if (success) {
+				options.onRenameListener.onSuccess();
+			} else {
+				options.onRenameListener.onFailure();
+			}
+			options.onRenameListener = null;
+		}
+	}
+
 	private static List<String> getStatusCodes(Element x) {
 		List<String> codes = new ArrayList<>();
 		if (x != null) {
@@ -292,5 +312,4 @@ public class PresenceParser extends AbstractParser implements
 			this.parseContactPresence(packet, account);
 		}
 	}
-
 }

src/main/java/eu/siacs/conversations/ui/ConversationFragment.java πŸ”—

@@ -1109,6 +1109,8 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 				case UNKNOWN:
 					showSnackbar(R.string.conference_unknown_error, R.string.try_again, joinMuc);
 					break;
+				case INVALID_NICK:
+					showSnackbar(R.string.invalid_muc_nick, R.string.edit, clickToMuc);
 				case SHUTDOWN:
 					showSnackbar(R.string.conference_shutdown, R.string.try_again, joinMuc);
 					break;

src/main/res/values/strings.xml πŸ”—

@@ -30,6 +30,7 @@
 	<string name="message_decrypting">Decrypting message. Please wait…</string>
 	<string name="pgp_message">OpenPGP encrypted message</string>
 	<string name="nick_in_use">Nickname is already in use</string>
+	<string name="invalid_muc_nick">Invalid nickname</string>
 	<string name="admin">Admin</string>
 	<string name="owner">Owner</string>
 	<string name="moderator">Moderator</string>