Skip to content

Commit f7f3822

Browse files
authored
Merge pull request #908 from lightpanda-io/guard_against_double_script_execution
Prevent double-execution of script tags.
2 parents 23f3bf4 + f4a6e34 commit f7f3822

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

src/browser/netsurf.zig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2885,3 +2885,15 @@ pub fn buttonGetType(button: *Button) ![]const u8 {
28852885
const s = s_ orelse return "button";
28862886
return strToData(s);
28872887
}
2888+
2889+
pub fn scriptGetProcessed(script: *Script) !bool {
2890+
var processed: bool = false;
2891+
const err = c.dom_html_script_element_get_processed(script, &processed);
2892+
try DOMErr(err);
2893+
return processed;
2894+
}
2895+
2896+
pub fn scriptSetProcessed(script: *Script, processed: bool) !void {
2897+
const err = c.dom_html_script_element_set_processed(script, processed);
2898+
try DOMErr(err);
2899+
}

src/browser/page.zig

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,12 @@ pub const Page = struct {
451451
// if no src is present, we evaluate the text source.
452452
// https://html.spec.whatwg.org/multipage/scripting.html#script-processing-model
453453
fn tryEvalScript(self: *Page, script: *const Script) !void {
454+
if (try script.alreadyProcessed()) {
455+
return;
456+
}
457+
458+
try script.markAsProcessed();
459+
454460
const html_doc = self.window.document;
455461
try parser.documentHTMLSetCurrentScript(html_doc, @ptrCast(script.element));
456462

@@ -998,6 +1004,21 @@ const Script = struct {
9981004
return null;
9991005
}
10001006

1007+
// If a script tag gets dynamically created and added to the dom:
1008+
// document.getElementsByTagName('head')[0].appendChild(script)
1009+
// that script tag will immediately get executed by our scriptAddedCallback.
1010+
// However, if the location where the script tag is inserted happens to be
1011+
// below where processHTMLDoc curently is, then we'll re-run that same script
1012+
// again in processHTMLDoc. This flag is used to let us know if a specific
1013+
// <script> has already been processed.
1014+
fn alreadyProcessed(self: *const Script) !bool {
1015+
return parser.scriptGetProcessed(@ptrCast(self.element));
1016+
}
1017+
1018+
fn markAsProcessed(self: *const Script) !void {
1019+
return parser.scriptSetProcessed(@ptrCast(self.element), true);
1020+
}
1021+
10011022
fn eval(self: *const Script, page: *Page, body: []const u8) !void {
10021023
var try_catch: Env.TryCatch = undefined;
10031024
try_catch.init(page.main_context);

0 commit comments

Comments
 (0)