Skip to content

Allow JavaScript binding when browser wrapper cannot be found#5229

Open
campersau wants to merge 3 commits intocefsharp:masterfrom
campersau:IsJavascriptBindingApiAllowed
Open

Allow JavaScript binding when browser wrapper cannot be found#5229
campersau wants to merge 3 commits intocefsharp:masterfrom
campersau:IsJavascriptBindingApiAllowed

Conversation

@campersau
Copy link
Copy Markdown
Contributor

@campersau campersau commented Mar 31, 2026

Fixes: #5228

Summary: Fixes regression to allow JavaScript bindings when browser wrapper can not be found.

Changes:

  • Moved all checks to IsJavascriptBindingApiAllowed to determine whether JavaScript bindings are enabled.

How Has This Been Tested?
Manually.
My App works again with this build: https://ci.appveyor.com/project/campersau/cefsharp/builds/53796822/artifacts

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Updated documentation

Checklist:

  • Tested the code(if applicable)
  • Commented my code
  • Changed the documentation(if applicable)
  • New files have a license disclaimer
  • The formatting is consistent with the project (project supports .editorconfig)

Summary by CodeRabbit

  • Refactor
    • Consolidated per-browser JavaScript binding configuration and centralized authorization checks for the JavaScript binding API, improving reliability of origin/allowlist handling. This restructures internal storage and lookup of binding settings to reduce race conditions and make allowlist enforcement more consistent, without changing user-facing behavior.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 31, 2026

📝 Walkthrough

Walkthrough

Moved per-browser JavaScript binding configuration out of CefBrowserWrapper into a new JavascriptBindingSettings type stored in _browserJavascriptBindingSettings. OnBrowserCreated creates and stores settings by browser id; OnContextCreated and IsJavascriptBindingApiAllowed read from that settings object; wrappers are removed on destroy but settings retained.

Changes

Cohort / File(s) Summary
Core wrapper logic
CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.cpp, CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.h
Add _browserJavascriptBindingSettings dictionary; OnBrowserCreated builds per-browser JavascriptBindingSettings and stores by browser id; OnContextCreated looks up settings (no longer fetching CefBrowserWrapper) and uses new IsJavascriptBindingApiAllowed(JavascriptBindingSettings^, CefRefPtr<CefFrame>) signature; remove wrapper on destroy but leave settings.
Per-browser settings type
CefSharp.BrowserSubprocess.Core/JavascriptBindingSettings.h
Add new managed JavascriptBindingSettings ref class with properties JavascriptBindingApiEnabled, JavascriptBindingApiHasAllowOrigins, and JavascriptBindingApiAllowOrigins; ctor/finalizer/destructor manage lifecycle of internal CefListValue reference.
Browser wrapper simplification
CefSharp.BrowserSubprocess.Core/CefBrowserWrapper.h
Remove JavaScript-binding-related fields and properties (JavascriptBindingApiEnabled, JavascriptBindingApiHasAllowOrigins, JavascriptBindingApiAllowOrigins); CefBrowserWrapper no longer holds binding allow-origins state.
Project files
CefSharp.BrowserSubprocess.Core/CefSharp.BrowserSubprocess.Core.vcxproj, CefSharp.BrowserSubprocess.Core/CefSharp.BrowserSubprocess.Core.netcore.vcxproj
Add JavascriptBindingSettings.h to <ClInclude> so the new header is compiled/included.

Sequence Diagram(s)

sequenceDiagram
    participant Browser as Browser (CefBrowser)
    participant Subproc as CefAppUnmanagedWrapper
    participant Store as _browserJavascriptBindingSettings
    participant Frame as Frame (CefFrame)

    Browser->>Subproc: OnBrowserCreated(browser)
    Subproc->>Store: create & store JavascriptBindingSettings[browserId]
    Subproc->>Subproc: _browserWrappers->TryAdd(browserId, wrapper)

    Frame->>Subproc: OnContextCreated(frame, browserId)
    Subproc->>Store: lookup JavascriptBindingSettings[browserId]
    Subproc->>Subproc: IsJavascriptBindingApiAllowed(settings, frame)
    alt allowed
        Subproc->>Frame: inject CefSharp JS binding
    else not allowed
        Subproc->>Frame: skip injection
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐇 I hopped through code with a twitch and a grin,
I carried settings tied to each browser within.
When contexts awaken I quietly peep,
I check origins and decide if I'll leap.
Little bindings hum — now all sleeps sound and thin.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main objective of the PR: fixing a regression that prevents JavaScript bindings when the browser wrapper cannot be found.
Description check ✅ Passed The PR description follows the template structure with Fixes, Summary, Changes, Testing method, and checklist items completed. All required sections are present and adequately filled.
Linked Issues check ✅ Passed The PR addresses the core issue #5228 by refactoring JavaScript binding checks into IsJavascriptBindingApiAllowed, eliminating the dependency on finding the BrowserWrapper and allowing bindings in iframe scenarios.
Out of Scope Changes check ✅ Passed All changes are scoped to implementing the JavaScript binding fix: new JavascriptBindingSettings class, removal of binding properties from CefBrowserWrapper, and refactoring of binding checks. No unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.cpp`:
- Around line 352-363: IsJavascriptBindingApiAllowed currently returns true when
browserWrapper is null, bypassing per-browser enforcement; change the
null-wrapper path in IsJavascriptBindingApiAllowed to treat a missing
browserWrapper as not allowed (return false) so that JavascriptBindingApiEnabled
and JavascriptBindingApiHasAllowOrigins checks are enforced, and add unit tests
that simulate a missing browserWrapper where (1) JavascriptBindingApiEnabled is
false and (2) JavascriptBindingApiHasAllowOrigins is true to verify bindings are
not injected when the wrapper lookup fails.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2b1d8844-dad5-4b5d-ab77-aff326ee7e6b

📥 Commits

Reviewing files that changed from the base of the PR and between 24e7df2 and eb57fa2.

📒 Files selected for processing (1)
  • CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.cpp

@AppVeyorBot
Copy link
Copy Markdown

Copy link
Copy Markdown
Member

@amaitland amaitland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR.

As a short term workaround this is probably ok, though I'd like to resolve this in a different way.

This avoids the issue that sometimes browsers are destroyed but then referenced again without them beeing created
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.h`:
- Around line 76-83: The cleanup loop is iterating the ConcurrentDictionary
directly with OfType<JavascriptBindingSettings^> which yields nothing; update
the block that checks _browserJavascriptBindingSettings to iterate its values
(e.g., use _browserJavascriptBindingSettings->Values or iterate KeyValuePair and
use kvp.Value) and delete each JavascriptBindingSettings instance
(JavascriptBindingSettings^) before setting _browserJavascriptBindingSettings =
nullptr; keep the existing null check and ensure you delete the value objects
rather than the pairs.

In `@CefSharp.BrowserSubprocess.Core/JavascriptBindingSettings.h`:
- Around line 21-25: The subprocess constructor JavascriptBindingSettings()
currently sets JavascriptBindingApiEnabled = true which contradicts the
documented default (false) and causes unintended injection; change the
constructor to set JavascriptBindingApiEnabled = false (keep the existing
initializations for JavascriptBindingApiHasAllowOrigins and
JavascriptBindingApiAllowOrigins intact) so the subprocess default matches
CefSharp/JavascriptBinding/JavascriptBindingSettings.cs and
IsJavascriptBindingApiAllowed behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bfe720d1-0267-4703-bec5-1c4c33f091c1

📥 Commits

Reviewing files that changed from the base of the PR and between eb57fa2 and 0e09797.

📒 Files selected for processing (6)
  • CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.cpp
  • CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.h
  • CefSharp.BrowserSubprocess.Core/CefBrowserWrapper.h
  • CefSharp.BrowserSubprocess.Core/CefSharp.BrowserSubprocess.Core.netcore.vcxproj
  • CefSharp.BrowserSubprocess.Core/CefSharp.BrowserSubprocess.Core.vcxproj
  • CefSharp.BrowserSubprocess.Core/JavascriptBindingSettings.h
💤 Files with no reviewable changes (1)
  • CefSharp.BrowserSubprocess.Core/CefBrowserWrapper.h
✅ Files skipped from review due to trivial changes (2)
  • CefSharp.BrowserSubprocess.Core/CefSharp.BrowserSubprocess.Core.vcxproj
  • CefSharp.BrowserSubprocess.Core/CefSharp.BrowserSubprocess.Core.netcore.vcxproj

@AppVeyorBot
Copy link
Copy Markdown

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.h (1)

30-54: ⚠️ Potential issue | 🔴 Critical

Add per-browser cleanup for _browserJavascriptBindingSettings in OnBrowserDestroyed.

_browserJavascriptBindingSettings entries are added when browsers are created but never removed when destroyed. Currently, cleanup only occurs at process teardown (destructor). In long-lived subprocesses with multiple browser creations/destructions, this causes unbounded accumulation of stale per-browser settings. Add a TryRemove call in OnBrowserDestroyed to clean up the entry for the destroyed browser ID, matching the pattern already used for _browserWrappers.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.h` around lines 30 -
54, OnBrowserDestroyed currently removes entries from _browserWrappers but does
not remove the per-browser settings in _browserJavascriptBindingSettings,
causing leaks; modify OnBrowserDestroyed to call TryRemove on
_browserJavascriptBindingSettings using the same browser id (the key used with
_browserWrappers) to remove the destroyed browser's JavascriptBindingSettings
entry (mirror the existing removal pattern for _browserWrappers and ensure any
associated resources are released).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.h`:
- Around line 30-54: OnBrowserDestroyed currently removes entries from
_browserWrappers but does not remove the per-browser settings in
_browserJavascriptBindingSettings, causing leaks; modify OnBrowserDestroyed to
call TryRemove on _browserJavascriptBindingSettings using the same browser id
(the key used with _browserWrappers) to remove the destroyed browser's
JavascriptBindingSettings entry (mirror the existing removal pattern for
_browserWrappers and ensure any associated resources are released).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a472c299-1812-48fa-b0e4-3ae109c6e717

📥 Commits

Reviewing files that changed from the base of the PR and between 0e09797 and 9687d6c.

📒 Files selected for processing (1)
  • CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.h

@AppVeyorBot
Copy link
Copy Markdown

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.

4 participants