Repository navigation
Commit 134674f
fix(store): a name that begins with a byte-order mark keeps it - the store reads every stored byte back, so "\uFEFFfoo" beside "foo", and "\uFEFF" alone, are each spelled as the file they name, and no query hit, scan JSON or delete names the file beside it (CI4 review F2.1, F2.2)
The packed store keeps a name as its UTF-8 bytes, and a name may begin
with U+FEFF: fs.readdir keeps it, and the encoder stores its three bytes
(EF BB BF). The store read names back with a TextDecoder made without
ignoreBOM, which reads a leading mark as nothing. So the 900-byte
"\uFEFFfoo" was named "foo" and spelled "/data/foo" - the path of the
5-byte file beside it - and a file named "\uFEFF" alone was spelled as
its folder, "/data/". path(), childPath(), the query's hits and the scan
JSON all build on name(), and the path lookup, which compares bytes,
then found the other file. DELETE /api/files, the cart, an Autopilot
query policy and an offload act on those paths. The decoder was the
store's from its start (3fd871f); CI4 review F1.1 (44dfcb7) had made
childPath agree with it rather than fix it.
The decoder now keeps the mark (ignoreBOM: true, as gitSafe's does), so
a name reads back as it was stored. childPath's branch for a parent whose
name begins with the mark is gone: with the mark kept, a name is empty or
ends with the separator exactly when its bytes do, so the plain byte rule
is exact, and CI4's byte-for-byte differential, which keeps its mark-led
names, still holds it to what reading the parent path answered.
Tests, RED before the fix for the reviewers' reason:
- tests/packedStore.test.ts: siblings "foo" and "\uFEFFfoo", a file
"\uFEFF", "\uFEFFsub/a" beside "sub/a", and a folder "\uFEFF" holding a
file, under "/data" and "C:\data": name(), path(), childPath(),
findByPath(path()) and the streamed scan JSON agree with the object
store, which keeps names as given. RED: the name "\uFEFFfoo" read as
"foo".
- tests/queryWalkWork.test.ts: type:file answers every file under its
own name and path, held to the listing the store was built from. RED:
"/data/foo" for both the 5-byte and the 900-byte file, "/data/" for
"\uFEFF".
Mutants, each RED for the right reason, restored and checked by SHA-256:
the old decoder (both tests, and the differential); childPath reading a
parent named "\uFEFF" alone as empty ("/data/sub/\uFEFFb"); path()
dropping the mark; the path lookup dropping it (finds the plain "foo");
the scan JSON dropping it; the child list leaving a child out.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>1 parent 2bac59f commit 134674f
3 files changed
Lines changed: 101 additions & 19 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
795 | 795 | | |
796 | 796 | | |
797 | 797 | | |
798 | | - | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
799 | 806 | | |
800 | 807 | | |
801 | 808 | | |
| |||
1509 | 1516 | | |
1510 | 1517 | | |
1511 | 1518 | | |
1512 | | - | |
1513 | | - | |
1514 | | - | |
1515 | | - | |
1516 | | - | |
1517 | | - | |
1518 | | - | |
1519 | | - | |
1520 | | - | |
1521 | | - | |
1522 | | - | |
1523 | | - | |
1524 | | - | |
1525 | | - | |
| 1519 | + | |
| 1520 | + | |
| 1521 | + | |
| 1522 | + | |
| 1523 | + | |
| 1524 | + | |
1526 | 1525 | | |
1527 | 1526 | | |
1528 | 1527 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
164 | 164 | | |
165 | 165 | | |
166 | 166 | | |
167 | | - | |
168 | | - | |
169 | | - | |
170 | | - | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
171 | 171 | | |
172 | 172 | | |
173 | 173 | | |
| |||
203 | 203 | | |
204 | 204 | | |
205 | 205 | | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
206 | 266 | | |
207 | 267 | | |
208 | 268 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
442 | 442 | | |
443 | 443 | | |
444 | 444 | | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
0 commit comments