Skip to content

fix: open SQLite on Windows long paths normalised to forward slashes - #133

Merged
abrignoni merged 2 commits into
mainfrom
fix/sqlite-longpath-uri
Aug 14, 2026
Merged

fix: open SQLite on Windows long paths normalised to forward slashes#133
abrignoni merged 2 commits into
mainfrom
fix/sqlite-longpath-uri

Conversation

@abrignoni

Copy link
Copy Markdown
Owner

What

get_sqlite_db_path() in scripts/ilapfuncs.py builds the file: URI that
open_sqlite_db_readonly() and attach_sqlite_db_readonly() use. It detected the Windows
extended-length prefix \\?\ by its backslashes only.

Many artifacts normalise a path to forward slashes for their own matching (splitting on /,
checking /mirror/) and then open that same string. On a Windows output path over 260
characters, the seeker path already carries the \\?\ long-path prefix, so normalising turns
it into //?/. That matched none of the prefix checks, fell to the normal-path branch, and
got a second \\?\ prepended:

file:%5C%5C%3F%5C//%3F/D:/...?mode=ro decodes to \\?\//?/D:/...

SQLite returns "unable to open database file", the helper returns None, and the artifact
loses its data. siminfo and usageapps are two confirmed cases. The forward-slash idiom is
common, so a per-artifact fix would be whack-a-mole; the helper is the right place.

The fix

One line: restore backslashes before inspecting the prefix.

path_str = str(path).replace('/', '\\')

/ is never a valid filename character on Windows and \\?\ paths require backslashes, so
this is always safe there. All four incoming forms (backslash or forward slash, extended or
plain) collapse to the single valid \\?\D:\...\file.db URI the helper already produced for
backslash inputs.

Testing

  • Unit: the patched function, with Windows forced, maps //?/D:/... and D:/... to a valid
    \\?\D:\... URI, and leaves backslash-extended, plain-backslash, spaces / #, and
    extended-UNC inputs byte-for-byte identical to before. No regression to working paths.
  • Corpus (macOS): before and after produce identical row counts on a Samsung image (siminfo
    2, SMS 123, MMS 12, Contacts 12), zero errors. Expected, since the change is inside the
    Windows-only branch.
  • Not yet confirmed end to end on a real Windows extraction over 260 characters. That is
    the platform this fixes and it needs a Windows run to close out. The change introduces no
    new URI form: it routes the broken inputs onto the backslash-extended URI that already
    ships and works.

Leveled across all five cores (iLEAPP, ALEAPP, RLEAPP, VLEAPP, DLEAPP); the helper is
identical in each.

Reported by Mattia Epifani.

abrignoni and others added 2 commits August 14, 2026 19:07
get_sqlite_db_path detected the \\?\ extended-length prefix by its
backslashes only. An artifact that normalises a path to forward slashes,
a common idiom for its own path matching, turns that prefix into //?/.
That form matched none of the checks, fell through to the normal-path
branch, and had a second \\?\ prepended, producing \\?\//?/D:/... which
SQLite cannot open. The database then failed to open on any Windows
output path over 260 characters, and every SQLite artifact reading such
a path silently lost its data.

Restore backslashes before inspecting the prefix. '/' is never a valid
filename character on Windows and \\?\ paths require backslashes, so the
conversion is always safe there. All four incoming forms (backslash or
forward slash, extended or plain) now collapse to the single valid
\\?\D:\...\file.db URI the helper already produced for backslash inputs,
so paths that work today are byte-for-byte unchanged.

Reported by Mattia Epifani, who hit it on a long ALEAPP output path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds a Windows-only regression test for the get_sqlite_db_path fix in the
previous commit. It builds a real SQLite database at a path over 260
characters through the \\?\ extended prefix, normalises that path to forward
slashes the way an artifact does, and asserts open_sqlite_db_readonly returns
a usable connection and reads a row back. A negative control reproduces the
pre-fix URI (\\?\//?/...) and asserts it really fails to open on the runner,
so the positive assertion is not vacuous.

The ubuntu runtime-contract job discovers the file and skips it, since \\?\
extended-length paths are a Windows-only concept. windows_smoke.yml runs it
for real, alongside the existing import smoke test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@abrignoni
abrignoni merged commit c0a972a into main Aug 14, 2026
7 checks passed
@abrignoni
abrignoni deleted the fix/sqlite-longpath-uri branch August 14, 2026 23:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant