mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-14 19:31:14 +00:00
A fifth Python plugin capability type, ResourceTexture, contributes height-map textures to the Texture Displacement picker. A pack returns a directory of images; the host validates it once at load and lists the images under a section of their own. - New capability type ResourceTexture, type string "resource-texture", exposed to plugin authors as orca.resource_texture.ResourceTexturePluginCapabilityBase with one required method, get_texture_dir(). - The directory is resolved once on the load worker, under the GIL, and cached as a plain string: the picker runs inside the ImGui frame, where a trampoline call would block on the GIL behind a load/unload worker, or throw past EndPopup. - Validation resolves the directory and requires containment in the plugin root, re-checked per file so a symlink inside the pack cannot resolve outside it. Containment is the only security control here and it guards exfiltration: layer bytes are embedded in every saved .3mf, so a pack that could return ~/.ssh/id_rsa would leak it through any shared project. - New host registry PluginResourceTextures, filled from both the plugin and the capability lifecycle callbacks plus a startup sweep. It holds strings only and never a capability reference, so nothing outlives Py_Finalize. - The picker lists pack textures read-only, one collapsible section per pack, in a fixed-size scrolling popup whose height follows the window. A generation counter invalidates the cached listing, and each gizmo's cached thumbnails, when the set of packs changes. - Tests in tests/slic3rutils/test_plugin_resource_texture.cpp cover the validator (parent-directory and absolute escapes, an escaping symlink, the extension whitelist, the 64-file cap), the listing and its load/disable/re-enable/unload lifecycle, hostile get_texture_dir() overrides, decode parity with hand-picked files, and a .3mf round trip with the pack uninstalled. No persistence work is needed: a layer carries its own image bytes and 3MF writes them into the archive, so uninstalling a pack leaves existing projects intact. Behaviour change worth noting for review: the picker popup is now a fixed size that scrolls, rather than sizing itself to its content, and it gains one collapsible section per pack. That sizing applies to every user, not only those with packs installed.