blob: f997a5f2afe20d70ad5c474197029b3ed3b7e15a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Freeze the prototype of javascript build-in objects.
*/
/* istanbul ignore next */
export function freezePrototype () {
Object.freeze(Object)
Object.freeze(Array)
// Object.freeze(Object.prototype)
freezeObjectProto()
Object.freeze(Array.prototype)
Object.freeze(String.prototype)
Object.freeze(Number.prototype)
Object.freeze(Boolean.prototype)
// Object.freeze(Error.prototype)
freezeErrorProto()
Object.freeze(Date.prototype)
Object.freeze(RegExp.prototype)
}
function freezeObjectProto () {
const proto = Object.prototype
const protoName = 'Object.prototype'
freezeProtoProperty(proto, '__defineGetter__', protoName)
freezeProtoProperty(proto, '__defineSetter__', protoName)
freezeProtoProperty(proto, '__lookupGetter__', protoName)
freezeProtoProperty(proto, '__lookupSetter__', protoName)
freezeProtoProperty(proto, 'constructor', protoName)
freezeProtoProperty(proto, 'hasOwnProperty', protoName)
freezeProtoProperty(proto, 'isPrototypeOf', protoName)
freezeProtoProperty(proto, 'propertyIsEnumerable', protoName)
freezeProtoProperty(proto, 'toLocaleString', protoName)
freezeProtoProperty(proto, 'toString', protoName)
freezeProtoProperty(proto, 'valueOf', protoName)
Object.seal(proto)
}
function freezeErrorProto () {
const proto = Error.prototype
const protoName = 'Error.prototype'
freezeProtoProperty(proto, 'name', protoName)
freezeProtoProperty(proto, 'message', protoName)
freezeProtoProperty(proto, 'toString', protoName)
freezeProtoProperty(proto, 'constructor', protoName)
Object.seal(proto)
}
function freezeProtoProperty (proto, propertyName, protoName) {
if (!proto.hasOwnProperty(propertyName)) {
return
}
const origin = proto[propertyName]
Object.defineProperty(proto, propertyName, {
get: function () {
return origin
},
set: function (value) {
if (this === proto) {
throw Error(`Cannot assign to read only property ${propertyName} of ${protoName}`)
}
Object.defineProperty(this, propertyName, {
value: value,
writable: true
})
return value
}
})
}