Skip to content

Fix KeePass XML parser compatibility - #979

Merged
theoephraim merged 6 commits into
mainfrom
pullfrog/978-fix-keepass-xmldom-parser
Aug 7, 2026
Merged

Fix KeePass XML parser compatibility#979
theoephraim merged 6 commits into
mainfrom
pullfrog/978-fix-keepass-xmldom-parser

Conversation

@pullfrog

@pullfrog pullfrog Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Fixes #978.

kdbxweb builds its parser with the errorHandler object that @xmldom/xmldom removed in 0.9, so the root overrides entry pinning xmldom to >=0.9.10 (added as a security floor) broke every KeePass database with errorHandler object is no longer supported. kdbxweb has not shipped a release since 2021 and upstream still has the old code, so there is no version to upgrade to.

Since the plugin bundles kdbxweb, its xmldom import is now redirected at build time to src/xmldom-compat.ts, a small wrapper that translates errorHandler into the supported onError callback and re-exports the rest of xmldom untouched. The override stays where it is, and the constraint lives in the one plugin that has it rather than capping xmldom for the whole repo.

Two things worth knowing for anyone touching that config: esbuild's alias option cannot express this (it prefix-matches subpaths, so the shim's own import resolves back into the shim, which is why it uses an onResolve hook), and xmldom has to be a direct dependency of the plugin or it will not resolve under bun's isolated installs.

The alternative was pinning xmldom to ^0.8.13, the newest release kdbxweb can talk to and free of the advisories that motivated the override. That worked, but put a repo-wide ceiling on a dependency for one plugin's sake.

Plugin tests now run in CI

This shipped because no plugin package defined a test:ci script, and CI runs turbo test:ci. The keepass suite reproduces this bug exactly, and had been failing unnoticed.

  • test:ci added to all 10 plugin packages that have tests. 1password and infisical build a separate test bundle first, without which their suites error out and report 31 and 5 tests "skipped".
  • turbo's test:ci now depends on build, since plugin tests load dist/plugin.cjs rather than src.
  • @varlock/website excluded from the root test:ci, so that new build dependency does not drag a full Astro build into every test run.

Unit tests cover the compat wrapper directly. A valid database cannot produce the non-fatal parse errors it guards against (the KDBX HMAC catches corruption first), so the strict-parse behavior is not reachable end to end.

Deferred KeePass setup

@initKeePass resolved dbPath/password eagerly at schema load, so an empty master password was fatal even when nothing in the schema read from KeePass. Setup now runs on the first kp()/kpBulk() call, memoized per instance. This is what the existing unused plugin with empty password causes no errors test always expected.

Verification

Full test:ci --force: 43/43 tasks, keepass 24/24. bun audit clean for the keepass plugin. Lint, typecheck:all, and the docs build all pass. Confirmed the built dist/plugin.cjs bundles xmldom 0.9.10 and opens real databases through it.

Pullfrog  | View workflow run | via Pullfrog | Using azure/gpt-5.6-sol𝕏

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

bumpy-frog

The changes in this PR will be included in the next version bump.

patch Patch releases

  • @varlock/keepass-plugin 2.0.0 → 2.0.1

Bump files in this PR

Click here if you want to add another bump file to this PR


This comment is maintained by bumpy.

@pkg-pr-new

pkg-pr-new Bot commented Aug 4, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/varlock@979
npm i https://pkg.pr.new/@varlock/keepass-plugin@979

commit: b32b0c2

The kdbxweb patch only reaches users because the plugin bundles kdbxweb at
build time, and nothing verified that. Plugin test suites had no `test:ci`
script, so `turbo test:ci` never ran them - the keepass suite reproduces this
bug exactly but had been failing unnoticed.

- add `test:ci` to every plugin package that has tests (10 suites)
- make turbo's `test:ci` depend on `build`, since plugin tests load dist/
- exclude the website from `test:ci` so it doesn't drag in a full astro build
- defer @initKeePass db setup until a kp()/kpBulk() call runs, so an unused
  instance with an empty password no longer fails the whole schema
- document the kdbxweb patch and its tie to the @xmldom/xmldom override
kdbxweb passes the errorHandler object that xmldom removed in 0.9, so the
root override (>=0.9.10, added for security) broke every KeePass database.
xmldom 0.8.13 shipped the same day as 0.9.10 with all five advisories
backported, and it still accepts errorHandler - so a version pin fixes this
with no patched dependency to maintain.

kdbxweb is the only package in the repo that depends on xmldom, and bun
ignores yarn-style scoped overrides, so the pin has to be global.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 7, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
varlock-website 8bebc4b Commit Preview URL

Branch Preview URL
Aug 07 2026, 07:43 PM

kdbxweb builds its parser with the errorHandler object that @xmldom/xmldom
removed in 0.9, so the root override (>=0.9.10) broke every KeePass database.
Pinning xmldom back to 0.8.x fixed it, but put a repo-wide ceiling on a
dependency for one plugin's sake.

kdbxweb's xmldom import is now redirected at build time to a small wrapper
that translates errorHandler into the supported onError callback, so the
override stays where it was and the constraint lives in the plugin that has
it. Unit tests cover the wrapper directly, since the strict parse behavior it
preserves is not otherwise reachable from a valid database file.
@pullfrog

pullfrog Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

Fixed the CI failure in commit 404fae4e and pushed it to PR #979. The test fixture's direct kdbxweb import was bypassing the plugin's bundled xmldom shim, so fixture creation now temporarily uses the compatible DOM implementation while plugin execution continues to exercise the bundle end to end; bun run test:ci passes all 43 tasks, and lint plus the KeePass typecheck pass.

Task list (5/5 completed)

Pullfrog  | View workflow run | via Pullfrog | Using azure/gpt-5.6-sol𝕏

@theoephraim
theoephraim merged commit 6ceaa75 into main Aug 7, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: errorHandler object is no longer supported, switch to onError! when opening KeePass database

1 participant