Add JS-CATCH-FALLBACK-01 rule and update npm packages

Add PHP-ALIAS-01 rule: prohibit field aliasing in serialization

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-12-23 07:36:18 +00:00
parent 3cc590186a
commit 3ce82a924a
1256 changed files with 6491 additions and 3989 deletions

View File

@@ -5,212 +5,21 @@
"use strict";
const Hash = require("./Hash");
/** @typedef {import("../../declarations/WebpackOptions").HashDigest} Encoding */
/** @typedef {import("./Hash")} Hash */
/** @typedef {import("../../declarations/WebpackOptions").HashFunction} HashFunction */
const BULK_SIZE = 3;
// We are using an object instead of a Map as this will stay static during the runtime
// so access to it can be optimized by v8
/** @type {{[key: string]: Map<string, string>}} */
const digestCaches = {};
/** @typedef {() => Hash} HashFactory */
class BulkUpdateDecorator extends Hash {
/**
* @param {Hash | HashFactory} hashOrFactory function to create a hash
* @param {string=} hashKey key for caching
*/
constructor(hashOrFactory, hashKey) {
super();
this.hashKey = hashKey;
if (typeof hashOrFactory === "function") {
this.hashFactory = hashOrFactory;
this.hash = undefined;
} else {
this.hashFactory = undefined;
this.hash = hashOrFactory;
}
this.buffer = "";
}
/**
* Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
* @overload
* @param {string | Buffer} data data
* @returns {Hash} updated hash
*/
/**
* Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
* @overload
* @param {string} data data
* @param {Encoding} inputEncoding data encoding
* @returns {Hash} updated hash
*/
/**
* Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
* @param {string | Buffer} data data
* @param {Encoding=} inputEncoding data encoding
* @returns {Hash} updated hash
*/
update(data, inputEncoding) {
if (
inputEncoding !== undefined ||
typeof data !== "string" ||
data.length > BULK_SIZE
) {
if (this.hash === undefined) {
this.hash = /** @type {HashFactory} */ (this.hashFactory)();
}
if (this.buffer.length > 0) {
this.hash.update(this.buffer);
this.buffer = "";
}
if (typeof data === "string" && inputEncoding) {
this.hash.update(data, inputEncoding);
} else {
this.hash.update(data);
}
} else {
this.buffer += data;
if (this.buffer.length > BULK_SIZE) {
if (this.hash === undefined) {
this.hash = /** @type {HashFactory} */ (this.hashFactory)();
}
this.hash.update(this.buffer);
this.buffer = "";
}
}
return this;
}
/**
* Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
* @overload
* @returns {Buffer} digest
*/
/**
* Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
* @overload
* @param {Encoding} encoding encoding of the return value
* @returns {string} digest
*/
/**
* Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
* @param {Encoding=} encoding encoding of the return value
* @returns {string | Buffer} digest
*/
digest(encoding) {
let digestCache;
const buffer = this.buffer;
if (this.hash === undefined) {
// short data for hash, we can use caching
const cacheKey = `${this.hashKey}-${encoding}`;
digestCache = digestCaches[cacheKey];
if (digestCache === undefined) {
digestCache = digestCaches[cacheKey] = new Map();
}
const cacheEntry = digestCache.get(buffer);
if (cacheEntry !== undefined) return cacheEntry;
this.hash = /** @type {HashFactory} */ (this.hashFactory)();
}
if (buffer.length > 0) {
this.hash.update(buffer);
}
if (!encoding) {
const result = this.hash.digest();
if (digestCache !== undefined) {
digestCache.set(buffer, result);
}
return result;
}
const digestResult = this.hash.digest(encoding);
// Compatibility with the old hash library
const result =
typeof digestResult === "string"
? digestResult
: /** @type {NodeJS.TypedArray} */ (digestResult).toString();
if (digestCache !== undefined) {
digestCache.set(buffer, result);
}
return result;
}
}
/* istanbul ignore next */
class DebugHash extends Hash {
constructor() {
super();
this.string = "";
}
/**
* Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
* @overload
* @param {string | Buffer} data data
* @returns {Hash} updated hash
*/
/**
* Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
* @overload
* @param {string} data data
* @param {Encoding} inputEncoding data encoding
* @returns {Hash} updated hash
*/
/**
* Update hash {@link https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding}
* @param {string | Buffer} data data
* @param {Encoding=} inputEncoding data encoding
* @returns {Hash} updated hash
*/
update(data, inputEncoding) {
if (typeof data !== "string") data = data.toString("utf8");
const prefix = Buffer.from("@webpack-debug-digest@").toString("hex");
if (data.startsWith(prefix)) {
data = Buffer.from(data.slice(prefix.length), "hex").toString();
}
this.string += `[${data}](${
/** @type {string} */
(
// eslint-disable-next-line unicorn/error-message
new Error().stack
).split("\n", 3)[2]
})\n`;
return this;
}
/**
* Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
* @overload
* @returns {Buffer} digest
*/
/**
* Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
* @overload
* @param {Encoding} encoding encoding of the return value
* @returns {string} digest
*/
/**
* Calculates the digest {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding}
* @param {Encoding=} encoding encoding of the return value
* @returns {string | Buffer} digest
*/
digest(encoding) {
return Buffer.from(`@webpack-debug-digest@${this.string}`).toString("hex");
}
}
/** @type {typeof import("crypto") | undefined} */
let crypto;
/** @type {typeof import("./hash/xxhash64") | undefined} */
let createXXHash64;
/** @type {typeof import("./hash/md4") | undefined} */
let createMd4;
/** @type {typeof import("./hash/DebugHash") | undefined} */
let DebugHash;
/** @type {typeof import("./hash/BatchedHash") | undefined} */
let BatchedHash;
/** @type {typeof import("./hash/BulkUpdateHash") | undefined} */
let BulkUpdateHash;
/**
* Creates a hash by name or function
@@ -219,12 +28,18 @@ let BatchedHash;
*/
module.exports = (algorithm) => {
if (typeof algorithm === "function") {
if (BulkUpdateHash === undefined) {
BulkUpdateHash = require("./hash/BulkUpdateHash");
}
// eslint-disable-next-line new-cap
return new BulkUpdateDecorator(() => new algorithm());
return new BulkUpdateHash(() => new algorithm());
}
switch (algorithm) {
// TODO add non-cryptographic algorithm here
case "debug":
if (DebugHash === undefined) {
DebugHash = require("./hash/DebugHash");
}
return new DebugHash();
case "xxhash64":
if (createXXHash64 === undefined) {
@@ -248,7 +63,10 @@ module.exports = (algorithm) => {
)(createMd4());
case "native-md4":
if (crypto === undefined) crypto = require("crypto");
return new BulkUpdateDecorator(
if (BulkUpdateHash === undefined) {
BulkUpdateHash = require("./hash/BulkUpdateHash");
}
return new BulkUpdateHash(
() =>
/** @type {Hash} */ (
/** @type {typeof import("crypto")} */
@@ -258,7 +76,10 @@ module.exports = (algorithm) => {
);
default:
if (crypto === undefined) crypto = require("crypto");
return new BulkUpdateDecorator(
if (BulkUpdateHash === undefined) {
BulkUpdateHash = require("./hash/BulkUpdateHash");
}
return new BulkUpdateHash(
() =>
/** @type {Hash} */ (
/** @type {typeof import("crypto")} */