Skip to content

fix plaud _parseAudioChunk RangeError on truncated BLE packets#7998

Merged
kodjima33 merged 1 commit into
mainfrom
fix/plaud-parse-audio-chunk-range-error
Jun 18, 2026
Merged

fix plaud _parseAudioChunk RangeError on truncated BLE packets#7998
kodjima33 merged 1 commit into
mainfrom
fix/plaud-parse-audio-chunk-range-error

Conversation

@krushnarout

Copy link
Copy Markdown
Member

Crash

PlaudDeviceConnection._parseAudioChunkRangeError (end): Invalid value: Not in inclusive range 9..189: 255

Crashlytics: https://console.firebase.google.com/u/0/project/based-hardware/crashlytics/app/ios:com.friend-app-with-wearable.ios12/issues/89db02e25fcf378409caf8a02d4d59ca?time=7d&types=crash&sessionEventKey=5daa07a501fd4234b65d76937d9783ca_2230583383207987879

Fatal Exception: FlutterError
0  ???   0x0 _TypedIntListMixin.sublist (dart:typed_data)
1  ???   0x0 PlaudDeviceConnection._parseAudioChunk + 75 (plaud_connection.dart:75)
2  ???   0x0 PlaudDeviceConnection._handleNotification + 58 (plaud_connection.dart:58)

Cause

_parseAudioChunk reads byte 8 of the BLE notification payload as the audio data length, then calls payload.sublist(9, 9 + length) without checking that the slice fits within the buffer. When a truncated or malformed packet arrives, the length byte can describe more bytes than are actually present — in this case a length of 246 on a 189-byte payload gives an end index of 255, which is out of range.

Fix

Added a single bounds check before the sublist call. If 9 + length > payload.length, the packet is silently discarded (returns null) so the app continues normally rather than crashing.

final length = payload[8];
if (9 + length > payload.length) return null;
return payload.sublist(9, 9 + length);

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds a single bounds check in _parseAudioChunk to prevent a RangeError crash when a truncated or malformed BLE packet from a Plaud device contains a length byte larger than the actual remaining payload. An existing payload.length < 9 guard already protects the byte-8 read; the new check closes the gap between that guard and the sublist call.

  • plaud_connection.dart (line 75): Inserts if (9 + length > payload.length) return null; so truncated packets are silently discarded instead of throwing RangeError.
  • The diff also contains whitespace-only reformatting in performGetImageListener and _toBytes64 — no semantic changes.

Confidence Score: 5/5

Safe to merge — the one-line guard directly fixes a confirmed Crashlytics crash without altering any other control flow.

The change is minimal and targeted: it adds a missing upper-bounds check in _parseAudioChunk that closes the gap between the existing payload.length < 9 guard and the sublist call. The existing guard already ensures byte 8 is readable; the new guard ensures the slice [9, 9+length] always fits within the buffer. All other changes in the diff are pure whitespace reformatting. No logic is removed or rearranged, and the null return on bad packets is consistent with every other early-exit in the same function.

No files require special attention.

Important Files Changed

Filename Overview
app/lib/services/devices/plaud_connection.dart Adds a one-line bounds guard in _parseAudioChunk to discard truncated BLE packets; rest of diff is whitespace reformatting only.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant BLE as BLE Device (Plaud)
    participant HC as _handleNotification
    participant PA as _parseAudioChunk
    participant AS as _audioStream

    BLE->>HC: "notification data (List<int>)"
    HC->>PA: "payload = data.sublist(1)"
    alt "payload.length < 9"
        PA-->>HC: return null (too short)
    else "position == 0xFFFFFFFF"
        PA-->>HC: return null (end marker)
    else "9 + length > payload.length (NEW GUARD)"
        PA-->>HC: return null (truncated packet)
    else valid packet
        PA->>AS: payload.sublist(9, 9 + length)
        PA-->>HC: audio chunk
        HC->>AS: _audioStream.add(chunk)
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant BLE as BLE Device (Plaud)
    participant HC as _handleNotification
    participant PA as _parseAudioChunk
    participant AS as _audioStream

    BLE->>HC: "notification data (List<int>)"
    HC->>PA: "payload = data.sublist(1)"
    alt "payload.length < 9"
        PA-->>HC: return null (too short)
    else "position == 0xFFFFFFFF"
        PA-->>HC: return null (end marker)
    else "9 + length > payload.length (NEW GUARD)"
        PA-->>HC: return null (truncated packet)
    else valid packet
        PA->>AS: payload.sublist(9, 9 + length)
        PA-->>HC: audio chunk
        HC->>AS: _audioStream.add(chunk)
    end
Loading

Reviews (1): Last reviewed commit: "fix plaud _parseAudioChunk RangeError on..." | Re-trigger Greptile

@kodjima33 kodjima33 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mobile crash fix (Crashlytics): bounds-guard before sublist prevents RangeError on truncated Plaud BLE packets; mirrors existing end-marker guard. CI green.

@kodjima33 kodjima33 merged commit 0455e1f into main Jun 18, 2026
3 checks passed
@kodjima33 kodjima33 deleted the fix/plaud-parse-audio-chunk-range-error branch June 18, 2026 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants