/** * 提现管理导出防崩溃与 PHP 8.0 兼容性回归测试 */ const fs = require('fs'); const path = require('path'); const assert = require('assert'); console.log('========================================================'); console.log(' 开始执行提现台账导出防崩溃与全链路加固测试'); console.log('========================================================\n'); // 1. 测试模型层 PHP 8.0 bcmath 防崩溃模拟 function simulateChargeRateFormat(value, chargeRate) { const rate = (value !== null && value !== undefined && value !== '') ? value : (chargeRate ?? 0); const safeRate = (!isNaN(rate) && rate !== '' && rate !== null && rate !== undefined) ? String(rate) : '0'; return (Number(safeRate) * 100).toFixed(1) + '%'; } function simulateRealAmount(amount, chargeFee) { const safeAmount = (!isNaN(amount) && amount !== '' && amount !== null) ? Number(amount) : 0; const safeFee = (!isNaN(chargeFee) && chargeFee !== '' && chargeFee !== null) ? Number(chargeFee) : 0; return Math.max(0, safeAmount - safeFee); } // 模拟各种异常输入,确保不抛出错误 assert.strictEqual(simulateChargeRateFormat(null, null), '0.0%'); assert.strictEqual(simulateChargeRateFormat('', ''), '0.0%'); assert.strictEqual(simulateChargeRateFormat(0, 0), '0.0%'); assert.strictEqual(simulateChargeRateFormat(undefined, 0.06), '6.0%'); assert.strictEqual(simulateRealAmount(null, null), 0); assert.strictEqual(simulateRealAmount('', ''), 0); assert.strictEqual(simulateRealAmount(100, 6), 94); assert.strictEqual(simulateRealAmount(10, 0.60), 9.4); console.log('[测试点 1] 模型层 PHP 8.0 bcmath 边界参数容错模拟断言通过'); // 2. 检查 application/admin/model/shopro/Withdraw.php 包含加固逻辑 const modelContent = fs.readFileSync(path.resolve(__dirname, '../../application/admin/model/shopro/Withdraw.php'), 'utf8'); assert(modelContent.includes('is_numeric($rate)'), 'getChargeRateFormatAttr 包含 is_numeric 校验'); assert(modelContent.includes('is_numeric($amount)'), 'getRealAmountAttr 包含 is_numeric 校验'); console.log('[测试点 2] Withdraw 模型源代码加固断言通过'); // 3. 检查 addons/shopro/library/Export.php 包含缓冲检查、临时文件生成与安全输出 const exportContent = fs.readFileSync(path.resolve(__dirname, '../../addons/shopro/library/Export.php'), 'utf8'); assert(exportContent.includes('ob_get_level() > 0'), 'Export.php 包含 ob_get_level() 检查防 Notice'); assert(exportContent.includes('temp/export/'), 'Export.php 优先写入临时文件校验'); assert(exportContent.includes('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'), 'Export.php 使用标准 xlsx mime 类型'); assert(exportContent.includes('Content-Length'), 'Export.php 包含 Content-Length 响应头'); assert(exportContent.includes("if ($this->config['save_type'] == 'save')"), 'Export.php 包含 save_type 判断'); assert(exportContent.includes('exit;'), 'Export.php 下载完成安全退出'); console.log('[测试点 3] Export.php 临时文件安全写入、标准MIME与下载防污染退出断言通过'); // 3.1 检查 composer.json 锁定 maennchen/zipstream-php: ^2.4 防 PHP 8.1 readonly 语法错误 const composerContent = fs.readFileSync(path.resolve(__dirname, '../../composer.json'), 'utf8'); assert(composerContent.includes('"maennchen/zipstream-php": "^2.4"'), 'composer.json 锁定 zipstream-php: ^2.4'); console.log('[测试点 3.1] composer.json 兼容性依赖锁定断言通过'); // 4. 检查 application/admin/controller/shopro/Withdraw.php 包含异常捕获、单 key 汇总、时间格式化 const controllerContent = fs.readFileSync(path.resolve(__dirname, '../../application/admin/controller/shopro/Withdraw.php'), 'utf8'); assert(controllerContent.includes('catch (\\Throwable $e)'), 'Withdraw.php 包含 \\Throwable 全局异常捕获'); assert(controllerContent.includes("(new WithdrawModel)->sheepFilter()"), 'Withdraw.php 使用全新实例查询防状态污染'); assert(controllerContent.includes("date('Y-m-d H:i:s'"), 'Withdraw.php 包含时间戳转格式化日期'); assert(controllerContent.includes("'id' => '合计: 共 ' . $total"), 'Withdraw.php 汇总行符合 Export.php 单 key 自动合并规范'); console.log('[测试点 4] Withdraw.php 控制器异常保护与导出规范断言通过'); // 5. 检查 public/assets/js/backend/shopro/withdraw.js 采用隐藏 iframe 下载 const jsContent = fs.readFileSync(path.resolve(__dirname, '../../public/assets/js/backend/shopro/withdraw.js'), 'utf8'); assert(jsContent.includes("document.createElement('iframe')"), 'withdraw.js 使用隐藏 iframe 触发下载'); assert(jsContent.includes('encodeURIComponent(search.search'), 'withdraw.js 对 search 参数进行安全 URI 编码'); assert(!jsContent.includes('window.location.href = `${Config.moduleurl}/shopro/withdraw/${type}'), '已移除直接 window.location 避免后台页面被替换'); console.log('[测试点 5] withdraw.js 前端静默下载与主页面安全隔离断言通过'); console.log('\n========================================================'); console.log(' 所有提现导出防崩溃加固测试全部通过![100% OK]'); console.log('========================================================');