@photostructure/fs-metadata 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/CLAUDE.md +1 -1
  3. package/CONTRIBUTING.md +15 -0
  4. package/README.md +2 -1
  5. package/dist/index.cjs +11 -4
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.d.cts +10 -5
  8. package/dist/index.d.mts +10 -5
  9. package/dist/index.d.ts +10 -5
  10. package/dist/index.mjs +10 -3
  11. package/dist/index.mjs.map +1 -1
  12. package/doc/LINUX_API_REFERENCE.md +310 -0
  13. package/doc/MACOS_API_REFERENCE.md +367 -31
  14. package/doc/WINDOWS_API_REFERENCE.md +35 -2
  15. package/doc/gotchas.md +28 -0
  16. package/package.json +15 -18
  17. package/prebuilds/darwin-arm64/@photostructure+fs-metadata.glibc.node +0 -0
  18. package/prebuilds/darwin-x64/@photostructure+fs-metadata.glibc.node +0 -0
  19. package/prebuilds/linux-arm64/@photostructure+fs-metadata.glibc.node +0 -0
  20. package/prebuilds/linux-arm64/@photostructure+fs-metadata.musl.node +0 -0
  21. package/prebuilds/linux-x64/@photostructure+fs-metadata.glibc.node +0 -0
  22. package/prebuilds/linux-x64/@photostructure+fs-metadata.musl.node +0 -0
  23. package/prebuilds/win32-arm64/@photostructure+fs-metadata.glibc.node +0 -0
  24. package/prebuilds/win32-x64/@photostructure+fs-metadata.glibc.node +0 -0
  25. package/scripts/precommit.ts +4 -1
  26. package/src/common/fd_guard.h +71 -0
  27. package/src/{darwin → common}/path_security.h +8 -5
  28. package/src/common/volume_utils.h +51 -0
  29. package/src/darwin/hidden.cpp +47 -14
  30. package/src/darwin/raii_utils.h +8 -8
  31. package/src/darwin/volume_metadata.cpp +33 -39
  32. package/src/index.ts +3 -3
  33. package/src/linux/blkid_cache.cpp +5 -11
  34. package/src/linux/blkid_cache.h +21 -0
  35. package/src/linux/gio_utils.cpp +7 -23
  36. package/src/linux/gio_utils.h +16 -40
  37. package/src/linux/gio_volume_metadata.cpp +16 -88
  38. package/src/linux/volume_metadata.cpp +35 -27
  39. package/src/options.ts +16 -3
  40. package/src/types/options.ts +1 -1
  41. package/src/windows/drive_status.h +74 -49
  42. package/src/windows/error_utils.h +2 -2
  43. package/src/windows/security_utils.h +47 -2
  44. package/src/windows/thread_pool.h +29 -4
  45. package/src/windows/volume_metadata.cpp +17 -12
package/CHANGELOG.md CHANGED
@@ -14,6 +14,39 @@ Fixed for any bug fixes.
14
14
  Security in case of vulnerabilities.
15
15
  -->
16
16
 
17
+ ## 0.8.0 - 2025-12-01
18
+
19
+ ### Added
20
+
21
+ - `FS_METADATA_TIMEOUT_MS` environment variable for configuring operation timeout (see [gotchas.md](./doc/gotchas.md))
22
+
23
+ ### Security
24
+
25
+ - Fixed TOCTOU race condition in macOS hidden file operations by using `fstat()`/`fchflags()` with file descriptors instead of path-based `stat()`/`chflags()`
26
+
27
+ ### Fixed
28
+
29
+ - Added `O_CLOEXEC` flag to `open()` calls to prevent fd leaks on fork/exec
30
+ - Fixed logic bug attempting to convert invalid CFStringRef in `ProcessNetworkVolume`
31
+ - Fixed inconsistent `status` field when DiskArbitration returns partial results
32
+ - Added `noexcept` to all RAII destructors to prevent `std::terminate` during stack unwinding
33
+ - Removed `GVolumeMonitor` from Linux GIO metadata enrichment to fix thread safety issues
34
+ - Fixed exception safety in Linux GIO metadata loop using RAII smart pointers
35
+ - Fixed Windows `FindFirstFileEx` handle leak by using `FindClose` instead of `CloseHandle`
36
+ - Fixed Windows promise race condition and resource leak from detached timeout threads
37
+ - Added `CreateEvent` error checking in Windows thread pool
38
+ - Zero-initialized `VolumeInfo` and `DiskSpaceInfo` members to prevent undefined behavior on `ERROR_NOT_READY`
39
+
40
+ ### Changed
41
+
42
+ - Extracted shared `FdGuard` RAII class to `common/fd_guard.h`
43
+ - Extracted shared `WouldOverflow()` utility to `common/volume_utils.h`
44
+ - Moved `path_security.h` to `common/` (POSIX-portable)
45
+ - Simplified CFString null-terminator handling using `strlen()`
46
+ - Documented intentional static dispatch queue singleton pattern
47
+ - Consolidated Linux GIO RAII helpers (`GFilePtr`, `GVolumePtr`, etc.) in `gio_utils.h`
48
+ - Added move semantics to `BlkidCache` for proper resource transfer
49
+
17
50
  ## 0.7.1 - 2025-10-29
18
51
 
19
52
  - Audit and address [several resource handling issues](./doc/SECURITY_AUDIT_2025.md)
package/CLAUDE.md CHANGED
@@ -197,4 +197,4 @@ git push origin main --follow-tags
197
197
 
198
198
  Never do inline imports like `const { mkdirSync } = await import("node:fs");` -- just use standard imports.
199
199
 
200
- Never include claude code messages in git commits
200
+ **NEVER** add "Generated with Claude Code" or "Co-Authored-By: Claude" lines to git commit messages. Keep commits clean and professional.
package/CONTRIBUTING.md CHANGED
@@ -6,6 +6,21 @@ For major changes, please open an issue first to discuss what you would like to
6
6
 
7
7
  Please make sure to update tests and documentation as appropriate.
8
8
 
9
+ ## Development Setup
10
+
11
+ This repository uses `ignore-scripts=true` in `.npmrc` as a security measure against [supply chain attacks](https://www.nodejs-security.com/blog/npm-ignore-scripts-best-practices-as-security-mitigation-for-malicious-packages). Since this is a native module, you need to explicitly enable scripts for the initial build:
12
+
13
+ ```bash
14
+ # Clone the repository
15
+ git clone https://github.com/photostructure/fs-metadata.git
16
+ cd fs-metadata
17
+
18
+ # Install with scripts enabled (required for native module build)
19
+ npm install --ignore-scripts=false
20
+
21
+ # Subsequent installs of new dependencies will have scripts disabled by default
22
+ ```
23
+
9
24
  ## Building from Source
10
25
 
11
26
  ### On Windows
package/README.md CHANGED
@@ -56,7 +56,8 @@ console.log(metadata);
56
56
  ### Options
57
57
 
58
58
  - **Debug**: Set `NODE_DEBUG=fs-meta` for debug output
59
- - **Timeouts**: Configure [timeout duration](https://photostructure.github.io/fs-metadata/variables/TimeoutMsDefault.html) for slow devices
59
+ - **Timeouts**: Configure [timeout duration](https://photostructure.github.io/fs-metadata/functions/getTimeoutMsDefault.html) for slow devices
60
+ - Set `FS_METADATA_TIMEOUT_MS` environment variable to override the default (5000ms)
60
61
  - **System Volumes**: Control [system volume filtering](https://photostructure.github.io/fs-metadata/interfaces/Options.html)
61
62
 
62
63
  ## Support
package/dist/index.cjs CHANGED
@@ -35,10 +35,10 @@ __export(index_exports, {
35
35
  OptionsDefault: () => OptionsDefault,
36
36
  SystemFsTypesDefault: () => SystemFsTypesDefault,
37
37
  SystemPathPatternsDefault: () => SystemPathPatternsDefault,
38
- TimeoutMsDefault: () => TimeoutMsDefault,
39
38
  VolumeHealthStatuses: () => VolumeHealthStatuses,
40
39
  getAllVolumeMetadata: () => getAllVolumeMetadata,
41
40
  getHiddenMetadata: () => getHiddenMetadata,
41
+ getTimeoutMsDefault: () => getTimeoutMsDefault,
42
42
  getVolumeMetadata: () => getVolumeMetadata,
43
43
  getVolumeMountPoints: () => getVolumeMountPoints,
44
44
  isHidden: () => isHidden,
@@ -612,7 +612,14 @@ async function setHiddenImpl(pathname, hide, method, nativeFn2) {
612
612
 
613
613
  // src/options.ts
614
614
  var import_node_os2 = require("os");
615
- var TimeoutMsDefault = 5e3;
615
+ var import_node_process3 = require("process");
616
+ var DefaultTimeoutMs = 5e3;
617
+ function getTimeoutMsDefault() {
618
+ const value = import_node_process3.env["FS_METADATA_TIMEOUT_MS"];
619
+ if (value == null) return DefaultTimeoutMs;
620
+ const parsed = parseInt(value, 10);
621
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : DefaultTimeoutMs;
622
+ }
616
623
  var SystemPathPatternsDefault = [
617
624
  "/boot",
618
625
  "/boot/efi",
@@ -681,7 +688,7 @@ var LinuxMountTablePathsDefault = [
681
688
  var IncludeSystemVolumesDefault = isWindows;
682
689
  var SkipNetworkVolumesDefault = false;
683
690
  var OptionsDefault = {
684
- timeoutMs: TimeoutMsDefault,
691
+ timeoutMs: getTimeoutMsDefault(),
685
692
  maxConcurrency: (0, import_node_os2.availableParallelism)(),
686
693
  systemPathPatterns: [...SystemPathPatternsDefault],
687
694
  systemFsTypes: [...SystemFsTypesDefault],
@@ -1456,10 +1463,10 @@ function setHidden(pathname, hidden, method = "auto") {
1456
1463
  OptionsDefault,
1457
1464
  SystemFsTypesDefault,
1458
1465
  SystemPathPatternsDefault,
1459
- TimeoutMsDefault,
1460
1466
  VolumeHealthStatuses,
1461
1467
  getAllVolumeMetadata,
1462
1468
  getHiddenMetadata,
1469
+ getTimeoutMsDefault,
1463
1470
  getVolumeMetadata,
1464
1471
  getVolumeMountPoints,
1465
1472
  isHidden,