script/dom/trustedtypes/
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::trustedtypes::trustedtypepolicy::TrustedType;
19use crate::dom::trustedtypes::trustedtypepolicyfactory::{
20 DEFAULT_SCRIPT_SINK_GROUP, TrustedTypePolicyFactory,
21};
22use crate::script_runtime::{CanGc, JSContext};
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(data: DOMString, global: &GlobalScope, can_gc: CanGc) -> DomRoot<Self> {
40 reflect_dom_object(Box::new(Self::new_inherited(data)), global, can_gc)
41 }
42
43 pub(crate) fn get_trusted_script_compliant_string(
44 global: &GlobalScope,
45 value: TrustedScriptOrString,
46 sink: &str,
47 can_gc: CanGc,
48 ) -> Fallible<DOMString> {
49 match value {
50 TrustedScriptOrString::String(value) => {
51 TrustedTypePolicyFactory::get_trusted_type_compliant_string(
52 TrustedType::TrustedScript,
53 global,
54 value,
55 sink,
56 DEFAULT_SCRIPT_SINK_GROUP,
57 can_gc,
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: 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 can_gc: CanGc,
81 ) -> bool {
82 let compilation_sink = if compilation_type == CompilationType::Function {
85 "Function"
86 } else {
87 "eval"
88 };
89 let mut is_trusted = match TrustedTypePolicyFactory::is_trusted_script(cx, body_arg) {
92 Ok(trusted_script) => {
94 body_string == trusted_script.data
96 },
97 _ => false,
98 };
99 if is_trusted {
101 assert!(parameter_args.len() == parameter_strings.len());
103 for index in 0..parameter_args.len() {
105 match ¶meter_args[index] {
107 TrustedScriptOrString::TrustedScript(trusted_script) => {
109 if parameter_strings[index] != *trusted_script.data() {
112 is_trusted = false;
113 }
114 },
115 TrustedScriptOrString::String(_) => {
117 is_trusted = false;
118 },
119 }
120 }
121 }
122 let source_string = if is_trusted {
125 code_string
129 } else {
130 match TrustedScript::get_trusted_script_compliant_string(
134 global,
135 TrustedScriptOrString::String(code_string.clone()),
136 compilation_sink,
137 can_gc,
138 ) {
139 Err(_) => {
141 return false;
142 },
143 Ok(source_string) => {
144 if source_string != code_string {
146 return false;
147 }
148 source_string
149 },
150 }
151 };
152 global
153 .get_csp_list()
154 .is_js_evaluation_allowed(global, &source_string.str())
155 }
156}
157
158impl fmt::Display for TrustedScript {
159 #[inline]
160 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
161 f.write_str(&self.data.str())
162 }
163}
164
165impl TrustedScriptMethods<crate::DomTypeHolder> for TrustedScript {
166 fn Stringifier(&self) -> DOMString {
168 self.data.clone()
169 }
170
171 fn ToJSON(&self) -> DOMString {
173 self.data.clone()
174 }
175}