Repository navigation
fix: received large images show 'not available' (array-format extraction corruption) - #1211
Merged
Merged
Conversation
Every Columba sender puts LXMF field 6 on the wire as [format, bytes],
and both backends serialize a received image as the JSON array
["jpg", "<hex>"]. When such a field exceeded the 500KB extraction
threshold, the generic path stored the whole array string to disk and
replaced the field with a bare {"_file_ref": path} object. The message
mapper hex-decodes file-ref payloads, so it tried to hex-decode
["jpg",... , failed, and the bubble rendered "image not available".
Images under the threshold (LOW/MEDIUM presets) stayed inline and
worked, which is why the bug looked intermittent.
Mirror the audio (field 7) handling: extraction now writes only the hex
payload and keeps the array shape as ["jpg", {"_file_ref": path}]. The
loader resolves a file ref nested in the array, and file-ref payloads
that contain a whole array string (written by the old code) are unwrapped
so already-received "not available" messages heal without re-download.
hasImageField in MessageMapper and MessagingViewModel recognize the new
shape.
Contributor
[Medium impact] The PR appears safe to merge; no actionable new issues were found. SummaryFixes large received images by saving only their hex payload and preserving the image array.
Diagram%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Received image array] --> B{Large hex payload?}
B -->|No| C[Keep image inline]
B -->|Yes| D[Save hex payload to disk]
D --> E[Keep format and nested file reference]
E --> F[loadImageBytes]
G[Legacy whole-array file] --> H[unwrapArrayPayload]
H --> F
F --> I[Decode image bytes]
Reviews (2) · Last reviewed commit: "fix(data): keep array shape when extract..." · Reviewed by Greptile |
Owner
Author
|
@greptile review |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Receiving an image attachment sometimes renders "image not available" (user-reported, most visible with Columba-iOS senders).
Every Columba sender puts LXMF field 6 on the wire as
[format, bytes](NativeMessageSender.kt:145, Columba-iOSRnsLxmf; the iOS interop test pins the shape: "the on-wire shape is [format_str, bytes]"), and both Android backends serialize a received image field as the JSON array["jpg", "<hex>"].When such a field exceeded the 500 KB attachment-extraction threshold,
ConversationRepository.extractLargeAttachmentstook the generic branch: it stored the whole array string["jpg","ffd8..."]to disk and replaced the field with a bare{"_file_ref": path}object.MessageMapper.loadImageByteshex-decodes file-ref payloads, so it tried to hex-decode["jpg",...→hexStringToByteArraythrew → null → the UI showed "not available".hasImageFieldstill returned true (bare file ref), so the bubble appeared with no image.Images below the threshold (LOW/MEDIUM presets, small photos) stayed inline and decoded fine — hence "sometimes". Audio (field 7) already had special handling; image (field 6) was missed.
Fix
ConversationRepository): newextractImageAttachmentForStoragemirrors the audio path — writes only the hex payload to disk and keeps the array shape:["jpg", {"_file_ref": path}].MessageMapper.loadImageBytes): resolves a_file_refnested in the array, andunwrapArrayPayloadrecovers payloads written by the old code (whole-array files), so already-received "not available" messages heal on next display without re-download.hasImageFieldinMessageMapperandMessagingViewModelrecognize the array+file-ref shape.Tests
ConversationRepositoryImageExtractionTest(data): red-before/passing-after repro — large array-format field 6 extracts to pure hex with array shape kept; hex-string format regression guard; small arrays untouched.MessageMapperTest(app): inline array decode, nested file-ref resolution, legacy whole-array recovery, staging fallback,hasImageAttachmentfor the new shape.:datasuite,MessageMapperTest,MessagingViewModelTest, and:app:detekt/:data:detektall pass.