( store: string, key: string, maxBytes: number, )
| 219 | * (truncateUtf8 in LocalMemoryRecallTool). |
| 220 | */ |
| 221 | export function getEntryBounded( |
| 222 | store: string, |
| 223 | key: string, |
| 224 | maxBytes: number, |
| 225 | ): { value: string; truncated: boolean } | null { |
| 226 | validateStoreName(store) |
| 227 | validateKey(key) |
| 228 | const entryPath = getEntryPath(store, key) |
| 229 | if (!existsSync(entryPath)) return null |
| 230 | const stat = statSync(entryPath) |
| 231 | const total = stat.size |
| 232 | const readBytes = Math.min(total, maxBytes) |
| 233 | const buf = Buffer.alloc(readBytes) |
| 234 | const fd = openSync(entryPath, 'r') |
| 235 | // M5 fix (codecov-100 audit #9): track how many bytes we ACTUALLY read, |
| 236 | // and surface short-reads as truncation. Previously the loop returned |
| 237 | // `buf` (a `readBytes`-sized allocation) regardless of whether the |
| 238 | // readSync calls cumulatively delivered that many bytes — a file that |
| 239 | // was truncated on disk between statSync and readSync would yield a |
| 240 | // half-zeroed buffer with truncated=false, silently corrupting the |
| 241 | // returned string. |
| 242 | let offset = 0 |
| 243 | try { |
| 244 | while (offset < readBytes) { |
| 245 | const n = readSync(fd, buf, offset, readBytes - offset, offset) |
| 246 | if (n === 0) break // EOF: file shrank between stat and read |
| 247 | // n < 0 cannot happen — Node's readSync throws on errno < 0 — but |
| 248 | // belt-and-suspenders for clarity: treat negative as EOF. |
| 249 | if (n < 0) break |
| 250 | offset += n |
| 251 | } |
| 252 | } finally { |
| 253 | closeSync(fd) |
| 254 | } |
| 255 | // M5: include `offset < readBytes` in the truncated flag so callers see |
| 256 | // EOF-during-read as truncation. Use subarray(0, offset) so the value |
| 257 | // length matches what we actually read (no trailing zero bytes). |
| 258 | const truncated = total > maxBytes || offset < readBytes |
| 259 | return { value: buf.subarray(0, offset).toString('utf8'), truncated } |
| 260 | } |
| 261 | |
| 262 | /** Delete an entry from a store. Returns true if it existed. */ |
| 263 | export function deleteEntry(store: string, key: string): boolean { |
no test coverage detected