feat(fs): add bounded byte-range reads - #2792
Conversation
Greptile SummaryAdds half-open, validated byte-range reads across local files, Android SAF, SFTP, and HTTP resources.
Confidence Score: 2/5The PR should not merge until HTTP responses are bounded during consumption and SAF JSON range decoding preserves the backend's BOM behavior. The new HTTP method can allocate an arbitrarily large remote response despite its bounded-read contract, and the external-storage wrapper rejects BOM-prefixed JSON that its full-file counterpart accepts. Files Needing Attention: src/fileSystem/index.js, src/fileSystem/externalFs.js
|
| Filename | Overview |
|---|---|
| src/fileSystem/index.js | Adds HTTP Range support, but buffers an untrusted response completely before enforcing the requested byte bound. |
| src/fileSystem/externalFs.js | Exposes SAF range reads but does not preserve the backend's existing BOM normalization for JSON. |
| src/fileSystem/readRange.js | Centralizes safe-integer and maximum-length validation plus optional decoding. |
| src/fileSystem/internalFs.js | Uses Blob.slice and FileReader to avoid loading bytes outside the requested local-file range. |
| src/fileSystem/sftp.js | Adds range reads through the existing connection lifecycle and native SFTP bridge. |
| src/plugins/sdcard/src/android/SDcard.java | Implements validated stream skipping and capped native reads for SAF content. |
| src/plugins/sftp/src/com/foxdebug/sftp/Sftp.java | Implements offset-based SFTP stream reads capped to the validated requested length. |
| tests/unit/readFileRange.test.js | Covers validation and principal backend delegation, but not oversized headerless HTTP responses or BOM-prefixed JSON ranges. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
Caller[fsOperation URL readFileRange] --> Validate[validateReadRange]
Validate --> Local[Local Blob.slice]
Validate --> SAF[SDcard native stream]
Validate --> SFTP[SFTP offset stream]
Validate --> HTTP[HTTP Range fetch]
Local --> Decode[decodeReadRange]
SAF --> Decode
SFTP --> Decode
HTTP --> Decode
Reviews (1): Last reviewed commit: "feat(fs): add bounded byte-range reads" | Re-trigger Greptile
| const data = await response.arrayBuffer(); | ||
| if (data.byteLength > range.length) { |
There was a problem hiding this comment.
Unbounded HTTP response buffering
When a server returns 206 without a valid Content-Length or Content-Range and streams more bytes than requested, response.arrayBuffer() buffers the entire body before the length check, causing WebView memory exhaustion despite the bounded-read contract.
How this was verified: The optional header guards can be skipped, while the response-size check runs only after the complete body has been buffered.
Knowledge Base Used: File System
| async readFileRange(start, end, encoding) { | ||
| const { data } = await externalFs.readFileRange(url, start, end); | ||
| return decodeReadRange(data, encoding); | ||
| }, |
There was a problem hiding this comment.
When a range contains an entire BOM-prefixed JSON document and uses the json encoding, this path passes the BOM directly to JSON decoding instead of applying the normalization used by readFile, causing the range read to reject for a document the full-file path accepts.
Knowledge Base Used: File System
No description provided.