@photostructure/fs-metadata 0.4.0 → 0.5.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 (179) hide show
  1. package/C++_REVIEW_TODO.md +291 -0
  2. package/CHANGELOG.md +29 -1
  3. package/CLAUDE.md +169 -0
  4. package/CONTRIBUTING.md +25 -0
  5. package/coverage/base.css +224 -0
  6. package/coverage/block-navigation.js +87 -0
  7. package/coverage/favicon.png +0 -0
  8. package/coverage/index.html +131 -0
  9. package/coverage/lcov-report/base.css +224 -0
  10. package/coverage/lcov-report/block-navigation.js +87 -0
  11. package/coverage/lcov-report/favicon.png +0 -0
  12. package/coverage/lcov-report/index.html +131 -0
  13. package/coverage/lcov-report/prettify.css +1 -0
  14. package/coverage/lcov-report/prettify.js +2 -0
  15. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  16. package/coverage/lcov-report/sorter.js +196 -0
  17. package/coverage/lcov-report/src/array.ts.html +217 -0
  18. package/coverage/lcov-report/src/async.ts.html +547 -0
  19. package/coverage/lcov-report/src/debuglog.ts.html +187 -0
  20. package/coverage/lcov-report/src/defer.ts.html +175 -0
  21. package/coverage/lcov-report/src/dirname.ts.html +124 -0
  22. package/coverage/lcov-report/src/error.ts.html +322 -0
  23. package/coverage/lcov-report/src/fs.ts.html +316 -0
  24. package/coverage/lcov-report/src/glob.ts.html +472 -0
  25. package/coverage/lcov-report/src/hidden.ts.html +724 -0
  26. package/coverage/lcov-report/src/index.html +521 -0
  27. package/coverage/lcov-report/src/index.ts.html +676 -0
  28. package/coverage/lcov-report/src/linux/dev_disk.ts.html +316 -0
  29. package/coverage/lcov-report/src/linux/index.html +146 -0
  30. package/coverage/lcov-report/src/linux/mount_points.ts.html +364 -0
  31. package/coverage/lcov-report/src/linux/mtab.ts.html +493 -0
  32. package/coverage/lcov-report/src/mount_point.ts.html +106 -0
  33. package/coverage/lcov-report/src/number.ts.html +148 -0
  34. package/coverage/lcov-report/src/object.ts.html +265 -0
  35. package/coverage/lcov-report/src/options.ts.html +475 -0
  36. package/coverage/lcov-report/src/path.ts.html +268 -0
  37. package/coverage/lcov-report/src/platform.ts.html +112 -0
  38. package/coverage/lcov-report/src/random.ts.html +205 -0
  39. package/coverage/lcov-report/src/remote_info.ts.html +553 -0
  40. package/coverage/lcov-report/src/stack_path.ts.html +298 -0
  41. package/coverage/lcov-report/src/string.ts.html +382 -0
  42. package/coverage/lcov-report/src/string_enum.ts.html +208 -0
  43. package/coverage/lcov-report/src/system_volume.ts.html +301 -0
  44. package/coverage/lcov-report/src/unc.ts.html +274 -0
  45. package/coverage/lcov-report/src/units.ts.html +274 -0
  46. package/coverage/lcov-report/src/uuid.ts.html +157 -0
  47. package/coverage/lcov-report/src/volume_health_status.ts.html +259 -0
  48. package/coverage/lcov-report/src/volume_metadata.ts.html +787 -0
  49. package/coverage/lcov-report/src/volume_mount_points.ts.html +388 -0
  50. package/coverage/lcov.info +3581 -0
  51. package/coverage/prettify.css +1 -0
  52. package/coverage/prettify.js +2 -0
  53. package/coverage/sort-arrow-sprite.png +0 -0
  54. package/coverage/sorter.js +196 -0
  55. package/coverage/src/array.ts.html +217 -0
  56. package/coverage/src/async.ts.html +547 -0
  57. package/coverage/src/debuglog.ts.html +187 -0
  58. package/coverage/src/defer.ts.html +175 -0
  59. package/coverage/src/dirname.ts.html +124 -0
  60. package/coverage/src/error.ts.html +322 -0
  61. package/coverage/src/fs.ts.html +316 -0
  62. package/coverage/src/glob.ts.html +472 -0
  63. package/coverage/src/hidden.ts.html +724 -0
  64. package/coverage/src/index.html +521 -0
  65. package/coverage/src/index.ts.html +676 -0
  66. package/coverage/src/linux/dev_disk.ts.html +316 -0
  67. package/coverage/src/linux/index.html +146 -0
  68. package/coverage/src/linux/mount_points.ts.html +364 -0
  69. package/coverage/src/linux/mtab.ts.html +493 -0
  70. package/coverage/src/mount_point.ts.html +106 -0
  71. package/coverage/src/number.ts.html +148 -0
  72. package/coverage/src/object.ts.html +265 -0
  73. package/coverage/src/options.ts.html +475 -0
  74. package/coverage/src/path.ts.html +268 -0
  75. package/coverage/src/platform.ts.html +112 -0
  76. package/coverage/src/random.ts.html +205 -0
  77. package/coverage/src/remote_info.ts.html +553 -0
  78. package/coverage/src/stack_path.ts.html +298 -0
  79. package/coverage/src/string.ts.html +382 -0
  80. package/coverage/src/string_enum.ts.html +208 -0
  81. package/coverage/src/system_volume.ts.html +301 -0
  82. package/coverage/src/unc.ts.html +274 -0
  83. package/coverage/src/units.ts.html +274 -0
  84. package/coverage/src/uuid.ts.html +157 -0
  85. package/coverage/src/volume_health_status.ts.html +259 -0
  86. package/coverage/src/volume_metadata.ts.html +787 -0
  87. package/coverage/src/volume_mount_points.ts.html +388 -0
  88. package/jest.config.cjs +67 -6
  89. package/package.json +51 -41
  90. package/prebuilds/linux-x64/@photostructure+fs-metadata.glibc.node +0 -0
  91. package/scripts/check-memory.mjs +243 -0
  92. package/scripts/clang-tidy.mjs +73 -0
  93. package/scripts/is-platform.mjs +12 -0
  94. package/scripts/post-build.mjs +21 -0
  95. package/scripts/run-asan.sh +92 -0
  96. package/scripts/valgrind-test.mjs +83 -0
  97. package/scripts/valgrind.sh +70 -0
  98. package/src/async.ts +3 -3
  99. package/src/binding.cpp +3 -3
  100. package/src/error.ts +3 -3
  101. package/src/fs.ts +1 -1
  102. package/src/glob.ts +2 -2
  103. package/src/hidden.ts +6 -6
  104. package/src/index.ts +19 -23
  105. package/src/linux/blkid_cache.cpp +15 -12
  106. package/src/linux/dev_disk.ts +2 -2
  107. package/src/linux/gio_mount_points.cpp +7 -7
  108. package/src/linux/gio_utils.cpp +19 -8
  109. package/src/linux/gio_volume_metadata.cpp +15 -15
  110. package/src/linux/mount_points.ts +9 -9
  111. package/src/linux/mtab.ts +7 -7
  112. package/src/linux/volume_metadata.cpp +6 -1
  113. package/src/object.ts +1 -1
  114. package/src/options.ts +3 -3
  115. package/src/path.ts +2 -2
  116. package/src/remote_info.ts +5 -5
  117. package/src/system_volume.ts +8 -8
  118. package/src/test-utils/assert.ts +2 -2
  119. package/src/test-utils/debuglog-child.ts +1 -3
  120. package/src/test-utils/debuglog-enabled-child.ts +10 -0
  121. package/src/test-utils/hidden-tests.ts +1 -1
  122. package/src/test-utils/platform.ts +3 -3
  123. package/src/types/native_bindings.ts +3 -3
  124. package/src/types/volume_metadata.ts +2 -2
  125. package/src/unc.ts +2 -2
  126. package/src/uuid.ts +1 -1
  127. package/src/volume_health_status.ts +6 -6
  128. package/src/volume_metadata.ts +20 -23
  129. package/src/volume_mount_points.ts +12 -17
  130. package/src/windows/drive_status.h +30 -13
  131. package/src/windows/hidden.cpp +12 -0
  132. package/src/windows/volume_metadata.cpp +17 -7
  133. package/tsup.config.ts +8 -2
  134. package/dist/index.cjs +0 -1439
  135. package/dist/index.cjs.map +0 -1
  136. package/dist/index.mjs +0 -1396
  137. package/dist/index.mjs.map +0 -1
  138. package/dist/types/array.d.ts +0 -25
  139. package/dist/types/async.d.ts +0 -42
  140. package/dist/types/debuglog.d.ts +0 -3
  141. package/dist/types/defer.d.ts +0 -10
  142. package/dist/types/dirname.d.ts +0 -1
  143. package/dist/types/error.d.ts +0 -17
  144. package/dist/types/fs.d.ts +0 -22
  145. package/dist/types/glob.d.ts +0 -17
  146. package/dist/types/hidden.d.ts +0 -29
  147. package/dist/types/index.d.ts +0 -91
  148. package/dist/types/linux/dev_disk.d.ts +0 -13
  149. package/dist/types/linux/mount_points.d.ts +0 -6
  150. package/dist/types/linux/mtab.d.ts +0 -47
  151. package/dist/types/mount_point.d.ts +0 -2
  152. package/dist/types/number.d.ts +0 -3
  153. package/dist/types/object.d.ts +0 -18
  154. package/dist/types/options.d.ts +0 -33
  155. package/dist/types/path.d.ts +0 -17
  156. package/dist/types/platform.d.ts +0 -4
  157. package/dist/types/random.d.ts +0 -12
  158. package/dist/types/remote_info.d.ts +0 -6
  159. package/dist/types/stack_path.d.ts +0 -2
  160. package/dist/types/string.d.ts +0 -37
  161. package/dist/types/string_enum.d.ts +0 -19
  162. package/dist/types/system_volume.d.ts +0 -14
  163. package/dist/types/types/hidden_metadata.d.ts +0 -32
  164. package/dist/types/types/mount_point.d.ts +0 -46
  165. package/dist/types/types/native_bindings.d.ts +0 -51
  166. package/dist/types/types/options.d.ts +0 -47
  167. package/dist/types/types/remote_info.d.ts +0 -33
  168. package/dist/types/types/volume_metadata.d.ts +0 -46
  169. package/dist/types/unc.d.ts +0 -11
  170. package/dist/types/units.d.ts +0 -38
  171. package/dist/types/uuid.d.ts +0 -16
  172. package/dist/types/volume_health_status.d.ts +0 -24
  173. package/dist/types/volume_metadata.d.ts +0 -8
  174. package/dist/types/volume_mount_points.d.ts +0 -6
  175. package/jest.config.base.cjs +0 -63
  176. package/prebuilds/darwin-arm64/@photostructure+fs-metadata.glibc.node +0 -0
  177. package/prebuilds/linux-arm64/@photostructure+fs-metadata.musl.node +0 -0
  178. package/prebuilds/linux-x64/@photostructure+fs-metadata.musl.node +0 -0
  179. package/prebuilds/win32-x64/@photostructure+fs-metadata.glibc.node +0 -0
@@ -0,0 +1,291 @@
1
+ # C++ Code Review TODO List
2
+
3
+ This document outlines a comprehensive review of all C++ files in the fs-metadata project to identify memory leaks, resource management issues, and API usage improvements.
4
+
5
+ ## Common Patterns to Review
6
+
7
+ ### Memory Management
8
+ - [x] All `malloc`/`free` pairs are properly matched - No malloc/free used, using RAII throughout
9
+ - [x] RAII patterns are used consistently for resource management - Excellent RAII usage across codebase
10
+ - [x] No raw pointers that could leak on exceptions - All resources properly wrapped
11
+ - [x] Smart pointers used appropriately - Consistent use of unique_ptr and custom RAII wrappers
12
+ - [x] All API-allocated resources are properly freed - RAII ensures cleanup
13
+
14
+ ### Platform API Usage
15
+ - [x] Verify API availability for target OS versions - APIs match stated OS requirements
16
+ - [x] Check for deprecated API usage - No deprecated N-API functions found
17
+ - [x] Ensure error handling follows platform conventions - Platform-specific error handling implemented
18
+ - [x] Validate string encoding conversions - UTF-8/wide conversions properly sized
19
+
20
+ ### Security and Input Validation
21
+ - [x] Comprehensive path validation to prevent directory traversal - Added ".." checks to Windows/Darwin hidden.cpp
22
+ - [ ] Input validation for empty/null mount points across all platforms
23
+ - [x] Buffer size constants defined for platform-specific limits - Fixed Windows buffer sizes
24
+ - [ ] Null byte and special character handling in paths
25
+
26
+ ### Thread Safety
27
+ - [x] Replace volatile with std::atomic for thread synchronization - Fixed in drive_status.h
28
+ - [x] Review N-API threadsafe function patterns - All async workers use proper patterns
29
+ - [ ] Document thread safety requirements
30
+ - [x] Ensure proper synchronization in async operations - Using atomic operations with proper memory ordering
31
+
32
+ ## File-by-File Review Checklist
33
+
34
+ ### 1. `src/binding.cpp` ✅
35
+ - [x] Review NAPI memory management patterns - No issues found
36
+ - [x] Check for proper cleanup in async worker lifecycles - Properly managed
37
+ - [x] Verify promise deferred resolution/rejection paths - Correct implementation
38
+ - [x] Validate string conversions between JS and C++ - Using Napi::String correctly
39
+ - [x] **Added**: const-correctness for Napi::Env variables
40
+ - **Platform APIs verified**: Node-API v9 compatibility
41
+
42
+ ### 2. Darwin/macOS Files
43
+
44
+ #### `src/darwin/volume_metadata.cpp` ✅
45
+ - [x] Verify CFRelease for all CoreFoundation objects - Using CFReleaser RAII wrapper
46
+ - DADisk objects properly managed with CFReleaser
47
+ - Disk descriptions properly managed with CFReleaser
48
+ - DASession objects properly managed with CFReleaser
49
+ - [x] Check DiskArbitration API cleanup - RAII ensures cleanup via CFReleaser
50
+ - [x] Review CFStringToString conversion for memory leaks - No leaks, proper string handling
51
+ - [x] Validate statvfs/statfs error handling - Comprehensive error checking
52
+ - [x] Check overflow protection in size calculations - Excellent overflow protection (lines 91-104)
53
+ - **Platform APIs verified**:
54
+ - DiskArbitration framework APIs (macOS 14+) - Proper RAII usage
55
+ - IOKit framework APIs - Not directly used
56
+ - CoreFoundation string handling - CFReleaser ensures proper cleanup
57
+ - **Notes**: Exemplary code with proper RAII, overflow protection, and error handling
58
+
59
+ #### `src/darwin/volume_mount_points.cpp` ✅
60
+ - [x] Review getmntinfo usage and buffer management - Using getmntinfo_r_np with MountBufferRAII
61
+ - [x] Verify CFURLRef lifecycle management - No CFURLRef used in this file
62
+ - [x] Check DADiskCreateFromBSDName cleanup - Not used in this file
63
+ - **Platform APIs verified**:
64
+ - `getmntinfo_r_np` with MNT_NOWAIT for thread safety
65
+ - BSD mount structure compatibility - Properly handled
66
+ - **Notes**: Good use of RAII, async/future for timeout handling, and faccessat for security
67
+
68
+ #### `src/darwin/hidden.cpp` ✅
69
+ - [x] Review NSURL object lifecycle - No NSURL/CFURLRef used, using stat/chflags
70
+ - [x] Check CFURLRef release patterns - Not applicable
71
+ - [x] Verify resource value key handling - Using UF_HIDDEN flag directly
72
+ - **Platform APIs verified**:
73
+ - File attribute APIs (UF_HIDDEN) - Proper usage with stat/chflags
74
+ - Path validation implemented (checks for "..")
75
+ - **Notes**: Simple and correct implementation using BSD APIs
76
+
77
+ ### 3. Windows Files
78
+
79
+ #### `src/windows/volume_metadata.cpp` ✅
80
+ - [x] Review WNetConnection RAII wrapper completeness - **FIXED**: Now handles ERROR_MORE_DATA
81
+ - Dynamic buffer resize implemented when ERROR_MORE_DATA is returned
82
+ - [x] Check GetVolumeInformation error handling - **FIXED**: Now uses MAX_PATH+1
83
+ - Using proper VOLUME_NAME_SIZE constant (MAX_PATH+1) for buffers
84
+ - [x] Verify wide string conversion cleanup - Proper PathConverter usage
85
+ - [x] Validate DeviceIoControl buffer management - Not used in this file
86
+ - **Platform APIs verified**:
87
+ - WNet APIs properly handle ERROR_MORE_DATA
88
+ - GetVolumeInformation uses correct MAX_PATH+1 buffers
89
+ - **Notes**: All buffer issues resolved, proper RAII patterns throughout
90
+
91
+ #### `src/windows/volume_mount_points.cpp` ✅
92
+ - [x] Review GetLogicalDrives usage - Proper usage with unique_ptr buffer
93
+ - [x] Check QueryDosDevice buffer allocation - Not used in this file
94
+ - [x] Verify GetVolumePathNamesForVolumeName memory management - Not used in this file
95
+ - **Platform APIs verified**:
96
+ - GetLogicalDriveStringsW - Proper buffer sizing and iteration
97
+ - GetVolumeInformationW - Using MAX_PATH+1 correctly
98
+ - Parallel drive status checking implemented
99
+ - **Notes**: Good implementation with proper buffer management
100
+
101
+ #### `src/windows/hidden.cpp` ✅
102
+ - [x] Review GetFileAttributes error handling - FileAttributeHandler RAII properly throws on error
103
+ - [x] Check SetFileAttributes validation - Proper error checking with exceptions
104
+ - [x] Verify wide string conversions - PathConverter properly handles UTF-8 to wide
105
+ - [x] **Added**: Path validation for directory traversal (".." check)
106
+ - **Platform APIs verified**:
107
+ - GetFileAttributesW/SetFileAttributesW - Proper usage with error handling
108
+ - FILE_ATTRIBUTE_HIDDEN - Correctly manipulated
109
+ - **Notes**: Excellent RAII implementation with FileAttributeHandler, now with path validation
110
+
111
+ ### 4. Linux Files (Completed)
112
+
113
+ #### `src/linux/volume_metadata.cpp` ✅
114
+ - [x] Review BlkidCache RAII wrapper - Already excellent
115
+ - [x] Check blkid_get_tag_value free() calls - Correctly using free()
116
+ - [x] Verify GIO integration memory management - Proper smart pointers
117
+ - [x] Validate statvfs error handling - Already comprehensive
118
+ - [x] **Added**: Input validation for empty mount points
119
+ - **Platform APIs verified**:
120
+ - libblkid API availability
121
+ - GIO optional dependency handling
122
+ - statvfs behavior
123
+
124
+ #### `src/linux/blkid_cache.cpp` ✅
125
+ - [x] Verify blkid_cache lifecycle - Already has proper RAII
126
+ - [x] Check error handling for cache operations - Good error handling
127
+ - [x] **Improved**: Double-check pattern in destructor for thread safety
128
+ - [x] **Added**: const-correctness for std::lock_guard instances
129
+ - **Platform APIs verified**:
130
+ - libblkid cache APIs - Proper use of blkid_get_cache/blkid_put_cache
131
+
132
+ #### `src/linux/gio_utils.cpp` (if GIO enabled) ✅
133
+ - [x] Review g_object_unref patterns - Already using GioResource RAII
134
+ - [x] Check GError cleanup - Not used in this file (GError-free patterns)
135
+ - [x] Verify GMount/GVolume reference counting - Proper ref/unref pairs
136
+ - [x] **Added**: Exception handling in forEachMount callback
137
+ - [x] **Added**: Null checks for root.get() before G_IS_FILE
138
+ - [x] **Added**: const-correctness for GioResource and callback results
139
+ - **Platform APIs verified**:
140
+ - GLib/GIO APIs (GNOME) - Proper memory management patterns
141
+ - GVfs mount integration
142
+
143
+ #### `src/linux/gio_mount_points.cpp` (if GIO enabled) ✅
144
+ - [x] Review g_volume_monitor lifecycle - Correct usage (singleton pattern)
145
+ - [x] Check GList cleanup patterns - Using g_list_free_full correctly
146
+ - [x] Verify string ownership - Proper GCharPtr smart pointers
147
+ - [x] **Added**: const-correctness for local variables (GCharPtr, GFileInfoPtr, etc.)
148
+ - **Platform APIs verified**:
149
+ - GVolumeMonitor APIs - Reference counting rules
150
+ - Mount enumeration
151
+
152
+ #### `src/linux/gio_volume_metadata.cpp` (if GIO enabled) ✅
153
+ - [x] Review g_drive object management - Using GObjectPtr smart pointers
154
+ - [x] Check g_icon handling - No GIcon usage in this file
155
+ - [x] Verify string ownership - Proper GCharPtr usage
156
+ - [x] **Added**: Defensive null checks for GObjectPtr::get()
157
+ - [x] **Added**: Null checks for string getters
158
+ - [x] **Added**: const-correctness for all GCharPtr and GObjectPtr locals
159
+ - **Platform APIs verified**:
160
+ - GDrive/GVolume metadata APIs - Ownership transfer rules
161
+
162
+ ## Testing Strategy
163
+
164
+ ### Memory Leak Detection ✅
165
+ 1. [x] Run valgrind, LeakSanitizer, and AddressSanitizer on Linux builds
166
+ - **Implemented**: Comprehensive memory testing infrastructure
167
+ - Valgrind: `npm run test:valgrind` with suppressions in `.valgrind.supp`
168
+ - AddressSanitizer: `npm run asan` with proper clang integration
169
+ - LeakSanitizer: Integrated with ASan, suppressions in `.lsan-suppressions.txt`
170
+ - All tests show 0 memory leaks in fs-metadata code
171
+ 2. [ ] Use Application Verifier on Windows
172
+ 3. [ ] Enable address sanitizer for macOS builds
173
+ 4. [x] Run existing memory.test.ts with extended iterations
174
+ - JavaScript memory tests: `npm run test:memory`
175
+ - Comprehensive suite: `npm run tests:memory`
176
+
177
+ ### API Verification
178
+ 1. [ ] Use Perplexity/WebSearch to verify:
179
+ - Minimum OS version requirements for each API
180
+ - Deprecated API alternatives
181
+ - Thread safety guarantees
182
+ - Memory ownership rules
183
+ 2. [ ] Cross-reference with official documentation:
184
+ - Apple Developer Documentation
185
+ - Microsoft Win32 API Reference
186
+ - Linux man pages and library docs
187
+
188
+ ### Resource Management
189
+ 1. [ ] Add stress tests for mount/unmount cycles
190
+ 2. [ ] Test with network filesystem timeouts
191
+ 3. [ ] Verify cleanup on exception paths
192
+ 4. [ ] Test with maximum path lengths
193
+
194
+ ## Priority Items
195
+
196
+ 1. ~~**Critical**: Thread safety in Windows DriveHealthChecker (src/windows/drive_status.h)~~ ✅ Completed
197
+ - ✅ Replaced `volatile bool shouldTerminate` with `std::atomic<bool>`
198
+ - ✅ Replaced `DriveStatus result` with `std::atomic<DriveStatus>`
199
+ - ✅ Removed dangerous `TerminateThread` usage
200
+ - ✅ Increased graceful shutdown timeout from 100ms to 1000ms
201
+ 2. ~~**High**: Windows API buffer issues~~ ✅ Completed
202
+ - ✅ WNetConnection: Handle ERROR_MORE_DATA with dynamic buffer resize
203
+ - ✅ GetVolumeInformation: Use MAX_PATH+1 instead of BUFFER_SIZE
204
+ 3. ~~**High**: CoreFoundation reference counting in macOS code~~ ✅ Completed - CFReleaser RAII wrapper
205
+ 4. ~~**High**: GIO object lifecycle management~~ ✅ Completed - Using smart pointers throughout
206
+ 5. ~~**Medium**: Security - Add comprehensive path validation~~ ✅ Completed
207
+ - ✅ Check for ".." in all platforms (Windows/Darwin have it, Linux doesn't have hidden file support)
208
+ - Validate against null bytes and special characters (remaining)
209
+ - Add input validation for empty mount points (remaining)
210
+ 6. ~~**Medium**: String encoding conversions across platforms~~ ✅ Completed - Proper UTF-8/wide conversions
211
+ 7. ~~**Medium**: Buffer overflow protection in size calculations~~ ✅ Completed - Darwin has exemplary protection
212
+
213
+ ### Completed Items
214
+ - ✅ Linux memory management review (all files)
215
+ - ✅ Darwin/macOS memory management review (all files)
216
+ - ✅ Windows memory management review (all files including drive_status.h)
217
+ - ✅ const-correctness improvements across codebase
218
+ - ✅ Memory leak detection infrastructure (Valgrind + ASan)
219
+ - ✅ Static analysis integration (clang-tidy)
220
+ - ✅ Comprehensive memory testing documentation
221
+ - ✅ RAII patterns verified across all platforms
222
+ - ✅ N-API usage verified - no deprecated functions
223
+ - ✅ Platform API compatibility verified
224
+ - ✅ Thread safety issues resolved (std::atomic usage)
225
+ - ✅ Windows API buffer handling fixed
226
+ - ✅ Path validation for directory traversal added
227
+
228
+ ## Recent Improvements (Completed)
229
+
230
+ ### Code Quality
231
+ 1. **const-correctness**: Added `const` qualifiers to all appropriate local variables across the codebase
232
+ - All Napi::Env instances
233
+ - All GCharPtr, GObjectPtr, GFileInfoPtr instances
234
+ - All std::lock_guard instances
235
+ - Improves code safety and enables compiler optimizations
236
+
237
+ 2. **Static Analysis**: Integrated clang-tidy
238
+ - Added to CI/CD pipeline
239
+ - Uses bear to generate compile_commands.json
240
+ - Runs only on platform-relevant files
241
+ - Added to precommit checks
242
+
243
+ 3. **Memory Testing Infrastructure**
244
+ - Created comprehensive memory testing documentation (`docs/MEMORY_TESTING.md`)
245
+ - Improved ASan configuration with proper suppressions
246
+ - Created standalone test runner (`scripts/run-asan.sh`)
247
+ - Updated `scripts/check-memory.mjs` with better ASan support
248
+ - All memory tests integrated into CI/CD
249
+
250
+ ## Documentation Updates Needed
251
+
252
+ - [x] Document RAII pattern usage guidelines - See existing code patterns
253
+ - [x] Add platform-specific memory management notes - Added to MEMORY_TESTING.md
254
+ - [x] Create error handling best practices - Documented in code
255
+ - [ ] Document thread safety requirements
256
+
257
+ ## Platform API Resources
258
+
259
+ ### macOS/Darwin
260
+ - Core Foundation Memory Management: Functions with "Create" or "Copy" require CFRelease
261
+ - DiskArbitration: Follows standard Core Foundation ownership rules
262
+ - Key Documentation: Apple Developer Documentation for DiskArbitration framework
263
+ - **Review Status**: ✅ All files use proper RAII with CFReleaser template
264
+
265
+ ### Windows
266
+ - WNetGetConnection: Start with 256 chars, handle ERROR_MORE_DATA
267
+ - GetVolumeInformation: Fixed buffers of MAX_PATH+1
268
+ - Key Documentation: Microsoft Learn Win32 API Reference
269
+ - **Review Status**: ⚠️ Buffer handling needs fixes, thread safety critical issue
270
+
271
+ ### Linux
272
+ - libblkid: Use free() for blkid_get_tag_value results, blkid_put_cache() for cache
273
+ - GLib/GIO: Use g_object_unref() or g_clear_object(), match allocation functions
274
+ - Key Documentation: libblkid man pages, GNOME Developer Documentation
275
+ - **Review Status**: ✅ All files properly reviewed and use smart pointers
276
+
277
+ ## Critical Windows Thread Safety Issue ✅ FIXED
278
+
279
+ File: `src/windows/drive_status.h`
280
+ ```cpp
281
+ // Fixed code:
282
+ std::atomic<bool> shouldTerminate{false}; // Using atomic with proper memory ordering
283
+ std::atomic<DriveStatus> result{DriveStatus::Unknown}; // Thread-safe result storage
284
+ // Removed TerminateThread - now uses graceful shutdown with 1000ms timeout
285
+ ```
286
+
287
+ This critical issue has been resolved:
288
+ - ✅ Race conditions eliminated with std::atomic
289
+ - ✅ Removed dangerous TerminateThread call
290
+ - ✅ Proper memory ordering with acquire/release semantics
291
+ - ✅ Graceful thread shutdown with increased timeout
package/CHANGELOG.md CHANGED
@@ -14,6 +14,34 @@ Fixed for any bug fixes.
14
14
  Security in case of vulnerabilities.
15
15
  -->
16
16
 
17
+ ## [0.5.0] - 2025-06-01
18
+
19
+ ### Added
20
+
21
+ - Comprehensive memory testing framework with Valgrind and AddressSanitizer support
22
+ - Thread safety tests for Windows platform
23
+ - Platform-specific build scripts with automatic OS detection
24
+ - Clang-tidy integration for C++ code analysis
25
+
26
+ ### Breaking
27
+
28
+ - Dropped support for Node.js v18, added support for Node.js v24
29
+
30
+ ### Changed
31
+
32
+ - Simplified ESM/CJS dual module support with unified build configuration
33
+ - Enhanced test coverage with additional error handling and edge case tests
34
+ - Updated all imports to use `node:` prefix for built-in modules
35
+
36
+ ### Fixed
37
+
38
+ - Added path validation to prevent directory traversal vulnerabilities in hidden file operations
39
+ - Improved error handling and null checks across Linux GIO implementation
40
+ - Fixed buffer allocation issues in Windows networking and volume operations
41
+ - Enhanced resource management with better validation for empty mount points
42
+ - Made `SystemPathPatternsDefault` values visible in TypeScript typings
43
+ - Improved test reliability across different CI environments
44
+
17
45
  ## [0.4.0] - 2025-01-09
18
46
 
19
47
  - `Fixed`: Switch to thread-safe `getmntinfo_r_np()` for macOS. Improved darwin resource management.
@@ -23,7 +51,7 @@ Security in case of vulnerabilities.
23
51
  - `Packaging`: Improved ESM/CJS support with common `__dirname` implementation thanks to `tsup` [shims](https://tsup.egoist.dev/#inject-cjs-and-esm-shims).
24
52
 
25
53
  This change simplifies the implementation and improves inline jsdocs as the exported code and docs have been inlined.
26
-
54
+
27
55
  - `Packaging`: Re-enabled test coverage assertions (after finding the magicks to get istanbul to see what the tests were exercising)
28
56
 
29
57
  - `Packaging`: Added debuglog tests
package/CLAUDE.md ADDED
@@ -0,0 +1,169 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ This is @photostructure/fs-metadata - a cross-platform native Node.js module for retrieving filesystem metadata, including mount points, volume information, and space utilization statistics.
8
+
9
+ ### Key Features
10
+ - Cross-platform support: Windows 10+ (x64), macOS 14+, Ubuntu 22+ (x64, arm64)
11
+ - Lists all mounted volumes/drives
12
+ - Gets detailed volume metadata (size, usage, filesystem type, etc.)
13
+ - Hidden file/directory attribute support (get/set)
14
+ - Non-blocking async native implementations
15
+ - Timeout handling for unresponsive network volumes
16
+ - ESM and CJS module support
17
+ - Full TypeScript type definitions
18
+
19
+ ### Platform-Specific Notes
20
+ - **Linux**: Optional GIO/GVfs mount support via Gnome libraries
21
+ - **Windows**: Uses separate threads per mountpoint for health checks to handle blocked system calls
22
+ - **System Volumes**: Each platform handles system volumes differently; the library uses heuristics to identify them
23
+
24
+ ## Common Commands
25
+
26
+ ### Build and Development
27
+ ```bash
28
+ # Install dependencies and build native modules
29
+ npm install
30
+
31
+ # Configure platform-specific build settings
32
+ npm run configure
33
+
34
+ # Build native bindings
35
+ npm run node-gyp-rebuild
36
+
37
+ # Create prebuilds for distribution
38
+ npm run prebuild
39
+
40
+ # Bundle TypeScript to dist/
41
+ npm run bundle
42
+ ```
43
+
44
+ ### Testing
45
+ ```bash
46
+ # Run all tests with coverage (includes memory tests on Linux)
47
+ npm run tests
48
+
49
+ # Run CommonJS tests
50
+ npm test cjs
51
+
52
+ # Run ESM tests
53
+ npm test esm
54
+
55
+ # Test memory leaks (JavaScript)
56
+ npm run test:memory
57
+
58
+ # Run valgrind memory analysis (Linux only)
59
+ npm run test:valgrind
60
+
61
+ # Run comprehensive memory tests (JavaScript + valgrind on Linux)
62
+ npm run tests:memory
63
+
64
+ # Run AddressSanitizer tests (Linux only)
65
+ npm run asan
66
+
67
+ # Run a specific test file (no coverage)
68
+ npm test volume_metadata
69
+ ```
70
+
71
+ ### Code Quality
72
+ ```bash
73
+ # Run ESLint
74
+ npm run lint
75
+
76
+ # Fix ESLint issues
77
+ npm run lint:fix
78
+
79
+ # Format code (all formats)
80
+ npm run fmt
81
+
82
+ # Format C++ code only
83
+ npm run fmt:cpp
84
+
85
+ # Format TypeScript only
86
+ npm run fmt:ts
87
+
88
+ # Type checking
89
+ npm run compile
90
+ ```
91
+
92
+ ### Pre-commit
93
+ ```bash
94
+ # Full precommit check (fmt, clean, prebuild, tests)
95
+ npm run precommit
96
+ ```
97
+
98
+ ### Documentation
99
+ ```bash
100
+ # Generate API documentation
101
+ npm run docs
102
+ ```
103
+
104
+ ## Architecture Overview
105
+
106
+ ### Core Structure
107
+ - **Native binding layer** (`src/binding.cpp`): Node-API v9 bridge between JavaScript and platform-specific implementations
108
+ - **Platform abstractions** in `src/common/`: Shared C++ interfaces for cross-platform functionality
109
+ - **Platform implementations**:
110
+ - `src/darwin/`: macOS-specific code using Core Foundation APIs
111
+ - `src/linux/`: Linux-specific code with optional GIO support for GNOME/GVfs
112
+ - `src/windows/`: Windows-specific code using Win32 APIs
113
+
114
+ ### Key Features
115
+ - **Volume Metadata**: Retrieves filesystem information (mount points, disk usage, health status)
116
+ - **Hidden File Support**: Cross-platform hidden file detection and manipulation
117
+ - **Async Operations**: All native operations use Worker threads to avoid blocking
118
+
119
+ ### Build System
120
+ - Uses `node-gyp` for native compilation
121
+ - Conditionally enables GIO support on Linux via `scripts/configure.mjs`
122
+ - Provides prebuilt binaries via `prebuildify` for common platforms
123
+ - Supports both ESM and CJS module formats
124
+
125
+ ### Testing Strategy
126
+ - Jest for both CJS and ESM test suites
127
+ - Platform-specific test expectations handled via `isWindows`, `isMacOS`, `isLinux` helpers
128
+ - Memory leak testing with garbage collection monitoring
129
+ - Coverage thresholds: 80% for all metrics
130
+
131
+ ### Memory Testing
132
+ - JavaScript memory tests: `npm run test:memory` - uses GC and heap monitoring
133
+ - Valgrind integration: `npm run test:valgrind` - runs on Linux only, checks for memory leaks
134
+ - AddressSanitizer: `npm run asan` - runs on Linux only, detects memory errors and leaks (~2x faster than Valgrind)
135
+ - Comprehensive memory tests: `npm run tests:memory` - runs all memory tests appropriate for the platform
136
+ - Automated test runners: `scripts/valgrind-test.mjs` and `scripts/run-asan.sh`
137
+ - CI/CD includes both valgrind and ASAN tests via `.github/workflows/memory-tests.yml`
138
+ - Cross-platform memory check script: `scripts/check-memory.mjs` handles platform differences
139
+ - Suppression files: `.valgrind.supp` (Valgrind), `.lsan-suppressions.txt` (LeakSanitizer)
140
+ - Memory tests are integrated into `npm run tests` pipeline on Linux
141
+ - See `docs/MEMORY_TESTING.md` for detailed memory testing guide
142
+
143
+ ### Timeout Handling
144
+ - Default timeout for volume operations to handle unresponsive network mounts
145
+ - Windows uses separate threads per mountpoint for health checks
146
+ - Configurable via `Options` interface
147
+
148
+ ### Debug Logging
149
+ - Enable with `NODE_DEBUG=fs-meta` or `NODE_DEBUG=photostructure:fs-metadata`
150
+ - Debug messages from both JavaScript and native code are sent to `stderr`
151
+ - Uses native Node.js debuglog for determining if logging is enabled
152
+
153
+ ## Example Usage
154
+
155
+ ```typescript
156
+ import { getVolumeMountPoints, getVolumeMetadata } from "@photostructure/fs-metadata";
157
+
158
+ // List all mounted volumes
159
+ const mountPoints = await getVolumeMountPoints();
160
+ console.dir({ mountPoints });
161
+
162
+ // Get metadata for a specific volume
163
+ const volumeMetadata = await getVolumeMetadata(mountPoints[0]);
164
+ console.dir({ volumeMetadata });
165
+
166
+ // Check if a file is hidden
167
+ import { isHidden } from "@photostructure/fs-metadata";
168
+ const hidden = await isHidden("/path/to/file");
169
+ ```
package/CONTRIBUTING.md CHANGED
@@ -44,3 +44,28 @@ into account both Windows and POSIX systems.
44
44
  - Windows on x64
45
45
  - glibc Linux on x64 and arm64, with or without Gnome GIO support
46
46
  - MUSL Alpine Linux on x64 and arm64
47
+
48
+ ## Development Gotchas
49
+
50
+ ### Windows Shell Parsing in npm Scripts
51
+
52
+ **Problem**: npm scripts containing Unix shell operators like `||` with complex commands will fail on Windows with syntax errors like `$' was unexpected at this time.`
53
+
54
+ **Why**: Windows Command Prompt/PowerShell parses the entire command line before execution, including the Unix-specific parts that would never run on Windows. Even though constructs like `node scripts/is-platform.mjs win32 || <unix-command>` would exit early on Windows, the shell still tries to parse the syntax after `||`.
55
+
56
+ **Solution**: For platform-specific npm scripts that use shell operators:
57
+ - Create a wrapper Node.js script that handles platform detection internally (see `scripts/clang-tidy.mjs`)
58
+ - The wrapper can use `process.platform` or `os.platform()` to detect Windows and exit early
59
+ - Unix-specific commands can then be spawned using `child_process.spawn()` with `sh -c`
60
+
61
+ **Example**: The `clang-tidy` npm script was moved from:
62
+ ```json
63
+ "clang-tidy": "node scripts/is-platform.mjs win32 || (npm run configure && bear -- npm run node-gyp-rebuild && find src -name '*.cpp' -o -name '*.h' | grep -E '\\.(cpp|h)$' | grep -v -E '(windows|darwin)/' | xargs clang-tidy)"
64
+ ```
65
+
66
+ To:
67
+ ```json
68
+ "clang-tidy": "node scripts/clang-tidy.mjs"
69
+ ```
70
+
71
+ Where the script handles platform detection and command execution internally.