script/dom/
trustedscript.rs1use std::fmt;
5
6use dom_struct::dom_struct;
7use js::jsapi::CompilationType;
8use js::rust::HandleValue;
9
10use crate::dom::bindings::codegen::Bindings::TrustedScriptBinding::TrustedScriptMethods;
11use crate::dom::bindings::codegen::UnionTypes::TrustedScriptOrString;
12use crate::dom::bindings::error::Fallible;
13use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
14use crate::dom::bindings::root::DomRoot;
15use crate::dom::bindings::str::DOMString;
16use crate::dom::csp::CspReporting;
17use crate::dom::globalscope::GlobalScope;
18use crate::dom::trustedtypepolicy::TrustedType;
19use crate::dom::trustedtypepolicyfactory::{DEFAULT_SCRIPT_SINK_GROUP, TrustedTypePolicyFactory};
20use crate::script_runtime::{CanGc, JSContext};
21
22#[dom_struct]
23pub struct TrustedScript {
24 reflector_: Reflector,
25
26 data: DOMString,
27}
28
29impl TrustedScript {
30 fn new_inherited(data: DOMString) -> Self {
31 Self {
32 reflector_: Reflector::new(),
33 data,
34 }
35 }
36
37 #[cfg_attr(crown, allow(crown::unrooted_must_root))]
38 pub(crate) fn new(data: DOMString, global: &GlobalScope, can_gc: CanGc) -> DomRoot<Self> {
39 reflect_dom_object(Box::new(Self::new_inherited(data)), global, can_gc)
40 }
41
42 pub(crate) fn get_trusted_script_compliant_string(
43 global: &GlobalScope,
44 value: TrustedScriptOrString,
45 sink: &str,
46 can_gc: CanGc,
47 ) -> Fallible<DOMString> {
48 match value {
49 TrustedScriptOrString::String(value) => {
50 TrustedTypePolicyFactory::get_trusted_type_compliant_string(
51 TrustedType::TrustedScript,
52 global,
53 value,
54 sink,
55 DEFAULT_SCRIPT_SINK_GROUP,
56 can_gc,
57 )
58 },
59
60 TrustedScriptOrString::TrustedScript(trusted_script) => Ok(trusted_script.data.clone()),
61 }
62 }
63
64 pub(crate) fn data(&self) -> DOMString {
65 self.data.clone()
66 }
67
68 #[allow(clippy::too_many_arguments)]
70 pub(crate) fn can_compile_string_with_trusted_type(
71 cx: JSContext,
72 global: &GlobalScope,
73 code_string: DOMString,
74 compilation_type: CompilationType,
75 parameter_strings: Vec<DOMString>,
76 body_string: DOMString,
77 parameter_args: Vec<TrustedScriptOrString>,
78 body_arg: HandleValue,
79 can_gc: CanGc,
80 ) -> bool {
81 let compilation_sink = if compilation_type == CompilationType::Function {
84 "Function"
85 } else {
86 "eval"
87 };
88 let mut is_trusted = match TrustedTypePolicyFactory::is_trusted_script(cx, body_arg) {
91 Ok(trusted_script) => {
93 body_string == trusted_script.data
95 },
96 _ => false,
97 };
98 if is_trusted {
100 assert!(parameter_args.len() == parameter_strings.len());
102 for index in 0..parameter_args.len() {
104 match ¶meter_args[index] {
106 TrustedScriptOrString::TrustedScript(trusted_script) => {
108 if parameter_strings[index] != trusted_script.data() {
111 is_trusted = false;
112 }
113 },
114 TrustedScriptOrString::String(_) => {
116 is_trusted = false;
117 },
118 }
119 }
120 }
121 let source_string = if is_trusted {
124 code_string
128 } else {
129 match TrustedScript::get_trusted_script_compliant_string(
133 global,
134 TrustedScriptOrString::String(code_string.clone()),
135 compilation_sink,
136 can_gc,
137 ) {
138 Err(_) => {
140 return false;
141 },
142 Ok(source_string) => {
143 if source_string != code_string {
145 return false;
146 }
147 source_string
148 },
149 }
150 };
151 global
152 .get_csp_list()
153 .is_js_evaluation_allowed(global, &source_string)
154 }
155}
156
157impl fmt::Display for TrustedScript {
158 #[inline]
159 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
160 f.write_str(&self.data)
161 }
162}
163
164impl TrustedScriptMethods<crate::DomTypeHolder> for TrustedScript {
165 fn Stringifier(&self) -> DOMString {
167 self.data.clone()
168 }
169
170 fn ToJSON(&self) -> DOMString {
172 self.data.clone()
173 }
174}