Skip to content

Plugin hardening#85

Open
facontidavide wants to merge 9 commits intomainfrom
plugin_hardening
Open

Plugin hardening#85
facontidavide wants to merge 9 commits intomainfrom
plugin_hardening

Conversation

@facontidavide
Copy link
Copy Markdown
Contributor

Compared to main, plugin_hardening is mostly a plugin ABI and loader hardening branch.

The first big change is plugin lifetime safety. Plugin handles now retain the loaded shared library while vtable-backed handles are alive, and dialog
handles can also carry a library owner. The reason is to avoid dangling vtable pointers after a DSO has been unloaded.

The second theme is stricter plugin validation. Source, parser, toolbox, and dialog vtables now get required-slot validation, and malformed plugins are
rejected during load or catalog scan instead of crashing later when a null callback is invoked. Some host callback/trampoline boundaries were also
hardened so exceptions and errors are translated at the ABI boundary.

Dialog discovery changed substantially. Dialog plugins can now expose a static manifest tail slot, so catalog scanning can read metadata without
instantiating the dialog plugin. There is still fallback behavior for older dialogs or null static manifests. This avoids running plugin constructors
during what should be metadata-only discovery.

The dialog loader was brought up to parity with the other plugin family loaders. DialogLibrary now uses the shared loader path, checks
pj_plugin_abi_version, validates required slots, and gets the same Windows sibling-DLL behavior as source/parser/toolbox loaders.

Parser writes gained an optional bulk Arrow path. Parser write hosts now have an optional append_arrow_stream tail slot, with SDK support and datastore
plumbing. This lets parser-shaped formats ingest naturally batched data without paying per-record overhead. Existing plugins do not need to change; only
plugins that want this new path need to rebuild against the new headers.

The branch also adds more ABI guardrails: layout sentinels for write-host and dialog vtables, plus a parser write-host minimum-size constant. These are
compile-time checks to catch accidental ABI field reorders or baseline drift.

Docs were updated across the plugin architecture, requirements, source/parser/toolbox/dialog guides, and datastore guide. The goal was to remove stale
guidance and make plugin ownership, manifest discovery, and bulk-write behavior match the actual code.

Finally, tests were expanded around these hardening points: required-slot failures, dialog loader failures, catalog regressions, parser Arrow stream
round trips, ABI layout sentinels, and the valid borrowed-dialog lifetime case.

Davide Faconti added 9 commits May 6, 2026 12:08
Add a static manifest tail slot to dialog vtables and teach catalog discovery to use it when present, while preserving the legacy create/get_manifest fallback for existing plugins.

Update SDK examples and docs for the two-argument dialog export, cover the static-manifest path in tests, and simplify redundant unexpected(std::string(...)) error construction.
Use the dialog static manifest tail slot only when it is present and non-null. New-header plugins using the legacy one-argument dialog macro now correctly fall back to runtime manifest discovery.
Keep the loader required-slot checks in a private implementation unit and wire them through an internal detail library. Also remove the dialog protocol subproject's global C++ standard override so it no longer downgrades the root build setting.
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