mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-28 14:43:28 +00:00
Compare commits
1 Commits
55e9d8d166
...
trusted_ty
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e658b27947 |
@@ -25,6 +25,7 @@ const History = @import("history.zig").History;
|
||||
const Location = @import("location.zig").Location;
|
||||
const MediaQueryList = @import("media_query_list.zig").MediaQueryList;
|
||||
const Performance = @import("performance.zig").Performance;
|
||||
const TrustedTypes = @import("trusted_types.zig");
|
||||
|
||||
pub const Interfaces = .{
|
||||
HTMLDocument,
|
||||
@@ -38,4 +39,5 @@ pub const Interfaces = .{
|
||||
Location,
|
||||
MediaQueryList,
|
||||
Performance,
|
||||
TrustedTypes.Interfaces,
|
||||
};
|
||||
|
||||
149
src/browser/html/trusted_types.zig
Normal file
149
src/browser/html/trusted_types.zig
Normal file
@@ -0,0 +1,149 @@
|
||||
// Copyright (C) 2023-2025 Lightpanda (Selecy SAS)
|
||||
//
|
||||
// Francis Bouvier <francis@lightpanda.io>
|
||||
// Pierre Tachoire <pierre@lightpanda.io>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const Env = @import("../env.zig").Env;
|
||||
const SessionState = @import("../env.zig").SessionState;
|
||||
|
||||
const log = std.log.scoped(.trusted_types);
|
||||
|
||||
pub const Interfaces = .{
|
||||
TrustedTypePolicyFactory,
|
||||
TrustedTypePolicy,
|
||||
TrustedTypePolicyOptions,
|
||||
TrustedHTML,
|
||||
TrustedScript,
|
||||
TrustedScriptURL,
|
||||
};
|
||||
|
||||
const TrustedHTML = struct {
|
||||
value: []const u8,
|
||||
|
||||
// TODO _toJSON
|
||||
pub fn _toString(self: *const TrustedHTML) []const u8 {
|
||||
return self.value;
|
||||
}
|
||||
};
|
||||
const TrustedScript = struct {
|
||||
value: []const u8,
|
||||
|
||||
pub fn _toString(self: *const TrustedScript) []const u8 {
|
||||
return self.value;
|
||||
}
|
||||
};
|
||||
const TrustedScriptURL = struct {
|
||||
value: []const u8,
|
||||
|
||||
pub fn _toString(self: *const TrustedScriptURL) []const u8 {
|
||||
return self.value;
|
||||
}
|
||||
};
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicyFactory
|
||||
pub const TrustedTypePolicyFactory = struct {
|
||||
// TBD innerHTML if set the default createHTML should be used when `element.innerHTML = userInput;` does v8 do that for us? Prob not.
|
||||
default_policy: ?TrustedTypePolicy = null, // The default policy, set by creating a policy with the name "default".
|
||||
created_policy_names: std.ArrayListUnmanaged([]const u8) = .empty,
|
||||
|
||||
pub fn _defaultPolicy(self: *TrustedTypePolicyFactory) ?TrustedTypePolicy {
|
||||
return self.default_policy;
|
||||
}
|
||||
|
||||
// https://w3c.github.io/trusted-types/dist/spec/#dom-trustedtypepolicyfactory-createpolicy
|
||||
// https://w3c.github.io/trusted-types/dist/spec/#abstract-opdef-create-a-trusted-type-policy
|
||||
pub fn _createPolicy(self: *TrustedTypePolicyFactory, name: []const u8, options: ?TrustedTypePolicyOptions, state: *SessionState) !TrustedTypePolicy {
|
||||
// TODO Throw TypeError if policy names are restricted by the Content Security Policy trusted-types directive and this name is not on the allowlist.
|
||||
// TODO Throw TypeError if the name is a duplicate and the Content Security Policy trusted-types directive is not using allow-duplicates
|
||||
|
||||
const policy = TrustedTypePolicy{
|
||||
.name = name,
|
||||
.options = options orelse TrustedTypePolicyOptions{},
|
||||
};
|
||||
|
||||
if (std.mem.eql(u8, name, "default")) {
|
||||
// TBD what if default_policy is already set?
|
||||
self.default_policy = policy;
|
||||
}
|
||||
try self.created_policy_names.append(state.arena, try state.arena.dupe(u8, name));
|
||||
|
||||
return policy;
|
||||
}
|
||||
};
|
||||
|
||||
pub const TrustedTypePolicyOptions = struct {
|
||||
createHTML: ?Env.Function = null, // (str, ..args) -> str
|
||||
createScript: ?Env.Function = null, // (str, ..args) -> str
|
||||
createScriptURL: ?Env.Function = null, // (str, ..args) -> str
|
||||
};
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicy
|
||||
pub const TrustedTypePolicy = struct {
|
||||
name: []const u8,
|
||||
options: TrustedTypePolicyOptions,
|
||||
|
||||
pub fn get_name(self: *TrustedTypePolicy) []const u8 {
|
||||
return self.name;
|
||||
}
|
||||
|
||||
pub fn _createHTML(self: *TrustedTypePolicy, html: []const u8) !TrustedHTML {
|
||||
// TODO handle throwIfMissing
|
||||
const create = self.options.createHTML orelse return error.TypeError;
|
||||
|
||||
var result: Env.Function.Result = undefined;
|
||||
const out = try create.tryCall([]const u8, .{html}, &result); // TODO varargs
|
||||
return .{
|
||||
.value = out,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn _createScript(self: *TrustedTypePolicy, script: []const u8) !TrustedScript {
|
||||
// TODO handle throwIfMissing
|
||||
const create = self.options.createScript orelse return error.TypeError;
|
||||
|
||||
var result: Env.Function.Result = undefined;
|
||||
return try create.tryCall(TrustedScript, .{script}, &result); // TODO varargs
|
||||
}
|
||||
|
||||
pub fn _createScriptURL(self: *TrustedTypePolicy, url: []const u8) !TrustedScriptURL {
|
||||
// TODO handle throwIfMissing
|
||||
const create = self.options.createScriptURL orelse return error.TypeError;
|
||||
|
||||
var result: Env.Function.Result = undefined;
|
||||
return try create.tryCall(TrustedScriptURL, .{url}, &result); // TODO varargs
|
||||
}
|
||||
};
|
||||
|
||||
const testing = @import("../../testing.zig");
|
||||
test "Browser.TrustedTypes" {
|
||||
var runner = try testing.jsRunner(testing.tracking_allocator, .{});
|
||||
defer runner.deinit();
|
||||
|
||||
try runner.testCases(&.{
|
||||
.{ "trustedTypes", "[object TrustedTypePolicyFactory]" },
|
||||
.{
|
||||
\\ let escapeHTMLPolicy = trustedTypes.createPolicy('myEscapePolicy', {
|
||||
\\ createHTML: (string) => string.replace(/</g, "<"),
|
||||
\\ });
|
||||
,
|
||||
null,
|
||||
},
|
||||
.{ "escapeHTMLPolicy.createHTML('<img src=x onerror=alert(1)>');", "<img src=x onerror=alert(1)>" },
|
||||
}, .{});
|
||||
}
|
||||
@@ -31,6 +31,7 @@ const Console = @import("../console/console.zig").Console;
|
||||
const EventTarget = @import("../dom/event_target.zig").EventTarget;
|
||||
const MediaQueryList = @import("media_query_list.zig").MediaQueryList;
|
||||
const Performance = @import("performance.zig").Performance;
|
||||
const TrustedTypePolicyFactory = @import("trusted_types.zig").TrustedTypePolicyFactory;
|
||||
|
||||
const storage = @import("../storage/storage.zig");
|
||||
|
||||
@@ -58,6 +59,7 @@ pub const Window = struct {
|
||||
console: Console = .{},
|
||||
navigator: Navigator = .{},
|
||||
performance: Performance,
|
||||
trusted_types: TrustedTypePolicyFactory = .{},
|
||||
|
||||
pub fn create(target: ?[]const u8, navigator: ?Navigator) !Window {
|
||||
var fbs = std.io.fixedBufferStream("");
|
||||
@@ -154,6 +156,10 @@ pub const Window = struct {
|
||||
return &self.performance;
|
||||
}
|
||||
|
||||
pub fn get_trustedTypes(self: *Window) !TrustedTypePolicyFactory {
|
||||
return self.trusted_types;
|
||||
}
|
||||
|
||||
// Tells the browser you wish to perform an animation. It requests the browser to call a user-supplied callback function before the next repaint.
|
||||
// fn callback(timestamp: f64)
|
||||
// Returns the request ID, that uniquely identifies the entry in the callback list.
|
||||
|
||||
@@ -1254,7 +1254,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
|
||||
return self.tryCallWithThis(T, self.getThis(), args, result);
|
||||
}
|
||||
|
||||
pub fn tryCallWithThis(self: *const Function, comptime T: type, this: anytype, args: anytype, result: *Result) !void {
|
||||
pub fn tryCallWithThis(self: *const Function, comptime T: type, this: anytype, args: anytype, result: *Result) !T {
|
||||
var try_catch: TryCatch = undefined;
|
||||
try_catch.init(self.scope);
|
||||
defer try_catch.deinit();
|
||||
|
||||
Reference in New Issue
Block a user