summaryrefslogtreecommitdiff
path: root/view
diff options
context:
space:
mode:
authorBrian Potchik <brian@vector35.com>2026-03-20 07:51:04 -0400
committerBrian Potchik <brian@vector35.com>2026-03-20 07:51:04 -0400
commit7228ba0b889765bc3474fbd5475870e24efc79ca (patch)
treed5a2f7d6f6f58f633e21a638ba9dbe10495f32df /view
parent9ca4a08fbeabc22bed721ab522cf0a7dc4484a9f (diff)
Add option to disable dedicated Universal architecture picker and use Container Browser
Add the ui.files.universal.dedicatedPicker setting, allowing users to choose between the dedicated architecture picker dialog and the standard container browser for opening Universal (fat) Mach-O binaries. Previously the dedicated picker was always used with no way to opt out. Implementing this required restructuring how Universal binaries are handled during file open. The previous approach intercepted Universal binaries during container processing, bypassing the container browser's normal pipeline with dedicated routing logic. This tightly coupled Universal-specific behavior into the container system, prevented the container browser from handling Universal binaries natively, and introduced several bugs around exclusion settings, nested containers, and multi-child container hierarchies. Bug fixes: - The previous implementation always intercepted Universal binaries during container processing with its own routing logic, bypassing the container browser entirely. There was no way for the container browser to handle Universal binaries natively, even when that was the desired behavior. - Universal binaries inside multi-child containers were not detected. The previous implementation only traversed single-child paths in the container hierarchy, silently ignoring Universal binaries that appeared as siblings among multiple children. - Nested containers (e.g., archives) inside Universal slices were not handled. The previous implementation intercepted Universal binaries at the transform routing level before the container browser could perform recursive delayering. When the dedicated picker is disabled, the container browser now processes the full hierarchy including Universal slices and any containers within them. - Reverted incorrect IsInteractive to IsUIEnabled change in UniversalTransform. The previous change conflated headless mode with non-interactive processing. The UI can be enabled while still performing a non-interactive auto-open (e.g., container browser auto-resolving with a preferred architecture). The IsInteractive() flag captures the actual intent and enables the transform to produce only the preferred architecture child for non-interactive sessions, avoiding unnecessary BinaryView construction for all slices.
Diffstat (limited to 'view')
-rw-r--r--view/macho/universaltransform.cpp9
1 files changed, 4 insertions, 5 deletions
diff --git a/view/macho/universaltransform.cpp b/view/macho/universaltransform.cpp
index 33164215..3309d853 100644
--- a/view/macho/universaltransform.cpp
+++ b/view/macho/universaltransform.cpp
@@ -266,20 +266,19 @@ bool UniversalTransform::DecodeWithContext(Ref<TransformContext> context, const
architectures.push_back(archName);
}
- // TODO: It is surprising that this is UniversalTransform's responsibility.
- if (!BinaryNinja::IsUIEnabled())
+ if (!context->IsInteractive())
{
- // When headless, filter to the preferred architecture if one is configured.
vector<string> archPref = context->GetSettings()->Get<vector<string>>("files.universal.architecturePreference");
if (auto result = find_first_of(archPref.begin(), archPref.end(), architectures.begin(), architectures.end()); result != archPref.end())
{
+ // Filter to preferred architecture to support container auto-open policy
size_t archIndex = find(architectures.begin(), architectures.end(), *result) - architectures.begin();
context->SetAvailableFiles({architectures[archIndex]});
return false;
}
- // Load the first architecture if no preference is found.
- if (archPref.empty() && architectures.size())
+ // Preserve original headless load behavior when no architecturePreference is specified
+ if (!BinaryNinja::IsUIEnabled() && archPref.empty() && architectures.size())
{
context->SetAvailableFiles({architectures[0]});
return false;