mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-10-08 12:21:44 -04:00
Merge pull request #3670 from lightpanda-io/default-sanitizer
mem: remove allocation for default sanitizer
This commit is contained in:
2 files changed
+37
-9
No files matched your search
@@ -27,6 +27,7 @@ const Telemetry = @import("telemetry/telemetry.zig").Telemetry;
|
||||
|
||||
const Network = @import("network/Network.zig");
|
||||
const Watchdog = @import("Watchdog.zig");
|
||||
const Sanitizer = @import("browser/webapi/Sanitizer.zig");
|
||||
pub const ArenaPool = @import("ArenaPool.zig");
|
||||
|
||||
const log = lp.log;
|
||||
@@ -45,6 +46,7 @@ arena_pool: ArenaPool,
|
||||
app_dir_path: ?[]const u8,
|
||||
|
||||
regex_context: *Regex.Context,
|
||||
default_sanitizer: *Sanitizer,
|
||||
|
||||
pub fn init(allocator: Allocator, config: *const Config) !*App {
|
||||
const platform = try Platform.init(.{
|
||||
@@ -73,6 +75,7 @@ pub fn init(allocator: Allocator, config: *const Config) !*App {
|
||||
.app_dir_path = undefined,
|
||||
.telemetry = undefined,
|
||||
.arena_pool = undefined,
|
||||
.default_sanitizer = undefined,
|
||||
.watchdog = .init(config.watchdogMs()),
|
||||
};
|
||||
try app.watchdog.start();
|
||||
@@ -89,6 +92,8 @@ pub fn init(allocator: Allocator, config: *const Config) !*App {
|
||||
app.arena_pool = ArenaPool.init(allocator, .{});
|
||||
errdefer app.arena_pool.deinit();
|
||||
|
||||
app.default_sanitizer = try .initDefault(&app.arena_pool);
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
@@ -107,6 +112,7 @@ pub fn deinit(self: *App) void {
|
||||
self.regex_context.deinit();
|
||||
self.snapshot.deinit();
|
||||
self.platform.deinit();
|
||||
self.default_sanitizer.deinitDefault();
|
||||
self.arena_pool.deinit();
|
||||
|
||||
allocator.destroy(self);
|
||||
|
||||
@@ -268,6 +268,24 @@ pub fn deinit(self: *Sanitizer, _: *Page) void {
|
||||
self._owned_arena.release();
|
||||
}
|
||||
|
||||
// Every setHTML/parseHTML that doesn't pass an explicit Sanitizer gets a default
|
||||
// one. This has ~300 entries, so rather than creating it every time, we have
|
||||
// one global default Sanitizer on the app. This value is only ever used internally
|
||||
// in sanitize where it is immutable.
|
||||
pub fn initDefault(arena_pool: *lp.ArenaPool) !*Sanitizer {
|
||||
const arena = try arena_pool.acquire(.small, "Sanitizer.default");
|
||||
errdefer arena.release();
|
||||
|
||||
const self = try arena.create(Sanitizer);
|
||||
self.* = .{ ._owned_arena = arena, ._arena = arena.allocator() };
|
||||
try self.setFromDefault();
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn deinitDefault(self: *Sanitizer) void {
|
||||
self._owned_arena.release();
|
||||
}
|
||||
|
||||
pub fn acquireRef(self: *Sanitizer) void {
|
||||
self._rc.acquire();
|
||||
}
|
||||
@@ -476,8 +494,6 @@ fn own(self: *Sanitizer, value: []const u8) ![]const u8 {
|
||||
return String.intern(value) orelse self._arena.dupe(u8, value);
|
||||
}
|
||||
|
||||
// -
|
||||
|
||||
const JsName = struct {
|
||||
name: String,
|
||||
namespace: ?[]const u8,
|
||||
@@ -1023,7 +1039,7 @@ const FromOptions = struct {
|
||||
}
|
||||
};
|
||||
|
||||
fn fromOptions(options: ?Options, safe: bool, exec: *const Execution) !?FromOptions {
|
||||
fn fromOptions(options: ?Options, safe: bool, frame: *Frame) !?FromOptions {
|
||||
const spec = blk: {
|
||||
const o = options orelse break :blk null;
|
||||
const spec = o.sanitizer orelse break :blk null;
|
||||
@@ -1036,11 +1052,14 @@ fn fromOptions(options: ?Options, safe: bool, exec: *const Execution) !?FromOpti
|
||||
break :blk spec;
|
||||
};
|
||||
|
||||
if (spec == null and safe == false) {
|
||||
return null;
|
||||
if (spec == null) {
|
||||
if (safe == false) {
|
||||
return null;
|
||||
}
|
||||
// A missing spec takes the "default" preset
|
||||
return .{ .sanitizer = frame._session.browser.app.default_sanitizer, .owned = false };
|
||||
}
|
||||
// A missing spec takes the "default" preset
|
||||
return .{ .sanitizer = try create(spec, safe == false, exec), .owned = true };
|
||||
return .{ .sanitizer = try create(spec, safe == false, &frame.js.execution), .owned = true };
|
||||
}
|
||||
|
||||
pub fn setAndFilterHTML(target: *Node, context: *Element, html: []const u8, options: ?Options, safe: bool, frame: *Frame) !void {
|
||||
@@ -1051,7 +1070,7 @@ pub fn setAndFilterHTML(target: *Node, context: *Element, html: []const u8, opti
|
||||
}
|
||||
}
|
||||
|
||||
const resolved = try fromOptions(options, safe, &frame.js.execution);
|
||||
const resolved = try fromOptions(options, safe, frame);
|
||||
defer if (resolved) |r| r.release(frame.page);
|
||||
|
||||
// Parsed into a detached fragment, so that nothing is connected (no fetch,
|
||||
@@ -1067,7 +1086,7 @@ pub fn setAndFilterHTML(target: *Node, context: *Element, html: []const u8, opti
|
||||
}
|
||||
|
||||
pub fn parseHTML(html: []const u8, options: ?Options, safe: bool, frame: *Frame) !*Node.Document {
|
||||
const resolved = try fromOptions(options, safe, &frame.js.execution);
|
||||
const resolved = try fromOptions(options, safe, frame);
|
||||
defer if (resolved) |r| r.release(frame.page);
|
||||
|
||||
const document = (try Frame.parse.htmlDocument(frame, html, .{ .allow_declarative_shadow = true })).asDocument();
|
||||
@@ -1079,6 +1098,9 @@ pub fn parseHTML(html: []const u8, options: ?Options, safe: bool, frame: *Frame)
|
||||
}
|
||||
|
||||
fn sanitize(self: *const Sanitizer, root: *Node, safe: bool, frame: *Frame) !void {
|
||||
if (@TypeOf(self) != *const Sanitizer) {
|
||||
@compileError("self *must* remain const since it can reference a globally shared default sanitizer that cannot be mutated");
|
||||
}
|
||||
const arena = frame.call_arena;
|
||||
|
||||
// A template's contents and a shadow root are trees of their own
|
||||
|
||||
Reference in new issue
Block a user