script/dom/trustedtypes/
trustedscript.rs1use std::fmt;
5
6use dom_struct::dom_struct;
7use js::context::JSContext;
8use js::jsapi::CompilationType;
9use js::rust::HandleValue;
10use script_bindings::reflector::{Reflector, reflect_dom_object_with_cx};
11
12use crate::dom::bindings::codegen::Bindings::TrustedScriptBinding::TrustedScriptMethods;
13use crate::dom::bindings::codegen::UnionTypes::TrustedScriptOrString;
14use crate::dom::bindings::error::Fallible;
15use crate::dom::bindings::root::DomRoot;
16use crate::dom::bindings::str::DOMString;
17use crate::dom::csp::CspReporting;
18use crate::dom::globalscope::GlobalScope;
19use crate::dom::trustedtypes::trustedtypepolicy::TrustedType;
20use crate::dom::trustedtypes::trustedtypepolicyfactory::{
21 DEFAULT_SCRIPT_SINK_GROUP, TrustedTypePolicyFactory,
22};
23
24#[dom_struct]
25pub struct TrustedScript {
26 reflector_: Reflector,
27
28 data: DOMString,
29}
30
31impl TrustedScript {
32 fn new_inherited(data: DOMString) -> Self {
33 Self {
34 reflector_: Reflector::new(),
35 data,
36 }
37 }
38
39 pub(crate) fn new(cx: &mut JSContext, data: DOMString, global: &GlobalScope) -> DomRoot<Self> {
40 reflect_dom_object_with_cx(Box::new(Self::new_inherited(data)), global, cx)
41 }
42
43 pub(crate) fn get_trusted_type_compliant_string(
44 cx: &mut JSContext,
45 global: &GlobalScope,
46 value: TrustedScriptOrString,
47 sink: &str,
48 ) -> Fallible<DOMString> {
49 match value {
50 TrustedScriptOrString::String(value) => {
51 TrustedTypePolicyFactory::get_trusted_type_compliant_string(
52 cx,
53 TrustedType::TrustedScript,
54 global,
55 value,
56 sink,
57 DEFAULT_SCRIPT_SINK_GROUP,
58 )
59 },
60
61 TrustedScriptOrString::TrustedScript(trusted_script) => Ok(trusted_script.data.clone()),
62 }
63 }
64
65 pub(crate) fn data(&self) -> &DOMString {
66 &self.data
67 }
68
69 #[allow(clippy::too_many_arguments)]
71 pub(crate) fn can_compile_string_with_trusted_type(
72 cx: &mut JSContext,
73 global: &GlobalScope,
74 code_string: DOMString,
75 compilation_type: CompilationType,
76 parameter_strings: Vec<DOMString>,
77 body_string: DOMString,
78 parameter_args: Vec<TrustedScriptOrString>,
79 body_arg: HandleValue,
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_type_compliant_string(
133 cx,
134 global,
135 TrustedScriptOrString::String(code_string.clone()),
136 compilation_sink,
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(cx, global, &source_string.str())
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.str())
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}