Force Nameprepping of JID domain parts
The IDN.toAscii()/IDN.toUnicode() family only namepreps the original domain passed to it if it contained non-ASCII characters. This means that for all-ASCII domains, no canonicalization is performed, which leads to issues like case-sensitivity. This workaround explicitly namepreps domain parts before calling IDN.toAscii() on them, in order to get a canonicalized representation (most notably, case invariance). A basic DB migration is also included.
This commit is contained in:
parent
8dfa701043
commit
b69ee7125d
|
@ -4,11 +4,13 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
import eu.siacs.conversations.entities.Contact;
|
||||
import eu.siacs.conversations.entities.Conversation;
|
||||
import eu.siacs.conversations.entities.Message;
|
||||
import eu.siacs.conversations.entities.Roster;
|
||||
import eu.siacs.conversations.xmpp.jid.InvalidJidException;
|
||||
import eu.siacs.conversations.xmpp.jid.Jid;
|
||||
|
||||
import android.content.Context;
|
||||
|
@ -16,13 +18,14 @@ import android.database.Cursor;
|
|||
import android.database.sqlite.SQLiteCantOpenDatabaseException;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.util.Log;
|
||||
|
||||
public class DatabaseBackend extends SQLiteOpenHelper {
|
||||
|
||||
private static DatabaseBackend instance = null;
|
||||
|
||||
private static final String DATABASE_NAME = "history";
|
||||
private static final int DATABASE_VERSION = 13;
|
||||
private static final int DATABASE_VERSION = 14;
|
||||
|
||||
private static String CREATE_CONTATCS_STATEMENT = "create table "
|
||||
+ Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, "
|
||||
|
@ -130,6 +133,88 @@ public class DatabaseBackend extends SQLiteOpenHelper {
|
|||
db.execSQL("delete from "+Contact.TABLENAME);
|
||||
db.execSQL("update "+Account.TABLENAME+" set "+Account.ROSTERVERSION+" = NULL");
|
||||
}
|
||||
if (oldVersion < 14 && newVersion >= 14) {
|
||||
// migrate db to new, canonicalized JID domainpart representation
|
||||
|
||||
// Conversation table
|
||||
Cursor cursor = db.rawQuery("select * from " + Conversation.TABLENAME, new String[0]);
|
||||
while(cursor.moveToNext()) {
|
||||
String newJid;
|
||||
try {
|
||||
newJid = Jid.fromString(
|
||||
cursor.getString(cursor.getColumnIndex(Conversation.CONTACTJID))
|
||||
).toString();
|
||||
} catch (InvalidJidException ignored) {
|
||||
Log.e(Config.LOGTAG, "Failed to migrate Conversation CONTACTJID "
|
||||
+cursor.getString(cursor.getColumnIndex(Conversation.CONTACTJID))
|
||||
+": " + ignored +". Skipping...");
|
||||
continue;
|
||||
}
|
||||
|
||||
String updateArgs[] = {
|
||||
newJid,
|
||||
cursor.getString(cursor.getColumnIndex(Conversation.UUID)),
|
||||
};
|
||||
db.execSQL("update " + Conversation.TABLENAME
|
||||
+ " set " + Conversation.CONTACTJID + " = ? "
|
||||
+ " where " + Conversation.UUID + " = ?", updateArgs);
|
||||
}
|
||||
cursor.close();
|
||||
|
||||
// Contact table
|
||||
cursor = db.rawQuery("select * from " + Contact.TABLENAME, new String[0]);
|
||||
while(cursor.moveToNext()) {
|
||||
String newJid;
|
||||
try {
|
||||
newJid = Jid.fromString(
|
||||
cursor.getString(cursor.getColumnIndex(Contact.JID))
|
||||
).toString();
|
||||
} catch (InvalidJidException ignored) {
|
||||
Log.e(Config.LOGTAG, "Failed to migrate Contact JID "
|
||||
+cursor.getString(cursor.getColumnIndex(Contact.JID))
|
||||
+": " + ignored +". Skipping...");
|
||||
continue;
|
||||
}
|
||||
|
||||
String updateArgs[] = {
|
||||
newJid,
|
||||
cursor.getString(cursor.getColumnIndex(Contact.ACCOUNT)),
|
||||
cursor.getString(cursor.getColumnIndex(Contact.JID)),
|
||||
};
|
||||
db.execSQL("update " + Contact.TABLENAME
|
||||
+ " set " + Contact.JID + " = ? "
|
||||
+ " where " + Contact.ACCOUNT + " = ? "
|
||||
+ " AND " + Contact.JID + " = ?", updateArgs);
|
||||
}
|
||||
cursor.close();
|
||||
|
||||
// Account table
|
||||
cursor = db.rawQuery("select * from " + Account.TABLENAME, new String[0]);
|
||||
while(cursor.moveToNext()) {
|
||||
String newServer;
|
||||
try {
|
||||
newServer = Jid.fromParts(
|
||||
cursor.getString(cursor.getColumnIndex(Account.USERNAME)),
|
||||
cursor.getString(cursor.getColumnIndex(Account.SERVER)),
|
||||
"mobile"
|
||||
).getDomainpart();
|
||||
} catch (InvalidJidException ignored) {
|
||||
Log.e(Config.LOGTAG, "Failed to migrate Account SERVER "
|
||||
+cursor.getString(cursor.getColumnIndex(Account.SERVER))
|
||||
+": " + ignored +". Skipping...");
|
||||
continue;
|
||||
}
|
||||
|
||||
String updateArgs[] = {
|
||||
newServer,
|
||||
cursor.getString(cursor.getColumnIndex(Account.UUID)),
|
||||
};
|
||||
db.execSQL("update " + Account.TABLENAME
|
||||
+ " set " + Account.SERVER + " = ? "
|
||||
+ " where " + Account.UUID + " = ?", updateArgs);
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized DatabaseBackend getInstance(Context context) {
|
||||
|
|
|
@ -130,12 +130,19 @@ public final class Jid {
|
|||
if (resourcepart.isEmpty() || resourcepart.length() > 1023) {
|
||||
throw new InvalidJidException(InvalidJidException.INVALID_PART_LENGTH);
|
||||
}
|
||||
dp = IDN.toUnicode(jid.substring(domainpartStart, slashLoc), IDN.USE_STD3_ASCII_RULES);
|
||||
try {
|
||||
dp = IDN.toUnicode(Stringprep.nameprep(jid.substring(domainpartStart, slashLoc)), IDN.USE_STD3_ASCII_RULES);
|
||||
} catch (final StringprepException e) {
|
||||
throw new InvalidJidException(InvalidJidException.STRINGPREP_FAIL, e);
|
||||
}
|
||||
finaljid = finaljid + dp + "/" + rp;
|
||||
} else {
|
||||
resourcepart = "";
|
||||
dp = IDN.toUnicode(jid.substring(domainpartStart, jid.length()),
|
||||
IDN.USE_STD3_ASCII_RULES);
|
||||
try{
|
||||
dp = IDN.toUnicode(Stringprep.nameprep(jid.substring(domainpartStart, jid.length())), IDN.USE_STD3_ASCII_RULES);
|
||||
} catch (final StringprepException e) {
|
||||
throw new InvalidJidException(InvalidJidException.STRINGPREP_FAIL, e);
|
||||
}
|
||||
finaljid = finaljid + dp;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue