Skip to content

Corrección: fix(filetxn): read directory identity through per-OS variants (#386) #391

Open

Description

@barbatdev

Source PR: #386
Branch: fix/windows-filetxn-directory-identity
Head reviewed: 4e3e08c

Push the fixes to the branch above; do not open a new pull request. Comment on the PR and on this issue when done.

Blocking findings

  • Windows identity read has no long-path handling, and the >MAX_PATH subtest asserts a host-dependent result (internal/filetxn/identity_windows.go:22): directoryIdentity hands the path verbatim to syscall.UTF16PtrFromString (line 18) and syscall.CreateFile (line 22). Neither applies the long-path handling that the os package adds to its own calls (os.Lstat, os.MkdirAll, os.Open), so the same path succeeds for the rest of the transaction and fails only in the identity read. The Windows refusals test then asserts the opposite for a long path: identity_windows_test.go:74 builds a path past 300 characters with os.MkdirAll and requires ok == true, which holds only when the host has the LongPathsEnabled registry value set. The PR body records go test -run TestDirectoryIdentity ./internal/filetxn/ as passing on Windows 11 without stating that host setting, so the evidence is not reproducible from the PR on a default Windows install.
    • Failure scenario: On a default Windows 11 host (LongPathsEnabled unset), go test -run TestDirectoryIdentityWindowsRefusals ./internal/filetxn/ fails the path longer than MAX_PATH subtest with long path (N chars) has no identity: os.MkdirAll creates the 300+ character directory through the os package, then syscall.CreateFile on the unprefixed name returns ERROR_PATH_NOT_FOUND and directoryIdentity reports ok=false. In the product, an install whose directory target path exceeds MAX_PATH creates its directories and then aborts the transaction in acceptCreatedDirectories with accepted directory identity is unavailable: <path>, instead of recording the identity the way it does for shorter paths.

Acceptance criteria

  • Fixed: Windows identity read has no long-path handling, and the >MAX_PATH subtest asserts a host-dependent result (internal/filetxn/identity_windows.go:22). The scenario below no longer reproduces: On a default Windows 11 host (LongPathsEnabled unset), go test -run TestDirectoryIdentityWindowsRefusals ./internal/filetxn/ fails the path longer than MAX_PATH subtest with long path (N chars) has no identity: os.MkdirAll creates the 300+ character directory through the os package, then syscall.CreateFile on the unprefixed name returns ERROR_PATH_NOT_FOUND and directoryIdentity reports ok=false. In the product, an install whose directory target path exceeds MAX_PATH creates its directories and then aborts the transaction in acceptCreatedDirectories with accepted directory identity is unavailable: <path>, instead of recording the identity the way it does for shorter paths.

Activity

  1. barbatjuan commented on Oct 24, 2026

    @barbatjuan
    Contributor

    Fixed on fix/windows-filetxn-directory-identity:

    • 1011b41: directoryIdentity opens long clean absolute paths through the \\?\ prefix (\\?\UNC\ for UNC), as the os package does, so the identity read no longer depends on the runtime long-path opt-in or on LongPathsEnabled.
    • adaec91: device paths stay unprefixed, and the prefix wiring is pinned by a test.

    Re-run of the scenario on a default Windows 11 host (LongPathsEnabled = 0x0), go1.26.5, head adaec91:

    go test -count=1 -v -run 'TestDirectoryIdentityWindowsRefusals/path_longer|TestDirectoryIdentityOpensLongPathsExtended' ./internal/filetxn/
    --- PASS: TestDirectoryIdentityOpensLongPathsExtended
    --- PASS: TestDirectoryIdentityWindowsRefusals/path_longer_than_MAX_PATH
    

    With the prefix removed from directoryIdentity, TestDirectoryIdentityOpensLongPathsExtended fails. That test opens a long directory whose name ends with a dot, which only the \\?\ form preserves. Details are in the PR thread: #386 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions