From a720c8900b6e0b9f8a00eda551043149526f2c01 Mon Sep 17 00:00:00 2001 From: Phillip Davis Date: Sat, 4 Apr 2026 13:51:10 -0400 Subject: [PATCH] fix sending oversized `WebxdcUpdate`s manually checked that the delete query works even when the rows are in the SqliteBlobTooBigException range --- src/cheogram/res/raw/webxdc.js | 6 +- .../persistance/DatabaseBackend.java | 56 +++++++++++++------ 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/cheogram/res/raw/webxdc.js b/src/cheogram/res/raw/webxdc.js index ca82e2a3d0a1041ca8dc412d486d19cdc442f746..11b8b84af88cda41a232f8ffb92b4447d1f2eaf9 100644 --- a/src/cheogram/res/raw/webxdc.js +++ b/src/cheogram/res/raw/webxdc.js @@ -39,7 +39,11 @@ window.webxdc = (() => { }, sendUpdate: (payload, descr) => { - InternalJSApi.sendStatusUpdate(JSON.stringify(payload), descr); + var serialized = JSON.stringify(payload); + if (serialized.length > 128 * 1024) { + throw new Error("sendUpdate() payload too large: " + serialized.length + " bytes (max 128 KB)"); + } + InternalJSApi.sendStatusUpdate(serialized, descr); }, importFiles: (filters) => { diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index c6cfcf9e37e374d455875443afd62ede9152513b..1d78675362f288d2091c79655bb9638451de5841 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -1496,6 +1496,16 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.insertWithOnConflict("cheogram.webxdc_updates", null, update.getContentValues(), SQLiteDatabase.CONFLICT_IGNORE); } + private int deleteOversizedWebxdcUpdates(SQLiteDatabase db, String conversationUuid, String thread) { + int deleted = db.delete("cheogram.webxdc_updates", + Message.CONVERSATION + "=? AND thread=? AND length(payload) > 131072", + new String[]{conversationUuid, thread}); + if (deleted > 0) { + Log.w(Config.LOGTAG, "Deleted " + deleted + " oversized webxdc update(s) for thread " + thread); + } + return deleted; + } + public WebxdcUpdate findLastWebxdcUpdate(Message message) { if (message.getThread() == null) { Log.w(Config.LOGTAG, "WebXDC message with no thread!"); @@ -1507,12 +1517,19 @@ public class DatabaseBackend extends SQLiteOpenHelper { Cursor cursor = db.query("cheogram.webxdc_updates", null, Message.CONVERSATION + "=? AND thread=?", selectionArgs, null, null, "serial ASC"); - WebxdcUpdate update = null; - if (cursor.moveToLast()) { - update = new WebxdcUpdate(cursor, cursor.getLong(cursor.getColumnIndex("serial"))); + try { + WebxdcUpdate update = null; + if (cursor.moveToLast()) { + update = new WebxdcUpdate(cursor, cursor.getLong(cursor.getColumnIndex("serial"))); + } + return update; + } catch (final android.database.sqlite.SQLiteBlobTooBigException e) { + Log.w(Config.LOGTAG, "findLastWebxdcUpdate: blob too big, deleting oversized rows", e); + deleteOversizedWebxdcUpdates(db, message.getConversation().getUuid(), message.getThread().getContent()); + return findLastWebxdcUpdate(message); + } finally { + cursor.close(); } - cursor.close(); - return update; } public List findWebxdcUpdates(Message message, long serial) { @@ -1521,19 +1538,26 @@ public class DatabaseBackend extends SQLiteOpenHelper { Cursor cursor = db.query("cheogram.webxdc_updates", null, Message.CONVERSATION + "=? AND thread=? AND serial>?", selectionArgs, null, null, "serial ASC"); - long maxSerial = 0; - if (cursor.moveToLast()) { - maxSerial = cursor.getLong(cursor.getColumnIndex("serial")); - } - cursor.moveToFirst(); - cursor.moveToPrevious(); + try { + long maxSerial = 0; + if (cursor.moveToLast()) { + maxSerial = cursor.getLong(cursor.getColumnIndex("serial")); + } + cursor.moveToFirst(); + cursor.moveToPrevious(); - List updates = new ArrayList<>(); - while (cursor.moveToNext()) { - updates.add(new WebxdcUpdate(cursor, maxSerial)); + List updates = new ArrayList<>(); + while (cursor.moveToNext()) { + updates.add(new WebxdcUpdate(cursor, maxSerial)); + } + return updates; + } catch (final android.database.sqlite.SQLiteBlobTooBigException e) { + Log.w(Config.LOGTAG, "findWebxdcUpdates: blob too big, deleting oversized rows", e); + deleteOversizedWebxdcUpdates(db, message.getConversation().getUuid(), message.getThread().getContent()); + return findWebxdcUpdates(message, serial); + } finally { + cursor.close(); } - cursor.close(); - return updates; } public void createConversation(Conversation conversation) {