react 污点? react 腐蚀? react 污染? react 玷污!!!
一、作用
二、污染唯一值
备注
binaryToComparableString()由 binaryToComparableString 实现
export function taintUniqueValue(
message: ?string,
lifetime: Reference,
value: string | bigint | $ArrayBufferView,
): void {
if (!enableTaint) {
throw new Error('Not implemented.');
}
message = '' + (message || defaultMessage);
if (
lifetime === null ||
(typeof lifetime !== 'object' && typeof lifetime !== 'function')
) {
throw new Error(
// 要污染一个值,必须通过传递一个持有对象来定义该值的生命周期
'To taint a value, a lifetime must be defined by passing an object that holds ' +
'the value.',
);
}
let entryValue: string | bigint;
if (typeof value === 'string' || typeof value === 'bigint') {
// Use as is.
// 按原样使用。
entryValue = value;
} else if (
value instanceof TypedArrayConstructor ||
value instanceof DataView
) {
// For now, we just convert binary data to a string so that we can just use the native
// hashing in the Map implementation. It doesn't really matter what form the string
// take as long as it's the same when we look it up.
// We're not too worried about collisions since this should be a high entropy value.
//
// 目前,我们只是将二进制数据转换为字符串,以便可以直接使用 Map 实现中的原生哈希功能。字符串的具体形式
// 实际上无关紧要,只要在查找时保持一致即可。我们不太担心冲突,因为这应该是一个高熵值。
TaintRegistryByteLengths.add(value.byteLength);
entryValue = binaryToComparableString(value);
} else {
const kind = value === null ? 'null' : typeof value;
if (kind === 'object' || kind === 'function') {
throw new Error(
// taintUniqueValue 不能污染对象或函数。请改用 taintObjectReference
'taintUniqueValue cannot taint objects or functions. Try taintObjectReference instead.',
);
}
throw new Error(
// 无法污染一个
'Cannot taint a ' +
kind +
// 因为这个值太泛,不够唯一,无法在全局范围内阻止。
' because the value is too general and not unique enough to block globally.',
);
}
const existingEntry = TaintRegistryValues.get(entryValue);
if (existingEntry === undefined) {
TaintRegistryValues.set(entryValue, {
message,
count: 1,
});
} else {
existingEntry.count++;
}
if (finalizationRegistry !== null) {
finalizationRegistry.register(lifetime, entryValue);
}
}
三、污染对象引用
export function taintObjectReference(
message: ?string,
object: Reference,
): void {
if (!enableTaint) {
throw new Error('Not implemented.');
}
message = '' + (message || defaultMessage);
if (typeof object === 'string' || typeof object === 'bigint') {
throw new Error(
// 只有对象或函数可以传递给 taintObjectReference。试试 taintUniqueValue。
'Only objects or functions can be passed to taintObjectReference. Try taintUniqueValue instead.',
);
}
if (
object === null ||
(typeof object !== 'object' && typeof object !== 'function')
) {
throw new Error(
// 只有对象或函数可以传递给 taintObjectReference。
'Only objects or functions can be passed to taintObjectReference.',
);
}
TaintRegistryObjects.set(object, message);
}
四、常量
1. en
备注
ReactSharedInternals()由 ReactSharedInternals 实现
const {
TaintRegistryObjects,
TaintRegistryValues,
TaintRegistryByteLengths,
TaintRegistryPendingRequests,
} = ReactSharedInternals;
2. 类型化数组构造函数
备注
getPrototypeOf()由 [getPrototypeOf] 实现
// This is the shared constructor of all typed arrays.
// 这是所有类型化数组的共享构造函数。
const TypedArrayConstructor = getPrototypeOf(Uint32Array.prototype).constructor;
3. 默认消息
const defaultMessage =
// 试图将受污染的值序列化到客户端组件或操作闭包。
'A tainted value was attempted to be serialized to a Client Component or Action closure. ' +
// 这会泄露给客户端。
'This would leak it to the client.';
4. 终结注册表
// If FinalizationRegistry doesn't exist, we assume that objects life forever.
// 如果 FinalizationRegistry 不存在,我们假设对象永远存在。
// E.g. the whole VM is just the lifetime of a request.
// 例如,整个虚拟机会随着请求的存在而存在。
const finalizationRegistry =
typeof FinalizationRegistry === 'function'
? new FinalizationRegistry(cleanup)
: null;
五、工具
1. 清理
function cleanup(entryValue: string | bigint): void {
const entry = TaintRegistryValues.get(entryValue);
if (entry !== undefined) {
TaintRegistryPendingRequests.forEach(function (requestQueue) {
requestQueue.push(entryValue);
entry.count++;
});
if (entry.count === 1) {
TaintRegistryValues.delete(entryValue);
} else {
entry.count--;
}
}
}