冻结运行环境内置的对象

This commit is contained in:
lyswhut 2023-11-05 14:36:57 +08:00
parent 44a3a37e0d
commit 1c99f40248

View File

@ -1,3 +1,4 @@
'use strict'
globalThis.lx_setup = (key, id, name, description, rawScript) => {
delete globalThis.setup
@ -37,7 +38,7 @@ globalThis.lx_setup = (key, id, name, description, rawScript) => {
const callbacks = new Map()
let timeoutId = 0
const setTimeout = (callback, timeout = 0, ...params) => {
const _setTimeout = (callback, timeout = 0, ...params) => {
if (typeof timeout !== 'number' || timeout < 0) throw new Error('timeout required number')
if (timeoutId > 90000000000) throw new Error('max timeout')
const id = timeoutId++
@ -48,7 +49,7 @@ globalThis.lx_setup = (key, id, name, description, rawScript) => {
set_timeout(id, parseInt(timeout))
return id
}
const clearTimeout = (id) => {
const _clearTimeout = (id) => {
const tagret = callbacks.get(id)
if (!tagret) return
callbacks.delete(id)
@ -113,11 +114,11 @@ globalThis.lx_setup = (key, id, name, description, rawScript) => {
// 'utils.zlib.inflate': 'utils.zlib.inflate',
// 'utils.zlib.deflate': 'utils.zlib.deflate',
}
const EVENT_NAMES = Object.freeze({
const EVENT_NAMES = {
request: 'request',
inited: 'inited',
updateAlert: 'updateAlert',
})
}
const eventNames = Object.values(EVENT_NAMES)
const events = {
request: null,
@ -299,7 +300,7 @@ globalThis.lx_setup = (key, id, name, description, rawScript) => {
else if (Array.isArray(data) || ArrayBuffer.isView(data)) return utils.buffer.bufToString(data, 'base64')
throw new Error('data type error: ' + typeof data + ' raw data: ' + data)
}
const utils = Object.freeze({
const utils = {
crypto: {
aesEncrypt(buffer, mode, key, iv) {
// console.log('aesEncrypt', buffer, mode, key, iv)
@ -391,12 +392,10 @@ globalThis.lx_setup = (key, id, name, description, rawScript) => {
// })
// })
// },
// },
})
Object.defineProperty(globalThis, 'lx', {
configurable: false,
writable: false,
value: Object.freeze({
// }),
}
globalThis.lx = {
EVENT_NAMES,
request(url, { method = 'get', timeout, headers, body, form, formData, binary }, callback) {
let options = { headers, binary: binary === true }
@ -461,35 +460,18 @@ globalThis.lx_setup = (key, id, name, description, rawScript) => {
return Promise.resolve()
},
utils,
currentScriptInfo: Object.freeze({
currentScriptInfo: {
name,
description,
}),
},
version: '1.0.0',
env: 'mobile',
}),
})
}
Object.defineProperty(globalThis, 'setTimeout', {
configurable: false,
writable: false,
value: setTimeout,
})
Object.defineProperty(globalThis, 'clearTimeout', {
configurable: false,
writable: false,
value: clearTimeout,
})
Object.defineProperty(globalThis, 'window', {
configurable: false,
writable: false,
value: globalThis,
})
Object.defineProperty(globalThis, 'document', {
configurable: false,
writable: false,
value: Object.freeze({
globalThis.setTimeout = _setTimeout
globalThis.clearTimeout = _clearTimeout
globalThis.window = globalThis
globalThis.document = {
getElementsByTagName(name) {
if (name == 'script') {
return [
@ -500,8 +482,40 @@ globalThis.lx_setup = (key, id, name, description, rawScript) => {
}
return null
},
}),
})
}
const _toString = Function.prototype.toString
// eslint-disable-next-line no-extend-native
Function.prototype.toString = function() {
return Object.getOwnPropertyDescriptors(this).name.configurable
? _toString.apply(this)
: `function ${this.name}() { [native code] }`
}
const excludes = [
Function.prototype.toString,
Function.prototype.toLocaleString,
Object.prototype.toString,
]
const freezeObject = (obj, freezedObj = new Set()) => {
if (obj == null) return
switch (typeof obj) {
case 'object':
case 'function':
if (freezedObj.has(obj)) return
// Object.freeze(obj)
freezedObj.add(obj)
for (const [name, { ...config }] of Object.entries(Object.getOwnPropertyDescriptors(obj))) {
if (!excludes.includes(config.value)) {
if (config.writable) config.writable = false
if (config.configurable) config.configurable = false
Object.defineProperty(obj, name, config)
}
freezeObject(config.value, freezedObj)
}
}
}
freezeObject(globalThis)
console.log('Preload finished.')
}