Repository navigation
[core] Fix plugin lookup when Root.PluginPath has multiple directories - #23796
JainAyush-01 wants to merge 1 commit into
Conversation
When Root.PluginPath (or ROOT_PLUGIN_PATH) contains multiple colon-separated directories, TPluginManager::LoadHandlersFromPluginDirs loops over each directory to load handler macros for the requested base class. In commit e60640c (root-project#18859), ConcatFileName was replaced by PrependPathName. Unlike ConcatFileName which returned a new heap-allocated string, PrependPathName modifies its second parameter in-place. Because `sbase` was passed directly: const char *p = gSystem->PrependPathName(d, sbase); the variable `sbase` was mutated in-place across iterations (e.g., from "TArchiveFile" to "/dir1/TArchiveFile", then to "/dir2//dir1/TArchiveFile"). Consequently, subsequent search directories received a mangled path and ROOT could not find its own built-in plugins whenever a custom plugin directory was prepended. Fix this by copying `sbase` to a temporary `TString temp = sbase;` on each iteration, matching the pattern used in the rest of TPluginManager.cxx. Fixes root-project#23536. Added regression test in core/base/test/TPluginManagerTests.cxx.
|
Did you have a look to https://github.com/root-project/root/blob/master/CONTRIBUTING.md#ai-assisted-coding-disclosure ? |
|
Hi @dpiparo, Thank you for pointing this out. I apologize, I missed the AI disclosure section in CONTRIBUTING.md. I have updated the description here (and on #23791) with the disclosure. I used an LLM to help explore the codebase and structure the test, but I made sure to verify the bug and C++ logic locally, sbase was passed by non const reference TString and inside the vpaths loop, so sbase.Prepend(...) was repeatedly accumulating previous path segments instead of evaluating each search path independently. Going forward, I will make sure all tool usage is properly disclosed according to the guidelines |
|
Thanks for you contribution. The test has been fixed and the PR has been extended as part of #23928 |
This Pull request:
Fixes an in-place string mutation bug in
TPluginManager::LoadHandlersFromPluginDirsthat breaks plugin discovery whenRoot.PluginPath(orROOT_PLUGIN_PATH) contains multiple colon-separated directories.Changes or fixes:
Root Cause:
In commit e60640c (#18859),
gSystem->ConcatFileNamewas replaced withgSystem->PrependPathName. UnlikeConcatFileNamewhich returned a new heap-allocated string without modifying the input,PrependPathName(const char *dir, TString &name)modifiesnamein place.In
TPluginManager::LoadHandlersFromPluginDirs(const char *base):Because
sbasewas passed directly toPrependPathNamewithout copying to a temporary variable:dir0 = "/custom/plugins"):sbasewas mutated from"TArchiveFile"to"/custom/plugins/TArchiveFile".dir1 = "$ROOTSYS/etc/plugins"):PrependPathNameprependeddir1to the already mutatedsbase, resulting in"$ROOTSYS/etc/plugins//custom/plugins/TArchiveFile".As a result, whenever a user or experiment environment (e.g. ALICE O2 / JAliEn) prepended a custom directory to
Root.PluginPath, all subsequent directories—including ROOT's own built-in plugins in$ROOTSYS/etc/plugins—failed to load.Fix:
Copy
sbaseto a temporaryTString temp = sbase;inside the loop before callingPrependPathName(d, temp), matching the pattern already used in theelsebranch (lines 545–546) and throughoutTPluginManager.cxx.Testing:
TEST(TPluginManager, MultiDirectoryPluginPath)incore/base/test/TPluginManagerTests.cxx.ctest -R CorePluginManagerTests: 100% passed (0.26s).Checklist:
This PR fixes #23536
AI-assisted coding disclosure: I used an AI assistant to help navigate the codebase, structure the unit test, and format this PR description. I have personally reviewed, debugged, and tested the C++ changes locally and take full responsibility for them.