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::domstring::TracedDOMString;
11use script_bindings::reflector::{Reflector, reflect_dom_object};
12
13use crate::dom::bindings::codegen::Bindings::TrustedScriptBinding::TrustedScriptMethods;
14use crate::dom::bindings::codegen::UnionTypes::TrustedScriptOrString;
15use crate::dom::bindings::error::Fallible;
16use crate::dom::bindings::root::DomRoot;
17use crate::dom::bindings::str::DOMString;
18use crate::dom::csp::CspReporting;
19use crate::dom::globalscope::GlobalScope;
20use crate::dom::trustedtypes::trustedtypepolicy::TrustedType;
21use crate::dom::trustedtypes::trustedtypepolicyfactory::{
22 DEFAULT_SCRIPT_SINK_GROUP, TrustedTypePolicyFactory,
23};
24
25#[dom_struct]
26pub struct TrustedScript {
27 reflector_: Reflector,
28
29 data: TracedDOMString,
30}
31
32impl TrustedScript {
33 fn new_inherited(data: DOMString) -> Self {
34 Self {
35 reflector_: Reflector::new(),
36 data: data.traced(),
37 }
38 }
39
40 pub(crate) fn new(cx: &mut JSContext, data: DOMString, global: &GlobalScope) -> DomRoot<Self> {
41 reflect_dom_object(cx, Box::new(Self::new_inherited(data)), global)
42 }
43
44 pub(crate) fn get_trusted_type_compliant_string(
45 cx: &mut JSContext,
46 global: &GlobalScope,
47 value: TrustedScriptOrString,
48 sink: &str,
49 ) -> Fallible<DOMString> {
50 match value {
51 TrustedScriptOrString::String(value) => {
52 TrustedTypePolicyFactory::get_trusted_type_compliant_string(
53 cx,
54 TrustedType::TrustedScript,
55 global,
56 value,
57 sink,
58 DEFAULT_SCRIPT_SINK_GROUP,
59 )
60 },
61
62 TrustedScriptOrString::TrustedScript(trusted_script) => {
63 Ok(trusted_script.data.clone().root())
64 },
65 }
66 }
67
68 pub(crate) fn data(&self) -> &TracedDOMString {
69 &self.data
70 }
71
72 #[allow(clippy::too_many_arguments)]
74 pub(crate) fn can_compile_string_with_trusted_type(
75 cx: &mut JSContext,
76 global: &GlobalScope,
77 code_string: DOMString,
78 compilation_type: CompilationType,
79 parameter_strings: Vec<DOMString>,
80 body_string: DOMString,
81 parameter_args: Vec<TrustedScriptOrString>,
82 body_arg: HandleValue,
83 ) -> bool {
84 let compilation_sink = if compilation_type == CompilationType::Function {
87 "Function"
88 } else {
89 "eval"
90 };
91 let mut is_trusted = match TrustedTypePolicyFactory::is_trusted_script(cx, body_arg) {
94 Ok(trusted_script) => {
96 *body_string == trusted_script.data
98 },
99 _ => false,
100 };
101 if is_trusted {
103 assert!(parameter_args.len() == parameter_strings.len());
105 for index in 0..parameter_args.len() {
107 match ¶meter_args[index] {
109 TrustedScriptOrString::TrustedScript(trusted_script) => {
111 if *parameter_strings[index] != *trusted_script.data() {
114 is_trusted = false;
115 }
116 },
117 TrustedScriptOrString::String(_) => {
119 is_trusted = false;
120 },
121 }
122 }
123 }
124 let source_string = if is_trusted {
127 code_string
131 } else {
132 match TrustedScript::get_trusted_type_compliant_string(
136 cx,
137 global,
138 TrustedScriptOrString::String(code_string.clone()),
139 compilation_sink,
140 ) {
141 Err(_) => {
143 return false;
144 },
145 Ok(source_string) => {
146 if source_string != code_string {
148 return false;
149 }
150 source_string
151 },
152 }
153 };
154 global
155 .get_csp_list()
156 .is_js_evaluation_allowed(cx, global, &source_string.str())
157 }
158}
159
160impl fmt::Display for TrustedScript {
161 #[inline]
162 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
163 f.write_str(&self.data.str())
164 }
165}
166
167impl TrustedScriptMethods<crate::DomTypeHolder> for TrustedScript {
168 fn Stringifier(&self) -> DOMString {
170 self.data.clone().root()
171 }
172
173 fn ToJSON(&self) -> DOMString {
175 self.data.clone().root()
176 }
177}