mirror of
https://github.com/yuaotian/go-cursor-help.git
synced 2026-03-08 06:44:14 +00:00
```
feat(cursor_hook): 增强storage.json telemetry字段保护机制
- 🔧 补齐核心ID字段(machineId、macMachineId、devDeviceId、sqmId)用于Hook与storage.json保护
- 新增normalizeFilePath函数规范化文件路径处理(兼容string/Buffer/URL等类型)
- 实现coerceContentToUtf8Text函数统一文本内容编码处理
- 扩展fs模块Hook覆盖appendFile、createWriteStream、open/close等API
- 添加fd追踪机制保护基于文件描述符的storage.json写入操作
- 优化注册表读取拦截逻辑增强健壮性
- 完善错误处理和日志输出机制
```
This commit is contained in:
@@ -120,6 +120,23 @@ var __cursor_hook_config__ = {
|
||||
ids = JSON.parse(content);
|
||||
// 补全缺失字段,保持向后兼容
|
||||
let updated = false;
|
||||
// 🔧 补齐核心 ID 字段(用于 Hook 与 storage.json 保护)
|
||||
if (!ids.machineId || typeof ids.machineId !== 'string') {
|
||||
ids.machineId = generateHex64();
|
||||
updated = true;
|
||||
}
|
||||
if (!ids.macMachineId || typeof ids.macMachineId !== 'string') {
|
||||
ids.macMachineId = generateHex64();
|
||||
updated = true;
|
||||
}
|
||||
if (!ids.devDeviceId || typeof ids.devDeviceId !== 'string') {
|
||||
ids.devDeviceId = generateUUID();
|
||||
updated = true;
|
||||
}
|
||||
if (!ids.sqmId || typeof ids.sqmId !== 'string') {
|
||||
ids.sqmId = `{${generateUUID().toUpperCase()}}`;
|
||||
updated = true;
|
||||
}
|
||||
if (!ids.machineGuid) {
|
||||
ids.machineGuid = generateUUID();
|
||||
updated = true;
|
||||
@@ -326,12 +343,81 @@ var __cursor_hook_config__ = {
|
||||
'telemetry.sqmId'
|
||||
];
|
||||
|
||||
// 规范化 filePath(兼容 string/Buffer/URL 等)
|
||||
function normalizeFilePath(filePath) {
|
||||
try {
|
||||
if (filePath === undefined || filePath === null) return '';
|
||||
if (typeof filePath === 'string') return filePath;
|
||||
if (Buffer.isBuffer(filePath)) return filePath.toString('utf8');
|
||||
|
||||
// WHATWG URL (fs 支持 URL 对象)
|
||||
if (typeof filePath === 'object' && typeof filePath.href === 'string') {
|
||||
// 优先将 file:// URL 转为本地路径,避免传递 "file:///..." 字符串导致 existsSync/readFileSync 失败
|
||||
if (typeof filePath.protocol === 'string' && filePath.protocol === 'file:') {
|
||||
try {
|
||||
const url = require('url');
|
||||
if (url && typeof url.fileURLToPath === 'function') {
|
||||
return url.fileURLToPath(filePath);
|
||||
}
|
||||
} catch (_) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
return filePath.href;
|
||||
}
|
||||
|
||||
return String(filePath);
|
||||
} catch (_) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function previewValue(value) {
|
||||
try {
|
||||
const s = String(value);
|
||||
return s.length > 16 ? s.slice(0, 16) + '...' : s;
|
||||
} catch (_) {
|
||||
return '<unprintable>';
|
||||
}
|
||||
}
|
||||
|
||||
// 将写入内容转为 utf8 文本,并提供回写为“同类类型”的包装器
|
||||
function coerceContentToUtf8Text(content) {
|
||||
try {
|
||||
if (typeof content === 'string') {
|
||||
return { text: content, wrap: (s) => s };
|
||||
}
|
||||
if (Buffer.isBuffer(content)) {
|
||||
return { text: content.toString('utf8'), wrap: (s) => Buffer.from(s, 'utf8') };
|
||||
}
|
||||
// TypedArray / DataView
|
||||
if (content && typeof content === 'object') {
|
||||
if (content instanceof Uint8Array) {
|
||||
// Buffer 也属于 Uint8Array,但已在上面处理
|
||||
const buf = Buffer.from(content);
|
||||
return { text: buf.toString('utf8'), wrap: (s) => new Uint8Array(Buffer.from(s, 'utf8')) };
|
||||
}
|
||||
if (typeof ArrayBuffer !== 'undefined' && content instanceof ArrayBuffer) {
|
||||
const buf = Buffer.from(content);
|
||||
return { text: buf.toString('utf8'), wrap: (s) => Buffer.from(s, 'utf8') };
|
||||
}
|
||||
if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && ArrayBuffer.isView(content)) {
|
||||
const buf = Buffer.from(content.buffer, content.byteOffset, content.byteLength);
|
||||
return { text: buf.toString('utf8'), wrap: (s) => Buffer.from(s, 'utf8') };
|
||||
}
|
||||
}
|
||||
} catch (_) {
|
||||
// ignore
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// 检查路径是否为 storage.json
|
||||
function isStorageJsonPath(filePath) {
|
||||
if (!filePath || typeof filePath !== 'string') return false;
|
||||
const normalized = filePath.replace(/\\/g, '/').toLowerCase();
|
||||
return normalized.includes('globalStorage/storage.json') ||
|
||||
normalized.includes('globalstorage/storage.json');
|
||||
const raw = normalizeFilePath(filePath);
|
||||
if (!raw) return false;
|
||||
const normalized = raw.replace(/\\/g, '/').toLowerCase();
|
||||
return normalized.includes('globalstorage/storage.json');
|
||||
}
|
||||
|
||||
// 保护 storage.json 中的 telemetry 字段
|
||||
@@ -340,57 +426,80 @@ var __cursor_hook_config__ = {
|
||||
|
||||
try {
|
||||
const fs = require('fs');
|
||||
let newData = typeof content === 'string' ? JSON.parse(content) : content;
|
||||
const coerced = coerceContentToUtf8Text(content);
|
||||
if (!coerced) return content;
|
||||
|
||||
let newData;
|
||||
try {
|
||||
newData = JSON.parse(coerced.text);
|
||||
} catch (_) {
|
||||
return content;
|
||||
}
|
||||
|
||||
// 如果写入的内容不是有效的 JSON 对象,直接返回
|
||||
if (typeof newData !== 'object' || newData === null) {
|
||||
return content;
|
||||
}
|
||||
|
||||
// 读取当前文件中的受保护字段
|
||||
// 保护值优先级:
|
||||
// 1) __cursor_ids__(Hook 配置/环境变量/自动生成)
|
||||
// 2) 现有 storage.json 中已存在的值
|
||||
// 3) 本次写入值(最低)
|
||||
const protectedValues = {
|
||||
'telemetry.machineId': __cursor_ids__ && __cursor_ids__.machineId,
|
||||
'telemetry.macMachineId': __cursor_ids__ && __cursor_ids__.macMachineId,
|
||||
'telemetry.devDeviceId': __cursor_ids__ && __cursor_ids__.devDeviceId,
|
||||
'telemetry.sqmId': __cursor_ids__ && __cursor_ids__.sqmId
|
||||
};
|
||||
|
||||
// 仅当 Hook 配置不完整时,才读取旧文件值作为二级兜底
|
||||
let existingProtected = {};
|
||||
try {
|
||||
if (fs.existsSync(filePath)) {
|
||||
const existing = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
||||
for (const key of PROTECTED_TELEMETRY_KEYS) {
|
||||
if (existing[key] !== undefined) {
|
||||
existingProtected[key] = existing[key];
|
||||
const needExisting = PROTECTED_TELEMETRY_KEYS.some((k) => !(typeof protectedValues[k] === 'string' && protectedValues[k]));
|
||||
if (needExisting) {
|
||||
try {
|
||||
if (fs.existsSync(filePath)) {
|
||||
const existingText = fs.readFileSync(filePath, 'utf8');
|
||||
const existing = JSON.parse(existingText);
|
||||
if (existing && typeof existing === 'object') {
|
||||
for (const key of PROTECTED_TELEMETRY_KEYS) {
|
||||
if (typeof existing[key] === 'string' && existing[key]) {
|
||||
existingProtected[key] = existing[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (_) {
|
||||
// ignore
|
||||
}
|
||||
} catch (e) {
|
||||
// 文件不存在或解析失败,使用 Hook 配置的 ID
|
||||
}
|
||||
|
||||
// 强制使用 Hook 配置的 ID(优先级最高)
|
||||
const protectedValues = {
|
||||
'telemetry.machineId': __cursor_ids__.machineId,
|
||||
'telemetry.macMachineId': __cursor_ids__.macMachineId,
|
||||
'telemetry.devDeviceId': __cursor_ids__.devDeviceId,
|
||||
'telemetry.sqmId': __cursor_ids__.sqmId
|
||||
};
|
||||
|
||||
// 检测并修正被覆盖的字段
|
||||
let modified = false;
|
||||
for (const key of PROTECTED_TELEMETRY_KEYS) {
|
||||
const protectedValue = protectedValues[key];
|
||||
if (newData[key] !== undefined && newData[key] !== protectedValue) {
|
||||
log(`[fs Hook] 拦截 ${key} 覆盖: ${newData[key].substring(0, 16)}... -> ${protectedValue.substring(0, 16)}...`);
|
||||
newData[key] = protectedValue;
|
||||
modified = true;
|
||||
} else if (newData[key] === undefined && existingProtected[key]) {
|
||||
// 如果新数据没有该字段,但旧文件有,保留旧值
|
||||
newData[key] = existingProtected[key];
|
||||
const fromIds = protectedValues[key];
|
||||
const desired = (typeof fromIds === 'string' && fromIds) ? fromIds
|
||||
: (typeof existingProtected[key] === 'string' && existingProtected[key]) ? existingProtected[key]
|
||||
: undefined;
|
||||
|
||||
if (desired === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 方案B:无论写入内容是否包含该字段,都确保最终值稳定(缺失则补齐)
|
||||
if (newData[key] !== desired) {
|
||||
log(`[fs Hook] 固定 ${key}: ${previewValue(newData[key])} -> ${previewValue(desired)}`);
|
||||
newData[key] = desired;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
log('[fs Hook] storage.json telemetry 字段已保护');
|
||||
return typeof content === 'string' ? JSON.stringify(newData, null, '\t') : newData;
|
||||
const nextText = JSON.stringify(newData, null, '\t');
|
||||
return coerced.wrap(nextText);
|
||||
}
|
||||
} catch (e) {
|
||||
log('[fs Hook] 处理 storage.json 失败:', e.message);
|
||||
const msg = e && e.message ? e.message : String(e);
|
||||
log('[fs Hook] 处理 storage.json 失败:', msg);
|
||||
}
|
||||
|
||||
return content;
|
||||
@@ -399,6 +508,35 @@ var __cursor_hook_config__ = {
|
||||
function hookFs(fsModule) {
|
||||
const originalWriteFileSync = fsModule.writeFileSync;
|
||||
const originalWriteFile = fsModule.writeFile;
|
||||
const originalAppendFileSync = fsModule.appendFileSync;
|
||||
const originalAppendFile = fsModule.appendFile;
|
||||
const originalCreateWriteStream = fsModule.createWriteStream;
|
||||
const originalOpenSync = fsModule.openSync;
|
||||
const originalOpen = fsModule.open;
|
||||
const originalCloseSync = fsModule.closeSync;
|
||||
const originalClose = fsModule.close;
|
||||
|
||||
// fd 追踪:覆盖 open/close 路径(仅用于 storage.json)
|
||||
const storageJsonFds = new Map();
|
||||
let inFdFix = false;
|
||||
|
||||
const fixStorageJsonFile = (filePath) => {
|
||||
if (inFdFix) return;
|
||||
inFdFix = true;
|
||||
try {
|
||||
const current = fsModule.readFileSync(filePath, 'utf8');
|
||||
const next = protectStorageJson(current, filePath);
|
||||
if (typeof next === 'string' && next !== current) {
|
||||
originalWriteFileSync.call(fsModule, filePath, next, 'utf8');
|
||||
log('[fs Hook] close-fix: storage.json telemetry 字段已重新保护');
|
||||
}
|
||||
} catch (e) {
|
||||
const msg = e && e.message ? e.message : String(e);
|
||||
log('[fs Hook] close-fix 失败:', msg);
|
||||
} finally {
|
||||
inFdFix = false;
|
||||
}
|
||||
};
|
||||
|
||||
// Hook writeFileSync
|
||||
fsModule.writeFileSync = function(filePath, data, options) {
|
||||
@@ -424,6 +562,126 @@ var __cursor_hook_config__ = {
|
||||
const protectedData = protectStorageJson(data, filePath);
|
||||
return originalPromisesWriteFile.call(this, filePath, protectedData, options);
|
||||
};
|
||||
|
||||
if (typeof fsModule.promises.appendFile === 'function') {
|
||||
const originalPromisesAppendFile = fsModule.promises.appendFile;
|
||||
fsModule.promises.appendFile = async function(filePath, data, options) {
|
||||
const protectedData = protectStorageJson(data, filePath);
|
||||
return originalPromisesAppendFile.call(this, filePath, protectedData, options);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Hook appendFileSync
|
||||
if (typeof originalAppendFileSync === 'function') {
|
||||
fsModule.appendFileSync = function(filePath, data, options) {
|
||||
const protectedData = protectStorageJson(data, filePath);
|
||||
return originalAppendFileSync.call(this, filePath, protectedData, options);
|
||||
};
|
||||
}
|
||||
|
||||
// Hook appendFile (异步版本)
|
||||
if (typeof originalAppendFile === 'function') {
|
||||
fsModule.appendFile = function(filePath, data, options, callback) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
options = undefined;
|
||||
}
|
||||
const protectedData = protectStorageJson(data, filePath);
|
||||
return originalAppendFile.call(this, filePath, protectedData, options, callback);
|
||||
};
|
||||
}
|
||||
|
||||
// Hook createWriteStream(仅对 storage.json:保持原生 WriteStream,但 close 后做补救性修正)
|
||||
if (typeof originalCreateWriteStream === 'function') {
|
||||
fsModule.createWriteStream = function(filePath, options) {
|
||||
const stream = originalCreateWriteStream.apply(this, arguments);
|
||||
if (isStorageJsonPath(filePath) && stream && typeof stream.on === 'function') {
|
||||
stream.on('close', () => {
|
||||
try {
|
||||
fixStorageJsonFile(filePath);
|
||||
} catch (_) {
|
||||
// ignore
|
||||
}
|
||||
});
|
||||
}
|
||||
return stream;
|
||||
};
|
||||
}
|
||||
|
||||
// Hook open/openSync:追踪 storage.json 的 fd
|
||||
if (typeof originalOpenSync === 'function') {
|
||||
fsModule.openSync = function(filePath) {
|
||||
const fd = originalOpenSync.apply(this, arguments);
|
||||
try {
|
||||
if (!inFdFix && isStorageJsonPath(filePath)) {
|
||||
storageJsonFds.set(fd, filePath);
|
||||
}
|
||||
} catch (_) {
|
||||
// ignore
|
||||
}
|
||||
return fd;
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof originalOpen === 'function') {
|
||||
fsModule.open = function(filePath, flags, mode, callback) {
|
||||
if (typeof mode === 'function') {
|
||||
callback = mode;
|
||||
mode = undefined;
|
||||
}
|
||||
|
||||
const wrapped = function(err, fd) {
|
||||
try {
|
||||
if (!err && !inFdFix && isStorageJsonPath(filePath)) {
|
||||
storageJsonFds.set(fd, filePath);
|
||||
}
|
||||
} catch (_) {
|
||||
// ignore
|
||||
}
|
||||
if (typeof callback === 'function') {
|
||||
return callback.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
if (mode === undefined) {
|
||||
return originalOpen.call(this, filePath, flags, wrapped);
|
||||
}
|
||||
return originalOpen.call(this, filePath, flags, mode, wrapped);
|
||||
};
|
||||
}
|
||||
|
||||
// Hook close/closeSync:关闭后再做一次“落盘后修正”(覆盖 fd 写入路径)
|
||||
if (typeof originalCloseSync === 'function') {
|
||||
fsModule.closeSync = function(fd) {
|
||||
const filePath = storageJsonFds.get(fd);
|
||||
const ret = originalCloseSync.apply(this, arguments);
|
||||
if (filePath !== undefined) {
|
||||
storageJsonFds.delete(fd);
|
||||
fixStorageJsonFile(filePath);
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof originalClose === 'function') {
|
||||
fsModule.close = function(fd, callback) {
|
||||
const filePath = storageJsonFds.get(fd);
|
||||
const wrapped = function(err) {
|
||||
try {
|
||||
if (!err && filePath !== undefined) {
|
||||
storageJsonFds.delete(fd);
|
||||
fixStorageJsonFile(filePath);
|
||||
}
|
||||
} catch (_) {
|
||||
// ignore
|
||||
}
|
||||
if (typeof callback === 'function') {
|
||||
return callback.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
return originalClose.call(this, fd, wrapped);
|
||||
};
|
||||
}
|
||||
|
||||
log('[fs Hook] 已启用 storage.json 写入保护');
|
||||
@@ -511,17 +769,21 @@ var __cursor_hook_config__ = {
|
||||
return {
|
||||
...registryModule,
|
||||
GetStringRegKey: function(hive, path, name) {
|
||||
const pathStr = (typeof path === 'string') ? path : '';
|
||||
// 拦截 MachineId 读取
|
||||
if (name === 'MachineId' || path.includes('SQMClient')) {
|
||||
if (name === 'MachineId' || pathStr.includes('SQMClient')) {
|
||||
log('拦截注册表 MachineId/SQMClient 读取');
|
||||
return __cursor_ids__.sqmId;
|
||||
}
|
||||
// 拦截 MachineGuid 读取
|
||||
if (name === 'MachineGuid' || path.includes('Cryptography')) {
|
||||
if (name === 'MachineGuid' || pathStr.includes('Cryptography')) {
|
||||
log('拦截注册表 MachineGuid 读取');
|
||||
return getMachineGuid();
|
||||
}
|
||||
return originalGetStringRegKey?.apply(this, arguments) || '';
|
||||
if (typeof originalGetStringRegKey === 'function') {
|
||||
return originalGetStringRegKey.apply(this, arguments) || '';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -605,15 +867,19 @@ var __cursor_hook_config__ = {
|
||||
const hooked = {
|
||||
...registryModule,
|
||||
GetStringRegKey: function(hive, path, name) {
|
||||
if (name === 'MachineId' || path?.includes('SQMClient')) {
|
||||
const pathStr = (typeof path === 'string') ? path : '';
|
||||
if (name === 'MachineId' || pathStr.includes('SQMClient')) {
|
||||
log('动态导入: 拦截 SQMClient');
|
||||
return __cursor_ids__.sqmId;
|
||||
}
|
||||
if (name === 'MachineGuid' || path?.includes('Cryptography')) {
|
||||
if (name === 'MachineGuid' || pathStr.includes('Cryptography')) {
|
||||
log('动态导入: 拦截 MachineGuid');
|
||||
return getMachineGuid();
|
||||
}
|
||||
return originalGetStringRegKey?.apply(this, arguments) || '';
|
||||
if (typeof originalGetStringRegKey === 'function') {
|
||||
return originalGetStringRegKey.apply(this, arguments) || '';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
@@ -630,6 +896,34 @@ var __cursor_hook_config__ = {
|
||||
const hooked = { ...fsModule };
|
||||
const originalWriteFileSync = fsModule.writeFileSync;
|
||||
const originalWriteFile = fsModule.writeFile;
|
||||
const originalAppendFileSync = fsModule.appendFileSync;
|
||||
const originalAppendFile = fsModule.appendFile;
|
||||
const originalCreateWriteStream = fsModule.createWriteStream;
|
||||
const originalOpenSync = fsModule.openSync;
|
||||
const originalOpen = fsModule.open;
|
||||
const originalCloseSync = fsModule.closeSync;
|
||||
const originalClose = fsModule.close;
|
||||
|
||||
const storageJsonFds = new Map();
|
||||
let inFdFix = false;
|
||||
|
||||
const fixStorageJsonFile = (filePath) => {
|
||||
if (inFdFix) return;
|
||||
inFdFix = true;
|
||||
try {
|
||||
const current = fsModule.readFileSync(filePath, 'utf8');
|
||||
const next = protectStorageJson(current, filePath);
|
||||
if (typeof next === 'string' && next !== current) {
|
||||
originalWriteFileSync.call(fsModule, filePath, next, 'utf8');
|
||||
log('动态导入: close-fix storage.json telemetry 字段已重新保护');
|
||||
}
|
||||
} catch (e) {
|
||||
const msg = e && e.message ? e.message : String(e);
|
||||
log('动态导入: close-fix 失败:', msg);
|
||||
} finally {
|
||||
inFdFix = false;
|
||||
}
|
||||
};
|
||||
|
||||
hooked.writeFileSync = function(filePath, data, options) {
|
||||
const protectedData = protectStorageJson(data, filePath);
|
||||
@@ -655,6 +949,121 @@ var __cursor_hook_config__ = {
|
||||
return originalPromisesWriteFile.call(this, filePath, protectedData, options);
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof fsModule.promises.appendFile === 'function') {
|
||||
const originalPromisesAppendFile = fsModule.promises.appendFile;
|
||||
hooked.promises.appendFile = async function(filePath, data, options) {
|
||||
const protectedData = protectStorageJson(data, filePath);
|
||||
return originalPromisesAppendFile.call(this, filePath, protectedData, options);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof originalAppendFileSync === 'function') {
|
||||
hooked.appendFileSync = function(filePath, data, options) {
|
||||
const protectedData = protectStorageJson(data, filePath);
|
||||
return originalAppendFileSync.call(this, filePath, protectedData, options);
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof originalAppendFile === 'function') {
|
||||
hooked.appendFile = function(filePath, data, options, callback) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
options = undefined;
|
||||
}
|
||||
const protectedData = protectStorageJson(data, filePath);
|
||||
return originalAppendFile.call(this, filePath, protectedData, options, callback);
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof originalCreateWriteStream === 'function') {
|
||||
hooked.createWriteStream = function(filePath, options) {
|
||||
const stream = originalCreateWriteStream.apply(this, arguments);
|
||||
if (isStorageJsonPath(filePath) && stream && typeof stream.on === 'function') {
|
||||
stream.on('close', () => {
|
||||
try {
|
||||
fixStorageJsonFile(filePath);
|
||||
} catch (_) {
|
||||
// ignore
|
||||
}
|
||||
});
|
||||
}
|
||||
return stream;
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof originalOpenSync === 'function') {
|
||||
hooked.openSync = function(filePath) {
|
||||
const fd = originalOpenSync.apply(this, arguments);
|
||||
try {
|
||||
if (!inFdFix && isStorageJsonPath(filePath)) {
|
||||
storageJsonFds.set(fd, filePath);
|
||||
}
|
||||
} catch (_) {
|
||||
// ignore
|
||||
}
|
||||
return fd;
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof originalOpen === 'function') {
|
||||
hooked.open = function(filePath, flags, mode, callback) {
|
||||
if (typeof mode === 'function') {
|
||||
callback = mode;
|
||||
mode = undefined;
|
||||
}
|
||||
|
||||
const wrapped = function(err, fd) {
|
||||
try {
|
||||
if (!err && !inFdFix && isStorageJsonPath(filePath)) {
|
||||
storageJsonFds.set(fd, filePath);
|
||||
}
|
||||
} catch (_) {
|
||||
// ignore
|
||||
}
|
||||
if (typeof callback === 'function') {
|
||||
return callback.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
if (mode === undefined) {
|
||||
return originalOpen.call(this, filePath, flags, wrapped);
|
||||
}
|
||||
return originalOpen.call(this, filePath, flags, mode, wrapped);
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof originalCloseSync === 'function') {
|
||||
hooked.closeSync = function(fd) {
|
||||
const filePath = storageJsonFds.get(fd);
|
||||
const ret = originalCloseSync.apply(this, arguments);
|
||||
if (filePath !== undefined) {
|
||||
storageJsonFds.delete(fd);
|
||||
fixStorageJsonFile(filePath);
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof originalClose === 'function') {
|
||||
hooked.close = function(fd, callback) {
|
||||
const filePath = storageJsonFds.get(fd);
|
||||
const wrapped = function(err) {
|
||||
try {
|
||||
if (!err && filePath !== undefined) {
|
||||
storageJsonFds.delete(fd);
|
||||
fixStorageJsonFile(filePath);
|
||||
}
|
||||
} catch (_) {
|
||||
// ignore
|
||||
}
|
||||
if (typeof callback === 'function') {
|
||||
return callback.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
return originalClose.call(this, fd, wrapped);
|
||||
};
|
||||
}
|
||||
|
||||
log('动态导入: 已 Hook fs 模块');
|
||||
|
||||
Reference in New Issue
Block a user