|
2 | 2 |
|
3 | 3 | All notable changes to this project will be documented in this file. |
4 | 4 |
|
| 5 | +## [1.4.1] - 2026-03-14 |
| 6 | + |
| 7 | +### Fixed |
| 8 | + |
| 9 | +- **Critical crash on bool config fields** — ToggleSwitch crashes with `PART_MovingKnobs` KeyNotFoundException when Molten Forge theme is active; replaced with CheckBox |
| 10 | +- **Memory leaks** — PipelineNodeViewModel and PipelineConnectorViewModel event subscriptions to `ActualThemeVariantChanged` and `PropertyChanged` were never unsubscribed, preventing GC; added `Detach()` cleanup on node removal |
| 11 | +- **Path traversal** — crafted filenames could escape output directories via RenamePatternNode, RenameAddAffixNode, RenameRegexNode (filename mode), and FolderOutputNode; added `PathGuard.EnsureWithinDirectory()` checks |
| 12 | +- **ReDoS vulnerability** — RenameRegexNode compiled user-supplied regex with no timeout; added 2-second timeout matching FilterNode |
| 13 | +- **Dry-run file I/O** — MetadataExtractNode, FilterNode, and SortNode performed disk reads during dry-run; now return defaults without file access |
| 14 | +- **ImageCompressNode data loss** — overwrote original file in-place; now saves to temp file and swaps atomically |
| 15 | +- **Output node error isolation** — first output node failure no longer prevents subsequent outputs from running |
| 16 | +- **Silently dropped jobs** — transforms returning empty with Processing status are now counted as skipped |
| 17 | +- **CTS race condition** — `Cancel()` and `Dispose()` on `_cts` could race; fixed with `Interlocked.Exchange` |
| 18 | +- **Predictable temp files** — PipelineSerializer and AppSettingsManager used `.tmp` suffix; now use random GUID suffix |
| 19 | +- **Serializer TOCTOU** — removed redundant `File.Exists` check before `ReadAllTextAsync` |
| 20 | +- **Sync File.Exists on UI thread** — removed blocking call from `OpenRecentAsync` |
| 21 | + |
| 22 | +### Added |
| 23 | + |
| 24 | +- **Path traversal protection** — `PathGuard.EnsureWithinDirectory()` helper used by all rename nodes and FolderOutputNode |
| 25 | +- **Decompression bomb guard** — 500 MB file size check and `MaxFrames = 1` decoder option on all image nodes |
| 26 | +- **ImageResize dimension bounds** — width/height validated to 1-32768 in `Configure()` |
| 27 | +- **Crash log handler** — unhandled exceptions write to `crash.log` in app directory |
| 28 | +- **13 new tests** — cancellation, dry-run, path traversal, ReDoS timeout, bounds validation, serializer edge cases (322 total) |
| 29 | + |
| 30 | +### Changed |
| 31 | + |
| 32 | +- **ConfigureAwait(false)** — added to all Core async methods to avoid unnecessary UI thread marshaling |
| 33 | +- **SortNode performance** — pre-compute sort keys to eliminate O(n log n) filesystem calls |
| 34 | +- **FileJob property caching** — `Extension`, `FileName`, `DirectoryName` cached with lazy invalidation |
| 35 | +- **Streaming serialization** — PipelineSerializer and AppSettingsManager stream to FileStream instead of string buffer |
| 36 | +- **Execution log batching** — buffer FileProcessed events with 50ms DispatcherTimer flush to reduce UI layout thrashing |
| 37 | +- **FilterNode normalization** — operator/field strings lowercased at configure time instead of per-file |
| 38 | +- **ImageConvertNode encoder caching** — encoder created once in `Configure()` instead of per file |
| 39 | +- **DRY refactoring** — extracted `ThemeHelper`, `NodeIconMap`, shared `ConfigHelper` test helper |
| 40 | +- **Named event handlers** — anonymous lambdas replaced with named methods in EditorViewModel and MainWindowViewModel |
| 41 | +- **NodeLibrary filtering** — reuses group VMs with `ApplyFilter()` instead of recreating per keystroke |
| 42 | +- Microsoft.Extensions.* 10.0.3 → 10.0.5, System.CommandLine 2.0.3 → 2.0.5 |
| 43 | + |
5 | 44 | ## [1.4.0] - 2026-03-07 |
6 | 45 |
|
7 | 46 | ### Added |
|
0 commit comments