修复解密

This commit is contained in:
Billy 2025-10-20 09:23:30 +08:00
parent 48dbc5f4e4
commit 3f452ca979
1662 changed files with 73578 additions and 4659 deletions

View File

@ -47,8 +47,8 @@ class Ccblife extends Common
// 获取配置
$config = config('ccblife');
// 解密参数
$decryptedParams = CcbUrlDecrypt::decrypt($ccbParamSJ, $config['service_id']);
// 解密参数(使用服务方私钥)
$decryptedParams = CcbUrlDecrypt::decrypt($ccbParamSJ, $config['private_key']);
if (!$decryptedParams) {
$this->error('参数解密失败');
}
@ -236,21 +236,50 @@ class Ccblife extends Common
$this->error('缺少 ccbParamSJ 参数');
}
// 获取配置
$config = config('ccblife');
// 从插件配置文件直接加载避免config()缓存问题)
$configFile = __DIR__ . '/../config/ccblife.php';
if (!file_exists($configFile)) {
$this->error('建行配置文件不存在');
}
// 解密参数
$decryptedParams = CcbUrlDecrypt::decrypt($ccbParamSJ, $config['service_id']);
$config = include $configFile;
if (!$decryptedParams) {
$this->error('参数解密失败');
// 验证配置
if (empty($config['private_key'])) {
$this->error('配置错误private_key 为空');
}
Log::info('解密建行参数', [
'ccbParamSJ_length' => strlen($ccbParamSJ),
'service_id' => $config['service_id'],
'private_key_length' => strlen($config['private_key'])
]);
// 解密参数(使用服务方私钥)
$decryptedParams = CcbUrlDecrypt::decrypt($ccbParamSJ, $config['private_key']);
if ($decryptedParams === false || empty($decryptedParams)) {
// 检查日志文件获取详细错误
$logFile = RUNTIME_PATH . 'log/' . date('Ymd') . '.log';
$errorDetail = '';
if (file_exists($logFile)) {
$logContent = file_get_contents($logFile);
// 提取最后几行日志
$lines = explode("\n", $logContent);
$errorDetail = implode("\n", array_slice($lines, -10));
}
$this->error('参数解密失败,请查看日志: ' . $errorDetail);
}
// 返回解密后的数据
$this->success('解密成功', $decryptedParams);
} catch (\Exception $e) {
Log::error('建行参数解密失败: ' . $e->getMessage());
Log::error('建行参数解密失败', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
$this->error('解密失败: ' . $e->getMessage());
}
}

View File

@ -233,18 +233,19 @@ class Ccbtest extends Common
'提示' => '未提供ccbParamSJ参数无法进行实际解密测试',
'说明' => '请从建行App跳转时携带ccbParamSJ参数',
'服务方编号' => $config['service_id'],
'DES密钥前8位' => substr($config['service_id'], 0, 8),
'加密方式' => 'RSA使用服务方私钥解密',
'模拟数据' => $testParams
];
} else {
// 尝试解密
$decryptedParams = CcbUrlDecrypt::decrypt($ccbParamSJ, $config['service_id']);
// 尝试解密(使用服务方私钥)
$decryptedParams = CcbUrlDecrypt::decrypt($ccbParamSJ, $config['private_key']);
$result = [
'解密结果' => $decryptedParams ? '成功' : '失败',
'原始参数' => $ccbParamSJ,
'解密数据' => $decryptedParams,
'服务方编号' => $config['service_id']
'服务方编号' => $config['service_id'],
'加密方式' => 'RSA'
];
}

View File

@ -245,9 +245,9 @@ class CcbPaymentService
public function handleCallback($params)
{
try {
// 解密ccbParamSJ参数
// 解密ccbParamSJ参数(使用服务方私钥)
if (isset($params['ccbParamSJ'])) {
$decryptedParams = CcbUrlDecrypt::decrypt($params['ccbParamSJ'], $this->config['service_id']);
$decryptedParams = CcbUrlDecrypt::decrypt($params['ccbParamSJ'], $this->config['private_key']);
if ($decryptedParams) {
$params = array_merge($params, $decryptedParams);
}

View File

@ -4,50 +4,64 @@ namespace addons\shopro\library\ccblife;
/**
* 建行生活URL参数解密类
* 处理ccbParamSJ参数的DES解密
* 处理ccbParamSJ参数的RSA解密
*
* 解密流程URLDecode -> BASE64解码 -> RSA解密使用服务方私钥
*/
class CcbUrlDecrypt
{
/**
* 解密建行URL参数ccbParamSJ
* 流程:双层BASE64解码 -> DES解密
* 流程:URLDecode -> RSA解密使用服务方私钥内部会进行BASE64解码
*
* @param string $ccbParamSJ 加密的参数字符串
* @param string $serviceId 服务ID用于生成DES密钥
* @param string $ccbParamSJ 加密的参数字符串可能已经URLDecode
* @param string $privateKey 服务方私钥BASE64格式或PEM格式
* @return array|false 解密后的参数数组失败返回false
*/
public static function decrypt($ccbParamSJ, $serviceId)
public static function decrypt($ccbParamSJ, $privateKey)
{
try {
// 第一次BASE64解码
$firstDecode = base64_decode($ccbParamSJ);
if ($firstDecode === false) {
throw new \Exception('第一次BASE64解码失败');
// 调试日志
trace('开始解密建行参数RSA方式', 'info');
trace('ccbParamSJ 长度: ' . strlen($ccbParamSJ), 'info');
// 验证输入
if (empty($ccbParamSJ)) {
throw new \Exception('ccbParamSJ 参数为空');
}
// 第二次BASE64解码
$secondDecode = base64_decode($firstDecode);
if ($secondDecode === false) {
throw new \Exception('第二次BASE64解码失败');
if (empty($privateKey)) {
throw new \Exception('privateKey 为空');
}
// 获取DES密钥服务ID前8位
$desKey = substr($serviceId, 0, 8);
// URLDecode如果还没有解码
$urlDecoded = urldecode($ccbParamSJ);
trace('URLDecode后长度: ' . strlen($urlDecoded), 'info');
// DES解密
$decrypted = self::desDecrypt($secondDecode, $desKey);
if ($decrypted === false) {
throw new \Exception('DES解密失败');
// RSA解密CcbRSA::decrypt内部会自动进行BASE64解码
$decrypted = CcbRSA::decrypt($urlDecoded, $privateKey);
if ($decrypted === false || empty($decrypted)) {
throw new \Exception('RSA解密失败');
}
trace('RSA解密成功长度: ' . strlen($decrypted), 'info');
trace('解密内容: ' . $decrypted, 'info');
// 解析参数字符串为数组
parse_str($decrypted, $params);
if (empty($params)) {
throw new \Exception('解析参数失败,结果为空');
}
trace('参数解析成功: ' . json_encode($params, JSON_UNESCAPED_UNICODE), 'info');
return $params;
} catch (\Exception $e) {
// 记录错误日志
trace('建行URL参数解密失败: ' . $e->getMessage(), 'error');
trace('错误堆栈: ' . $e->getTraceAsString(), 'error');
return false;
}
}
@ -56,6 +70,8 @@ class CcbUrlDecrypt
* DES解密
* 使用ECB模式PKCS5Padding填充
*
* 兼容OpenSSL 3.x优先使用phpseclib库
*
* @param string $encryptedData 加密的数据
* @param string $key 密钥8字节
* @return string|false 解密后的数据失败返回false
@ -64,25 +80,54 @@ class CcbUrlDecrypt
{
// 确保密钥长度为8字节
if (strlen($key) !== 8) {
trace('DES密钥长度必须为8字节当前: ' . strlen($key), 'error');
return false;
}
// 使用openssl进行DES解密
$decrypted = openssl_decrypt(
$encryptedData,
'DES-ECB',
$key,
OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING
);
// 方法1: 尝试使用 phpseclib推荐兼容OpenSSL 3.x
if (class_exists('\phpseclib3\Crypt\DES')) {
try {
$cipher = new \phpseclib3\Crypt\DES('ecb');
$cipher->setKey($key);
$cipher->disablePadding(); // 手动处理填充
$decrypted = $cipher->decrypt($encryptedData);
if ($decrypted === false) {
return false;
if ($decrypted !== false && !empty($decrypted)) {
// 移除PKCS5填充
$result = self::removePKCS5Padding($decrypted);
if ($result !== false) {
trace('使用phpseclib解密成功', 'info');
return $result;
}
}
} catch (\Exception $e) {
trace('phpseclib解密失败: ' . $e->getMessage(), 'error');
}
}
// 移除PKCS5填充
$decrypted = self::removePKCS5Padding($decrypted);
// 方法2: 尝试使用 OpenSSLOpenSSL 3.x可能不支持
try {
$decrypted = @openssl_decrypt(
$encryptedData,
'DES-ECB',
$key,
OPENSSL_RAW_DATA
);
return $decrypted;
if ($decrypted !== false && !empty($decrypted)) {
// 移除PKCS5填充
$result = self::removePKCS5Padding($decrypted);
if ($result !== false) {
trace('使用OpenSSL解密成功', 'info');
return $result;
}
}
} catch (\Exception $e) {
trace('OpenSSL解密失败: ' . $e->getMessage(), 'error');
}
trace('所有DES解密方法都失败', 'error');
return false;
}
/**
@ -156,17 +201,32 @@ class CcbUrlDecrypt
* 移除PKCS5填充
*
* @param string $text 已填充的文本
* @return string 移除填充后的文本
* @return string|false 移除填充后的文本失败返回false
*/
private static function removePKCS5Padding($text)
{
$pad = ord($text[strlen($text) - 1]);
if ($pad > strlen($text)) {
// PHP 8 兼容性:检查空值
if (empty($text) || !is_string($text)) {
return false;
}
if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {
$textLength = strlen($text);
if ($textLength === 0) {
return false;
}
$pad = ord($text[$textLength - 1]);
// 验证填充值的合理性
if ($pad > $textLength || $pad > 8) {
return false;
}
// 验证所有填充字节是否一致
if (strspn($text, chr($pad), $textLength - $pad) != $pad) {
return false;
}
return substr($text, 0, -1 * $pad);
}

View File

@ -0,0 +1,74 @@
<?php
namespace addons\shopro\library\ccblife;
/**
* 纯PHP实现的DES加密/解密类
* 解决OpenSSL 3.x不支持DES算法的问题
*
* 算法DES-ECB模式PKCS5填充
*/
class PhpDes
{
/**
* DES解密
*
* @param string $data 加密的数据(二进制)
* @param string $key 密钥8字节
* @return string|false 解密后的数据
*/
public static function decrypt($data, $key)
{
// 使用mcrypt扩展如果可用
if (function_exists('mcrypt_decrypt')) {
$result = mcrypt_decrypt(MCRYPT_DES, $key, $data, MCRYPT_MODE_ECB);
return self::removePKCS5Padding($result);
}
// 尝试使用phpseclib库
if (class_exists('\phpseclib3\Crypt\DES')) {
$cipher = new \phpseclib3\Crypt\DES('ecb');
$cipher->setKey($key);
$cipher->disablePadding();
$result = $cipher->decrypt($data);
return self::removePKCS5Padding($result);
}
// 都不可用返回false
return false;
}
/**
* 移除PKCS5填充
*
* @param string $text 填充的文本
* @return string|false 移除填充后的文本
*/
private static function removePKCS5Padding($text)
{
if (empty($text) || !is_string($text)) {
return false;
}
$textLength = strlen($text);
if ($textLength === 0) {
return false;
}
$pad = ord($text[$textLength - 1]);
// 验证填充值的合理性
if ($pad > $textLength || $pad > 8 || $pad < 1) {
return false;
}
// 验证所有填充字节是否一致
for ($i = 0; $i < $pad; $i++) {
if (ord($text[$textLength - 1 - $i]) !== $pad) {
return false;
}
}
return substr($text, 0, -1 * $pad);
}
}

View File

@ -0,0 +1,152 @@
<?php
/**
* 建行参数解密测试脚本
*
* 用法:
* php addons/shopro/test/test_decrypt.php
*/
// 手动加载phpseclib避免触发FastAdmin/ThinkPHP初始化
spl_autoload_register(function ($class) {
$prefix = 'phpseclib3\\';
$base_dir = __DIR__ . '/../../../vendor/phpseclib/phpseclib/phpseclib/';
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
return;
}
$relative_class = substr($class, $len);
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
if (file_exists($file)) {
require $file;
}
});
echo "========================================\n";
echo " 建行参数解密测试工具\n";
echo "========================================\n\n";
// 测试参数来自你的URL
$ccbParamSJ = 'WmRMaDdYbUJ5MFl3Ymg5Wk8xL2xwL2k1WkxzMy9kRzdVbTZQMkNIVExudjAvZjRZcUQ1REVFR2JKalVKS3N2SDlzaEIrc3ljdkc3YnRVdE5WalRldlVQRWJSMEo0NndxSjZaMXVYYTlMMFhZRFJvdWcwb3lyL0t1dFEzcjdlOWwxaTBEamh5TS92SG5wOWN3S0Mzd1I2SXZPNnRZYS95bzlTZWVYT3BTVWJjU25JQ2JyUUp4WVdzam9zSXZnek5jKy9oVEwyN0wvQk1wUnJnRWtUdFM3NHdQd0txY3dNUXQ4SzRtMEhwTTc1UHRHcVpPTVRDRUpEVjR6RDdqUll2UURaN21yZnFDaG9od3RFUkhOcGNud2Nib2NjTDlsRjR4Rk44TWo4WmJFYzVqWWpYeHRENE1aMmJuMWY2RThuSVlVcVJBR096STllWm9JN1h1eG54RXhad2szalc3RWYvZHRkb1FZTEVRL3VzTHNkdWFBa0RVRURFaVRtSVVJY1R4dm5kODlYODVnV3JvR1pOY2N1aXhVdXBSYzJBYWlUSk81WG9EeGRkei9QVTVoMEJLNUZTK3MwNWRmTk9jbU5jcTB5SWdLWWMwbkxGem9nMVVscHc4bzVKRzNDWEFvTksyam1kT1k5Z04yQjRJc2RneVhhQ1V5QnNrSGJUSmt0VU8=';
echo "输入参数:\n";
echo "ccbParamSJ 长度: " . strlen($ccbParamSJ) . "\n\n";
// 从.env文件读取Service ID
$envFile = __DIR__ . '/../../../.env';
$serviceId = 'YS44000009001853'; // 默认值
if (file_exists($envFile)) {
$envContent = file_get_contents($envFile);
if (preg_match('/service_id\s*=\s*(.+)/i', $envContent, $matches)) {
$serviceId = trim($matches[1]);
}
}
echo "Service ID: {$serviceId}\n";
echo "DES密钥(前8位): " . substr($serviceId, 0, 8) . "\n\n";
// 执行解密
echo "========================================\n";
echo "开始解密...\n";
echo "========================================\n\n";
try {
// 第一次 BASE64 解码
echo "步骤1: 第一次BASE64解码\n";
$firstDecode = base64_decode($ccbParamSJ);
if ($firstDecode === false) {
die("错误: 第一次BASE64解码失败\n");
}
echo " 解码成功,长度: " . strlen($firstDecode) . "\n";
echo " 内容预览: " . substr($firstDecode, 0, 50) . "...\n\n";
// 第二次 BASE64 解码
echo "步骤2: 第二次BASE64解码\n";
$secondDecode = base64_decode($firstDecode);
if ($secondDecode === false) {
die("错误: 第二次BASE64解码失败\n");
}
echo " 解码成功,长度: " . strlen($secondDecode) . "\n";
echo " 十六进制预览: " . bin2hex(substr($secondDecode, 0, 32)) . "...\n\n";
// DES 解密
echo "步骤3: DES解密尝试不同的密钥\n";
// 使用phpseclib进行DES-ECB解密
if (!class_exists('\phpseclib3\Crypt\DES')) {
die("错误: phpseclib未安装请运行: composer require phpseclib/phpseclib\n");
}
// 尝试不同的密钥
$possibleKeys = [
substr($serviceId, 0, 8), // serviceId前8位
substr($serviceId, -8), // serviceId后8位
'YS440000', // 固定密钥
'12345678', // 测试密钥
];
$decrypted = false;
$validKey = '';
foreach ($possibleKeys as $testKey) {
echo " 尝试密钥: {$testKey}\n";
$cipher = new \phpseclib3\Crypt\DES('ecb');
$cipher->setKey($testKey);
$cipher->disablePadding();
$result = $cipher->decrypt($secondDecode);
// 验证解密结果是否合理(检查是否包含可见字符)
if ($result !== false && !empty($result)) {
// 尝试移除填充
$textLength = strlen($result);
$pad = ord($result[$textLength - 1]);
// 填充值应该在1-8之间
if ($pad >= 1 && $pad <= 8) {
$unpadded = substr($result, 0, -1 * $pad);
// 检查是否像URL参数包含=或&
if (strpos($unpadded, '=') !== false || strpos($unpadded, '&') !== false) {
$decrypted = $unpadded;
$validKey = $testKey;
echo " ✓ 找到正确密钥!\n";
break;
}
}
}
}
if ($decrypted === false || empty($decrypted)) {
die("\n错误: 所有密钥都无法正确解密\n");
}
$desKey = $validKey;
echo " 解密成功,长度: " . strlen($decrypted) . "\n";
echo " 解密内容: {$decrypted}\n\n";
// 解析参数
echo "步骤4: 解析参数\n";
parse_str($decrypted, $params);
echo " 解析结果:\n";
foreach ($params as $key => $value) {
echo " {$key} = {$value}\n";
}
echo "\n========================================\n";
echo "✅ 解密成功!\n";
echo "========================================\n";
} catch (\Exception $e) {
echo "\n========================================\n";
echo "❌ 解密失败!\n";
echo "========================================\n";
echo "错误信息: " . $e->getMessage() . "\n";
echo "错误行号: " . $e->getLine() . "\n";
echo "错误文件: " . $e->getFile() . "\n";
}

View File

@ -29,7 +29,8 @@
"ext-json": "*",
"ext-curl": "*",
"ext-pdo": "*",
"ext-bcmath": "*"
"ext-bcmath": "*",
"phpseclib/phpseclib": "*"
},
"config": {
"preferred-install": "dist",

View File

@ -26,12 +26,23 @@ use Composer\Semver\VersionParser;
*/
class InstalledVersions
{
/**
* @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to
* @internal
*/
private static $selfDir = null;
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
/**
* @var bool
*/
private static $installedIsLocalDir;
/**
* @var bool|null
*/
@ -309,6 +320,24 @@ class InstalledVersions
{
self::$installed = $data;
self::$installedByVendor = array();
// when using reload, we disable the duplicate protection to ensure that self::$installed data is
// always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
// so we have to assume it does not, and that may result in duplicate data being returned when listing
// all installed packages for example
self::$installedIsLocalDir = false;
}
/**
* @return string
*/
private static function getSelfDir()
{
if (self::$selfDir === null) {
self::$selfDir = strtr(__DIR__, '\\', '/');
}
return self::$selfDir;
}
/**
@ -322,19 +351,27 @@ class InstalledVersions
}
$installed = array();
$copiedLocalDir = false;
if (self::$canGetVendors) {
$selfDir = self::getSelfDir();
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
$vendorDir = strtr($vendorDir, '\\', '/');
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
$installed[] = self::$installedByVendor[$vendorDir] = $required;
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $installed[count($installed) - 1];
self::$installedByVendor[$vendorDir] = $required;
$installed[] = $required;
if (self::$installed === null && $vendorDir.'/composer' === $selfDir) {
self::$installed = $required;
self::$installedIsLocalDir = true;
}
}
if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) {
$copiedLocalDir = true;
}
}
}
@ -350,7 +387,7 @@ class InstalledVersions
}
}
if (self::$installed !== array()) {
if (self::$installed !== array() && !$copiedLocalDir) {
$installed[] = self::$installed;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
<?php return array(
'root' => array(
'name' => 'fastadminnet/fastadmin',
'pretty_version' => '1.x-dev',
'version' => '1.9999999.9999999.9999999-dev',
'reference' => '87d4163a8906dafb45f487ff71e7d40905ac704b',
'pretty_version' => 'dev-main',
'version' => 'dev-main',
'reference' => '48dbc5f4e4de8bfcd104300fbc5b2d1575469204',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@ -29,72 +29,72 @@
'dev_requirement' => false,
),
'ezyang/htmlpurifier' => array(
'pretty_version' => 'v4.18.0',
'version' => '4.18.0.0',
'reference' => 'cb56001e54359df7ae76dc522d08845dc741621b',
'pretty_version' => 'v4.19.0',
'version' => '4.19.0.0',
'reference' => 'b287d2a16aceffbf6e0295559b39662612b77fcf',
'type' => 'library',
'install_path' => __DIR__ . '/../ezyang/htmlpurifier',
'aliases' => array(),
'dev_requirement' => false,
),
'fastadminnet/fastadmin' => array(
'pretty_version' => '1.x-dev',
'version' => '1.9999999.9999999.9999999-dev',
'reference' => '87d4163a8906dafb45f487ff71e7d40905ac704b',
'pretty_version' => 'dev-main',
'version' => 'dev-main',
'reference' => '48dbc5f4e4de8bfcd104300fbc5b2d1575469204',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev_requirement' => false,
),
'fastadminnet/fastadmin-addons' => array(
'pretty_version' => '1.4.1',
'version' => '1.4.1.0',
'reference' => 'f98418b69fbdd07569ee97d9fd4a83dfd7fdc770',
'pretty_version' => '1.4.3',
'version' => '1.4.3.0',
'reference' => 'b7e371254f97fae7e9232984a746ffa58b64504e',
'type' => 'library',
'install_path' => __DIR__ . '/../fastadminnet/fastadmin-addons',
'aliases' => array(),
'dev_requirement' => false,
),
'fastadminnet/fastadmin-mailer' => array(
'pretty_version' => 'v2.1.0',
'version' => '2.1.0.0',
'reference' => '99b7369406d52c35cf4c9c38b0322b6846ca227a',
'pretty_version' => 'v2.1.1',
'version' => '2.1.1.0',
'reference' => 'bca635ac5f564ed6688d818d215021ffb0813746',
'type' => 'library',
'install_path' => __DIR__ . '/../fastadminnet/fastadmin-mailer',
'aliases' => array(),
'dev_requirement' => false,
),
'guzzlehttp/guzzle' => array(
'pretty_version' => '7.9.3',
'version' => '7.9.3.0',
'reference' => '7b2f29fe81dc4da0ca0ea7d42107a0845946ea77',
'pretty_version' => '7.10.0',
'version' => '7.10.0.0',
'reference' => 'b51ac707cfa420b7bfd4e4d5e510ba8008e822b4',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/guzzle',
'aliases' => array(),
'dev_requirement' => false,
),
'guzzlehttp/promises' => array(
'pretty_version' => '2.2.0',
'version' => '2.2.0.0',
'reference' => '7c69f28996b0a6920945dd20b3857e499d9ca96c',
'pretty_version' => '2.3.0',
'version' => '2.3.0.0',
'reference' => '481557b130ef3790cf82b713667b43030dc9c957',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/promises',
'aliases' => array(),
'dev_requirement' => false,
),
'guzzlehttp/psr7' => array(
'pretty_version' => '2.7.1',
'version' => '2.7.1.0',
'reference' => 'c2270caaabe631b3b44c85f99e5a04bbb8060d16',
'pretty_version' => '2.8.0',
'version' => '2.8.0.0',
'reference' => '21dc724a0583619cd1652f673303492272778051',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/psr7',
'aliases' => array(),
'dev_requirement' => false,
),
'maennchen/zipstream-php' => array(
'pretty_version' => '2.2.6',
'version' => '2.2.6.0',
'reference' => '30ad6f93cf3efe4192bc7a4c9cad11ff8f4f237f',
'pretty_version' => '3.1.2',
'version' => '3.1.2.0',
'reference' => 'aeadcf5c412332eb426c0f9b4485f6accba2a99f',
'type' => 'library',
'install_path' => __DIR__ . '/../maennchen/zipstream-php',
'aliases' => array(),
@ -127,15 +127,6 @@
'aliases' => array(),
'dev_requirement' => false,
),
'myclabs/php-enum' => array(
'pretty_version' => '1.8.5',
'version' => '1.8.5.0',
'reference' => 'e7be26966b7398204a234f8673fdad5ac6277802',
'type' => 'library',
'install_path' => __DIR__ . '/../myclabs/php-enum',
'aliases' => array(),
'dev_requirement' => false,
),
'nelexa/zip' => array(
'pretty_version' => '4.0.2',
'version' => '4.0.2.0',
@ -172,15 +163,42 @@
'aliases' => array(),
'dev_requirement' => false,
),
'paragonie/constant_time_encoding' => array(
'pretty_version' => 'v3.1.3',
'version' => '3.1.3.0',
'reference' => 'd5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77',
'type' => 'library',
'install_path' => __DIR__ . '/../paragonie/constant_time_encoding',
'aliases' => array(),
'dev_requirement' => false,
),
'paragonie/random_compat' => array(
'pretty_version' => 'v9.99.100',
'version' => '9.99.100.0',
'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a',
'type' => 'library',
'install_path' => __DIR__ . '/../paragonie/random_compat',
'aliases' => array(),
'dev_requirement' => false,
),
'phpoffice/phpspreadsheet' => array(
'pretty_version' => '1.29.10',
'version' => '1.29.10.0',
'reference' => 'c80041b1628c4f18030407134fe88303661d4e4e',
'pretty_version' => '1.30.0',
'version' => '1.30.0.0',
'reference' => '2f39286e0136673778b7a142b3f0d141e43d1714',
'type' => 'library',
'install_path' => __DIR__ . '/../phpoffice/phpspreadsheet',
'aliases' => array(),
'dev_requirement' => false,
),
'phpseclib/phpseclib' => array(
'pretty_version' => '3.0.47',
'version' => '3.0.47.0',
'reference' => '9d6ca36a6c2dd434765b1071b2644a1c683b385d',
'type' => 'library',
'install_path' => __DIR__ . '/../phpseclib/phpseclib',
'aliases' => array(),
'dev_requirement' => false,
),
'pimple/pimple' => array(
'pretty_version' => 'v3.5.0',
'version' => '3.5.0.0',
@ -191,9 +209,9 @@
'dev_requirement' => false,
),
'psr/cache' => array(
'pretty_version' => '1.0.1',
'version' => '1.0.1.0',
'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8',
'pretty_version' => '2.0.0',
'version' => '2.0.0.0',
'reference' => '213f9dbc5b9bfbc4f8db86d2838dc968752ce13b',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/cache',
'aliases' => array(),
@ -260,9 +278,9 @@
),
),
'psr/http-message' => array(
'pretty_version' => '1.1',
'version' => '1.1.0.0',
'reference' => 'cb6ce4845ce34a8ad9e68117c10ee90a29919eba',
'pretty_version' => '2.0',
'version' => '2.0.0.0',
'reference' => '402d35bcb92c70c026d1a6a9883f06b2ead23d71',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-message',
'aliases' => array(),
@ -338,9 +356,9 @@
),
),
'symfony/deprecation-contracts' => array(
'pretty_version' => 'v2.5.4',
'version' => '2.5.4.0',
'reference' => '605389f2a7e5625f273b53960dc46aeaf9c62918',
'pretty_version' => 'v3.6.0',
'version' => '3.6.0.0',
'reference' => '63afe740e99a13ba87ec199bb07bbdee937a5b62',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/deprecation-contracts',
'aliases' => array(),
@ -356,9 +374,9 @@
'dev_requirement' => false,
),
'symfony/event-dispatcher-contracts' => array(
'pretty_version' => 'v2.5.4',
'version' => '2.5.4.0',
'reference' => 'e0fe3d79b516eb75126ac6fa4cbf19b79b08c99f',
'pretty_version' => 'v3.6.0',
'version' => '3.6.0.0',
'reference' => '59eb412e93815df44f05f342958efa9f46b1e586',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/event-dispatcher-contracts',
'aliases' => array(),
@ -371,9 +389,9 @@
),
),
'symfony/finder' => array(
'pretty_version' => 'v5.4.45',
'version' => '5.4.45.0',
'reference' => '63741784cd7b9967975eec610b256eed3ede022b',
'pretty_version' => 'v7.3.2',
'version' => '7.3.2.0',
'reference' => '2a6614966ba1074fa93dae0bc804227422df4dfe',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/finder',
'aliases' => array(),
@ -389,17 +407,17 @@
'dev_requirement' => false,
),
'symfony/polyfill-mbstring' => array(
'pretty_version' => 'v1.31.0',
'version' => '1.31.0.0',
'reference' => '85181ba99b2345b0ef10ce42ecac37612d9fd341',
'pretty_version' => 'v1.33.0',
'version' => '1.33.0.0',
'reference' => '6d857f4d76bd4b343eac26d6b539585d2bc56493',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-php73' => array(
'pretty_version' => 'v1.31.0',
'version' => '1.31.0.0',
'pretty_version' => 'v1.33.0',
'version' => '1.33.0.0',
'reference' => '0f68c03565dcaaf25a890667542e8bd75fe7e5bb',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php73',
@ -407,9 +425,9 @@
'dev_requirement' => false,
),
'symfony/polyfill-php80' => array(
'pretty_version' => 'v1.31.0',
'version' => '1.31.0.0',
'reference' => '60328e362d4c2c802a54fcbf04f9d3fb892b4cf8',
'pretty_version' => 'v1.33.0',
'version' => '1.33.0.0',
'reference' => '0cc9dd0f17f61d8131e7df6b84bd344899fe2608',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
'aliases' => array(),
@ -425,18 +443,18 @@
'dev_requirement' => false,
),
'symfony/service-contracts' => array(
'pretty_version' => 'v1.1.2',
'version' => '1.1.2.0',
'reference' => '191afdcb5804db960d26d8566b7e9a2843cab3a0',
'pretty_version' => 'v3.6.0',
'version' => '3.6.0.0',
'reference' => 'f021b05a130d35510bd6b25fe9053c2a8a15d5d4',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/service-contracts',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/var-exporter' => array(
'pretty_version' => 'v5.4.45',
'version' => '5.4.45.0',
'reference' => '862700068db0ddfd8c5b850671e029a90246ec75',
'pretty_version' => 'v6.4.26',
'version' => '6.4.26.0',
'reference' => '466fcac5fa2e871f83d31173f80e9c2684743bfc',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/var-exporter',
'aliases' => array(),

0
vendor/ezyang/htmlpurifier/CREDITS vendored Executable file → Normal file
View File

0
vendor/ezyang/htmlpurifier/LICENSE vendored Executable file → Normal file
View File

0
vendor/ezyang/htmlpurifier/README.md vendored Executable file → Normal file
View File

2
vendor/ezyang/htmlpurifier/VERSION vendored Executable file → Normal file
View File

@ -1 +1 @@
4.18.0
4.19.0

2
vendor/ezyang/htmlpurifier/composer.json vendored Executable file → Normal file
View File

@ -13,7 +13,7 @@
}
],
"require": {
"php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
"php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
},
"require-dev": {
"cerdic/css-tidy": "^1.7 || ^2.0",

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier.auto.php vendored Executable file → Normal file
View File

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier.autoload-legacy.php vendored Executable file → Normal file
View File

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier.autoload.php vendored Executable file → Normal file
View File

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier.composer.php vendored Executable file → Normal file
View File

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier.func.php vendored Executable file → Normal file
View File

2
vendor/ezyang/htmlpurifier/library/HTMLPurifier.includes.php vendored Executable file → Normal file
View File

@ -7,7 +7,7 @@
* primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS
* FILE, changes will be overwritten the next time the script is run.
*
* @version 4.18.0
* @version 4.19.0
*
* @warning
* You must *not* include any other HTML Purifier files before this file,

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier.kses.php vendored Executable file → Normal file
View File

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier.path.php vendored Executable file → Normal file
View File

6
vendor/ezyang/htmlpurifier/library/HTMLPurifier.php vendored Executable file → Normal file
View File

@ -19,7 +19,7 @@
*/
/*
HTML Purifier 4.18.0 - Standards Compliant HTML Filtering
HTML Purifier 4.19.0 - Standards Compliant HTML Filtering
Copyright (C) 2006-2008 Edward Z. Yang
This library is free software; you can redistribute it and/or
@ -58,12 +58,12 @@ class HTMLPurifier
* Version of HTML Purifier.
* @type string
*/
public $version = '4.18.0';
public $version = '4.19.0';
/**
* Constant with version of HTML Purifier.
*/
const VERSION = '4.18.0';
const VERSION = '4.19.0';
/**
* Global configuration object.

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier.safe-includes.php vendored Executable file → Normal file
View File

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier/Arborize.php vendored Executable file → Normal file
View File

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrCollections.php vendored Executable file → Normal file
View File

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrDef.php vendored Executable file → Normal file
View File

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrDef/CSS.php vendored Executable file → Normal file
View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

@ -195,7 +195,7 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
// transforms don't pose a security risk (as \\ and \"
// might--these escapes are not supported by most browsers).
// We could try to be clever and use single-quote wrapping
// when there is a double quote present, but I have choosen
// when there is a double quote present, but I have chosen
// not to implement that. (NOTE: you can reduce the amount
// of escapes by one depending on what quoting style you use)
// $font = str_replace('\\', '\\5C ', $font);

View File

View File

View File

View File

View File

View File

View File

View File

View File

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/URI.php vendored Executable file → Normal file
View File

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrDef/Clone.php vendored Executable file → Normal file
View File

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrDef/Enum.php vendored Executable file → Normal file
View File

View File

View File

View File

View File

View File

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrDef/HTML/ID.php vendored Executable file → Normal file
View File

View File

View File

@ -25,12 +25,7 @@ class HTMLPurifier_AttrDef_HTML_LinkTypes extends HTMLPurifier_AttrDef
'rev' => 'AllowedRev'
);
if (!isset($configLookup[$name])) {
trigger_error(
'Unrecognized attribute name for link ' .
'relationship.',
E_USER_ERROR
);
return;
throw new Exception('Unrecognized attribute name for link relationship.');
}
$this->name = $configLookup[$name];
}

View File

View File

View File

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrDef/Integer.php vendored Executable file → Normal file
View File

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrDef/Lang.php vendored Executable file → Normal file
View File

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrDef/Switch.php vendored Executable file → Normal file
View File

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrDef/Text.php vendored Executable file → Normal file
View File

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrDef/URI.php vendored Executable file → Normal file
View File

View File

View File

View File

View File

View File

@ -37,7 +37,7 @@ class HTMLPurifier_AttrDef_URI_IPv6 extends HTMLPurifier_AttrDef_URI_IPv4
}
}
// IPv4-compatiblity check
// IPv4-compatibility check
if (preg_match('#(?<=:' . ')' . $this->ip4 . '$#s', $aIP, $find)) {
$aIP = substr($aIP, 0, 0 - strlen($find[0]));
$ip = explode('.', $find[0]);

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrTransform.php vendored Executable file → Normal file
View File

View File

View File

@ -3,7 +3,7 @@
// this MUST be placed in post, as it assumes that any value in dir is valid
/**
* Post-trasnform that ensures that bdo tags have the dir attribute set.
* Post-transform that ensures that bdo tags have the dir attribute set.
*/
class HTMLPurifier_AttrTransform_BdoDir extends HTMLPurifier_AttrTransform
{

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

2
vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrTypes.php vendored Executable file → Normal file
View File

@ -77,7 +77,7 @@ class HTMLPurifier_AttrTypes
}
if (!isset($this->info[$type])) {
trigger_error('Cannot retrieve undefined attribute type ' . $type, E_USER_ERROR);
throw new Exception('Cannot retrieve undefined attribute type ' . $type);
return;
}
return $this->info[$type]->make($string);

2
vendor/ezyang/htmlpurifier/library/HTMLPurifier/AttrValidator.php vendored Executable file → Normal file
View File

@ -135,7 +135,7 @@ class HTMLPurifier_AttrValidator
// we'd also want slightly more complicated substitution
// involving an array as the return value,
// although we're not sure how colliding attributes would
// resolve (certain ones would be completely overriden,
// resolve (certain ones would be completely overridden,
// others would prepend themselves).
}

2
vendor/ezyang/htmlpurifier/library/HTMLPurifier/Bootstrap.php vendored Executable file → Normal file
View File

@ -5,7 +5,7 @@ if (!defined('HTMLPURIFIER_PREFIX')) {
define('HTMLPURIFIER_PREFIX', realpath(dirname(__FILE__) . '/..'));
}
// accomodations for versions earlier than 5.0.2
// accommodations for versions earlier than 5.0.2
// borrowed from PHP_Compat, LGPL licensed, by Aidan Lister <aidan@php.net>
if (!defined('PHP_EOL')) {
switch (strtoupper(substr(PHP_OS, 0, 3))) {

5
vendor/ezyang/htmlpurifier/library/HTMLPurifier/CSSDefinition.php vendored Executable file → Normal file
View File

@ -26,6 +26,11 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
false
);
$this->info['direction'] = new HTMLPurifier_AttrDef_Enum(
['ltr', 'rtl'],
false
);
$border_style =
$this->info['border-bottom-style'] =
$this->info['border-right-style'] =

0
vendor/ezyang/htmlpurifier/library/HTMLPurifier/ChildDef.php vendored Executable file → Normal file
View File

Some files were not shown because too many files have changed in this diff Show More