Browse Source

android: parse decimal channel IDs for avatar requests and group keys

master
evgeny 1 week ago
parent
commit
eae3ef5c32
  1. 2
      tools/chatgui-android/app/src/main/java/com/utun/chat/data/AvatarProtocol.kt
  2. 14
      tools/chatgui-android/app/src/main/java/com/utun/chat/data/AvatarRepository.kt
  3. 4
      tools/chatgui-android/jni_bridge/android_jni_bridge.c

2
tools/chatgui-android/app/src/main/java/com/utun/chat/data/AvatarProtocol.kt

@ -9,6 +9,8 @@ object AvatarProtocol {
const val MAX_GROUP = 16 * 1024
private val filePattern = Regex("[0-9a-f]{64}\\.png")
fun validFile(file: String): Boolean = filePattern.matches(file)
// channel_id в БД/событиях — десятичный u64; avatar_server в userinfo — hex.
fun groupId(id: String): Long = id.toULongOrNull(10)?.toLong() ?: 0
fun node(id: String): Long = id.toULongOrNull(16)?.toLong() ?: 0
fun hex(id: Long): String = id.toULong().toString(16).padStart(16, '0')
fun hash(bytes: ByteArray): String = bytes.joinToString("") { "%02x".format(it.toInt() and 255) }

14
tools/chatgui-android/app/src/main/java/com/utun/chat/data/AvatarRepository.kt

@ -182,7 +182,10 @@ class AvatarRepository(context: Context) {
}
private fun requestMembers(group: String) {
if (account == 0L) start()
if (account == 0L || AvatarProtocol.node(group) == 0L) return
if (account == 0L) return
if (AvatarProtocol.groupId(group) == 0L) {
log("WARN", "Member snapshot: invalid decimal channel_id=$group"); return
}
val now = android.os.SystemClock.elapsedRealtime()
if (now - (memberRequests[group] ?: -5000) < 5000) return
memberRequests[group] = now
@ -191,12 +194,14 @@ class AvatarRepository(context: Context) {
private suspend fun request(type: Int, group: String, server: Long = 0, owner: Long = 0, command: Int = 0,
enqueue: (Long, Long) -> Boolean): ByteArray {
val id = ids.incrementAndGet(); val gid = AvatarProtocol.node(group)
val id = ids.incrementAndGet(); val gid = AvatarProtocol.groupId(group)
require(gid != 0L) { "invalid decimal channel_id=$group" }
val result = CompletableDeferred<ByteArray>()
val operation = Pending(type, gid, server, owner, command, result)
pending[id] = operation
var complete = false
try {
log("DEBUG", "Request id=$id type=$type group=$group parsedGroup=${gid.toULong()} server=${AvatarProtocol.hex(server)}")
if (!enqueue(id, gid)) throw IOException("native enqueue failed id=$id type=$type group=$group")
val data = withTimeout(60_000) { result.await() }
complete = true
@ -209,7 +214,10 @@ class AvatarRepository(context: Context) {
fun ensureGroup(group: String, force: Boolean = false) {
if (account == 0L) start()
if (account == 0L || AvatarProtocol.node(group) == 0L) return
if (account == 0L) return
if (AvatarProtocol.groupId(group) == 0L) {
log("WARN", "Group snapshot: invalid decimal channel_id=$group"); return
}
if ("group:$group" in loads) { if (force) dirtyGroups.add(group); return }
val current = _groups.value[group]
if (!force && current != null && !current.error &&

4
tools/chatgui-android/jni_bridge/android_jni_bridge.c

@ -2684,8 +2684,8 @@ static void android_avatar_snapshot(void* arg) {
struct group_avatar_record record;
memset(&record, 0, sizeof(record));
int failed = group_avatar_get(req->inst, req->group, &record) < 0;
char channel[17]; uint8_t key[32];
snprintf(channel, sizeof(channel), "%016llx", (unsigned long long)req->group);
char channel[32]; uint8_t key[32];
snprintf(channel, sizeof(channel), "%llu", (unsigned long long)req->group);
int can_edit = topo_node_sqlite_channel_get_priv(chat_core_get_db(req->inst), channel, key) == 0;
memset(key, 0, sizeof(key));
if (failed) DEBUG_WARN(DEBUG_CATEGORY_CHAT, "Android avatar: snapshot failed group=%s id=%llu", channel,

Loading…
Cancel
Save