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 pub(crate) fn new(data: DOMString, global: &GlobalScope, can_gc: CanGc) -> DomRoot<Self> {
38 reflect_dom_object(Box::new(Self::new_inherited(data)), global, can_gc)
39 }
40
41 pub(crate) fn get_trusted_script_compliant_string(
42 global: &GlobalScope,
43 value: TrustedScriptOrString,
44 sink: &str,
45 can_gc: CanGc,
46 ) -> Fallible<DOMString> {
47 match value {
48 TrustedScriptOrString::String(value) => {
49 TrustedTypePolicyFactory::get_trusted_type_compliant_string(
50 TrustedType::TrustedScript,
51 global,
52 value,
53 sink,
54 DEFAULT_SCRIPT_SINK_GROUP,
55 can_gc,
56 )
57 },
58
59 TrustedScriptOrString::TrustedScript(trusted_script) => Ok(trusted_script.data.clone()),
60 }
61 }
62
63 pub(crate) fn data(&self) -> &DOMString {
64 &self.data
65 }
66
67 #[allow(clippy::too_many_arguments)]
69 pub(crate) fn can_compile_string_with_trusted_type(
70 cx: JSContext,
71 global: &GlobalScope,
72 code_string: DOMString,
73 compilation_type: CompilationType,
74 parameter_strings: Vec<DOMString>,
75 body_string: DOMString,
76 parameter_args: Vec<TrustedScriptOrString>,
77 body_arg: HandleValue,
78 can_gc: CanGc,
79 ) -> bool {
80 let compilation_sink = if compilation_type == CompilationType::Function {
83 "Function"
84 } else {
85 "eval"
86 };
87 let mut is_trusted = match TrustedTypePolicyFactory::is_trusted_script(cx, body_arg) {
90 Ok(trusted_script) => {
92 body_string == trusted_script.data
94 },
95 _ => false,
96 };
97 if is_trusted {
99 assert!(parameter_args.len() == parameter_strings.len());
101 for index in 0..parameter_args.len() {
103 match ¶meter_args[index] {
105 TrustedScriptOrString::TrustedScript(trusted_script) => {
107 if parameter_strings[index] != *trusted_script.data() {
110 is_trusted = false;
111 }
112 },
113 TrustedScriptOrString::String(_) => {
115 is_trusted = false;
116 },
117 }
118 }
119 }
120 let source_string = if is_trusted {
123 code_string
127 } else {
128 match TrustedScript::get_trusted_script_compliant_string(
132 global,
133 TrustedScriptOrString::String(code_string.clone()),
134 compilation_sink,
135 can_gc,
136 ) {
137 Err(_) => {
139 return false;
140 },
141 Ok(source_string) => {
142 if source_string != code_string {
144 return false;
145 }
146 source_string
147 },
148 }
149 };
150 global
151 .get_csp_list()
152 .is_js_evaluation_allowed(global, &source_string.str())
153 }
154}
155
156impl fmt::Display for TrustedScript {
157 #[inline]
158 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
159 f.write_str(&self.data.str())
160 }
161}
162
163impl TrustedScriptMethods<crate::DomTypeHolder> for TrustedScript {
164 fn Stringifier(&self) -> DOMString {
166 self.data.clone()
167 }
168
169 fn ToJSON(&self) -> DOMString {
171 self.data.clone()
172 }
173}