(local, name, wrapper, events, returnAsValue)
| 172 | } |
| 173 | |
| 174 | function proxyDescribe(local, name, wrapper, events, returnAsValue) { |
| 175 | let known; |
| 176 | let desc = (known = globalDesc[name]) || updateGlobalDesc(name); |
| 177 | if (!desc) return; |
| 178 | let { get, set, value } = desc; |
| 179 | const isChild = !known && isChildWindowKey(name); |
| 180 | const isWindow = value === window |
| 181 | || name === 'window' |
| 182 | || name === 'self' |
| 183 | || name === 'globalThis' |
| 184 | || name === 'top' && window === top // `top` is unforgeable |
| 185 | || name === 'parent' && window === window::getWindowParent(); |
| 186 | if (isWindow) { |
| 187 | value = desc.value = wrapper; |
| 188 | get = false; |
| 189 | delete desc.get; |
| 190 | delete desc.set; |
| 191 | } else if (get && set && isString(name) |
| 192 | // Spoofed String index getters won't be called within length, length itself is unforgeable |
| 193 | && name.length >= 3 && name[0] === 'o' && name[1] === 'n' |
| 194 | ) { |
| 195 | setWindowEvent(desc, name, events, wrapper); |
| 196 | } else { |
| 197 | if (get) desc.get = safeBind(get, window); |
| 198 | if (set) desc.set = safeBind(set, window); |
| 199 | if (value && name === kConsole) desc.value = value = safeCopy(value); |
| 200 | } |
| 201 | if (!isChild) { |
| 202 | defineProperty(local, name, desc); /* proto is null */// eslint-disable-line no-restricted-syntax |
| 203 | } |
| 204 | return !returnAsValue ? desc |
| 205 | : !get ? value |
| 206 | : isChild ? global[name] |
| 207 | : local[name]; |
| 208 | } |
| 209 | |
| 210 | function setWindowEvent(desc, name, events, wrapper) { |
| 211 | name = name::slice(2); |
no test coverage detected