Skip to content
This repository was archived by the owner on Jan 30, 2025. It is now read-only.

Commit 64c825d

Browse files
committed
Fix iframe execCtx race
The events are as follows when an iframe is attached: 1. execCtx for about:blank for new frame is set; 2. execCtx for navigated frame with url is set; 3. original about:blank execCtx is destroyed. If we only work with the original execCtx, then it will be destroyed by the 3rd event. To prevent this we overwrite the original one with the new one in the 2nd event. What this means is that we do not end up in an infinite loop when waitForExecutionContext is called.
1 parent 00eb584 commit 64c825d

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

common/frame.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -447,10 +447,31 @@ func (f *Frame) setContext(world executionWorld, execCtx frameExecutionContext)
447447
panic(err)
448448
}
449449

450+
// There is a race condition when it comes to attaching iframes and the
451+
// execution context that apply to these frames. What usually occurs is:
452+
//
453+
// 1. An exec context for about:blank is first set;
454+
// 2. A new set event is received for exec context for the url pointing
455+
// to the actual destination for the iframe;
456+
// 3. Finally the execution context for about:blank is destroyed, not
457+
// for the second execution context.
458+
//
459+
// This is the order of events when iframes are in use on a site, and
460+
// so it is safe to nil the original execution context and overwrite it
461+
// with the second one.
462+
//
463+
// The exec context destroyed event will not remove the new exec context
464+
// since the ids do not match.
465+
//
466+
// If we didn't overwrite the first execCtx with the new one, then
467+
// waitForExecutionContext could end up waiting indefinitely since all
468+
// execCtx were destroyed.
450469
if f.executionContexts[world] != nil {
451-
f.log.Debugf("Frame:setContext", "fid:%s furl:%q ectxid:%d world:%s, world exists",
470+
f.log.Debugf("Frame:setContext", "fid:%s furl:%q ectxid:%d world:%s, overriding existing world",
452471
f.ID(), f.URL(), execCtx.ID(), world)
453-
return
472+
473+
f.executionContexts[world] = nil
474+
f.documentHandle = nil
454475
}
455476

456477
f.executionContexts[world] = execCtx

0 commit comments

Comments
 (0)