You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Objective: To create a detailed and reliable record of critical system actions for security analysis and compliance.
Status: No audit logging: The refactored subscription flow does not add any logging/audit metadata, so it is not verifiable from the diff whether critical actions (if any) are captured with required context (user, timestamp, outcome).
Generic: Security-First Input Validation and Data Handling
Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent vulnerabilities
Status: Missing input validation: The new SubscribeAsync overloads do not validate potentially caller-provided inputs such as eventName and jsonTypeInfo, so it is unclear from the diff whether invalid/malicious values are prevented upstream.
The PR adds many nearly identical private handler methods, causing significant code duplication. Refactor this by using a single generic private method to handle context filtering for all events, which would be more maintainable.
// In dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContext.cspublicTask<Subscription>OnNavigationStartedAsync(Action<NavigationInfo>handler, ...){if(handlerisnull)thrownewArgumentNullException(nameof(handler));returnBiDi.BrowsingContext.OnNavigationStartedAsync(
e =>HandleNavigationStarted(e,handler), ...);}privatevoidHandleNavigationStarted(NavigationInfoe,Action<NavigationInfo>handler){if(Equals(e.Context)){handler(e);}}// ... dozens of similar handler methods for different events ...privatevoidHandleFragmentNavigated(NavigationInfoe,Action<NavigationInfo>handler){if(Equals(e.Context)){handler(e);}}
After:
// In a new helper class or within each moduleprivatestaticAction<T>CreateContextFilteredHandler<T>(Te,Action<T>handler,BrowsingContextcontext)whereT:IContextEventArgs{return(args)=>{if(context.Equals(args.Context)){handler(args);}};}// In dotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContext.cspublicTask<Subscription>OnNavigationStartedAsync(Action<NavigationInfo>handler, ...){if(handlerisnull)thrownewArgumentNullException(nameof(handler));returnBiDi.BrowsingContext.OnNavigationStartedAsync(CreateContextFilteredHandler(handler,this), ...);}
Suggestion importance[1-10]: 9
__
Why: The suggestion correctly identifies massive code duplication introduced across multiple files, which contradicts the PR's goal of improving maintainability and is a significant design flaw.
High
Possible issue
Restore special handling for subscription options
Restore the special handling for OnEntryAddedAsync subscription options, which was removed during refactoring, to avoid unintended context scoping due to a known spec issue.
public Task<Subscription> OnEntryAddedAsync(Func<Log.LogEntry, Task> handler, ContextSubscriptionOptions? options = null)
{
if (handler is null) throw new ArgumentNullException(nameof(handler));
return logModule.OnEntryAddedAsync(
e => HandleEntryAddedAsync(e, handler),
- ContextSubscriptionOptions.WithContext(options, context));+ new SubscriptionOptions() { Timeout = options?.Timeout }); // special case, don't scope to context, awaiting https://github.com/w3c/webdriver-bidi/issues/1032
}
public Task<Subscription> OnEntryAddedAsync(Action<Log.LogEntry> handler, ContextSubscriptionOptions? options = null)
{
if (handler is null) throw new ArgumentNullException(nameof(handler));
return logModule.OnEntryAddedAsync(
e => HandleEntryAdded(e, handler),
- ContextSubscriptionOptions.WithContext(options, context));+ new SubscriptionOptions() { Timeout = options?.Timeout }); // special case, don't scope to context, awaiting https://github.com/w3c/webdriver-bidi/issues/1032
}
Apply / Chat
Suggestion importance[1-10]: 8
__
Why: The suggestion correctly identifies that the refactoring removed special-case logic for OnEntryAddedAsync that was intentionally added to work around a spec issue, which could be a significant regression.
Medium
General
Guard against null type info
Add a null check for the jsonTypeInfo parameter in SubscribeAsync to prevent potential exceptions.
+if (jsonTypeInfo is null)+ throw new ArgumentNullException(nameof(jsonTypeInfo), "Event JSON type info cannot be null.");
_eventTypesMap[eventName] = jsonTypeInfo;
Apply / Chat
Suggestion importance[1-10]: 7
__
Why: The suggestion correctly points out a missing null check for the jsonTypeInfo parameter, which improves the method's robustness by preventing potential null reference exceptions.
Medium
Learned best practice
Centralize repeated handler logic
Replace the many per-event HandleXxx methods with 1–2 generic helpers that apply the context filter and invoke the provided handler to keep behavior single-sourced.
-private async Task HandleNavigationStartedAsync(NavigationInfo e, Func<NavigationInfo, Task> handler)+private Task InvokeIfThisContextAsync<T>(T e, Func<T, Task> handler, Func<T, BrowsingContext> getContext)
{
- if (Equals(e.Context))- {- await handler(e).ConfigureAwait(false);- }+ return Equals(getContext(e)) ? handler(e) : Task.CompletedTask;
}
-private void HandleNavigationStarted(NavigationInfo e, Action<NavigationInfo> handler)+private void InvokeIfThisContext<T>(T e, Action<T> handler, Func<T, BrowsingContext> getContext)
{
- if (Equals(e.Context))+ if (Equals(getContext(e)))
{
handler(e);
}
}
-private async Task HandleFragmentNavigatedAsync(NavigationInfo e, Func<NavigationInfo, Task> handler)-{- if (Equals(e.Context))- {- await handler(e).ConfigureAwait(false);- }-}+private Task HandleNavigationStartedAsync(NavigationInfo e, Func<NavigationInfo, Task> handler) =>+ InvokeIfThisContextAsync(e, handler, x => x.Context);-private void HandleFragmentNavigated(NavigationInfo e, Action<NavigationInfo> handler)-{- if (Equals(e.Context))- {- handler(e);- }-}+private void HandleNavigationStarted(NavigationInfo e, Action<NavigationInfo> handler) =>+ InvokeIfThisContext(e, handler, x => x.Context);+private Task HandleFragmentNavigatedAsync(NavigationInfo e, Func<NavigationInfo, Task> handler) =>+ InvokeIfThisContextAsync(e, handler, x => x.Context);++private void HandleFragmentNavigated(NavigationInfo e, Action<NavigationInfo> handler) =>+ InvokeIfThisContext(e, handler, x => x.Context);+
Apply / Chat
Suggestion importance[1-10]: 6
__
Why:
Relevant best practice - Reduce duplication by centralizing shared behavior (use helpers for repeated context-filter + invoke logic instead of many near-identical methods).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
User description
💥 What does this PR do?
Fail fast with
NullArgumentExceptionif provided event handler isnull.🔧 Implementation Notes
Also translated inline lambda expression to private method for better stacktrace.
🔄 Types of changes
PR Type
Enhancement, Tests
Description
Add null guard checks for event handlers with ArgumentNullException
Extract inline lambda expressions to private named methods for better stacktraces
Refactor Broker.SubscribeAsync to consolidate duplicate logic
Improve code maintainability across BiDi event subscription modules
Diagram Walkthrough
File Walkthrough
Broker.cs
Consolidate SubscribeAsync implementationsdotnet/src/webdriver/BiDi/Broker.cs
handlers
method
BrowsingContext.cs
Extract event handlers to private methods with null guardsdotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContext.cs
BrowsingContextInputModule.cs
Add null guards and extract input module handlersdotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextInputModule.cs
HandleFileDialogOpened methods
BrowsingContextLogModule.cs
Add null guards and extract log module handlersdotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextLogModule.cs
methods
ContextSubscriptionOptions.WithContext
BrowsingContextNetworkModule.cs
Add null guards and extract network module handlersdotnet/src/webdriver/BiDi/BrowsingContext/BrowsingContextNetworkModule.cs
methods
EventHandler.cs
Add null guards to EventHandler constructorsdotnet/src/webdriver/BiDi/EventHandler.cs
parameter
parameter
handlers