1.修复上传漏洞和SQL注入漏洞-增强登录验证功能
This commit is contained in:
@@ -7,122 +7,171 @@ namespace ba;
|
||||
*/
|
||||
class Version
|
||||
{
|
||||
private const VERSION_COMMANDS = [
|
||||
'npm' => 'npm -v',
|
||||
'cnpm' => 'cnpm -v',
|
||||
'yarn' => 'yarn -v',
|
||||
'pnpm' => 'pnpm -v',
|
||||
'node' => 'node -v',
|
||||
];
|
||||
|
||||
/**
|
||||
* 比较两个版本号
|
||||
* @param string $v1 要求的版本号
|
||||
* @param bool|string $v2 被比较版本号
|
||||
* @return bool 是否达到要求的版本号
|
||||
*/
|
||||
public static function compare(string $v1, bool|string $v2): bool
|
||||
{
|
||||
if (!$v2) {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* 比较两个版本号
|
||||
* @param string $v1 要求的版本号
|
||||
* @param bool|string $v2 被比较版本号
|
||||
* @return bool 是否达到要求的版本号
|
||||
*/
|
||||
public static function compare(string $v1, bool|string $v2): bool
|
||||
{
|
||||
if (!$v2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strtolower($v1[0]) == 'v') {
|
||||
$v1 = substr($v1, 1);
|
||||
}
|
||||
if (strtolower($v2[0]) == 'v') {
|
||||
$v2 = substr($v2, 1);
|
||||
}
|
||||
if (strtolower($v1[0]) == 'v') {
|
||||
$v1 = substr($v1, 1);
|
||||
}
|
||||
if (strtolower($v2[0]) == 'v') {
|
||||
$v2 = substr($v2, 1);
|
||||
}
|
||||
|
||||
if ($v1 == "*" || $v1 == $v2) {
|
||||
return true;
|
||||
}
|
||||
if ($v1 == "*" || $v1 == $v2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (str_contains($v1, '-')) $v1 = explode('-', $v1)[0];
|
||||
if (str_contains($v2, '-')) $v2 = explode('-', $v2)[0];
|
||||
if (str_contains($v1, '-')) $v1 = explode('-', $v1)[0];
|
||||
if (str_contains($v2, '-')) $v2 = explode('-', $v2)[0];
|
||||
|
||||
$v1 = explode('.', $v1);
|
||||
$v2 = explode('.', $v2);
|
||||
$v1 = explode('.', $v1);
|
||||
$v2 = explode('.', $v2);
|
||||
|
||||
for ($i = 0; $i < count($v1); $i++) {
|
||||
if (!isset($v2[$i])) {
|
||||
break;
|
||||
}
|
||||
if ($v1[$i] == $v2[$i]) {
|
||||
continue;
|
||||
}
|
||||
if ($v1[$i] > $v2[$i]) {
|
||||
return false;
|
||||
}
|
||||
if ($v1[$i] < $v2[$i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (count($v1) != count($v2)) {
|
||||
return !(count($v1) > count($v2));
|
||||
}
|
||||
for ($i = 0; $i < count($v1); $i++) {
|
||||
if (!isset($v2[$i])) {
|
||||
break;
|
||||
}
|
||||
if ($v1[$i] == $v2[$i]) {
|
||||
continue;
|
||||
}
|
||||
if ($v1[$i] > $v2[$i]) {
|
||||
return false;
|
||||
}
|
||||
if ($v1[$i] < $v2[$i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (count($v1) != count($v2)) {
|
||||
return !(count($v1) > count($v2));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是一个数字版本号
|
||||
* @param $version
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkDigitalVersion($version): bool
|
||||
{
|
||||
if (!$version) {
|
||||
return false;
|
||||
}
|
||||
if (strtolower($version[0]) == 'v') {
|
||||
$version = substr($version, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是一个数字版本号
|
||||
* @param $version
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkDigitalVersion($version): bool
|
||||
{
|
||||
if (!$version) {
|
||||
return false;
|
||||
}
|
||||
if (strtolower($version[0]) == 'v') {
|
||||
$version = substr($version, 1);
|
||||
}
|
||||
$rule1 = '/\.{2,10}/';
|
||||
$rule2 = '/^\d+(\.\d+){0,10}$/';
|
||||
if (!preg_match($rule1, (string)$version)) {
|
||||
return !!preg_match($rule2, (string)$version);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
$rule1 = '/\.{2,10}/';
|
||||
$rule2 = '/^\d+(\.\d+){0,10}$/';
|
||||
if (!preg_match($rule1, (string)$version)) {
|
||||
return !!preg_match($rule2, (string)$version);
|
||||
}
|
||||
return false;
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getCnpmVersion(): string
|
||||
{
|
||||
$execOut = self::getOutputFromProc('cnpm');
|
||||
if ($execOut) {
|
||||
$preg = '/cnpm@(.+?) \(/is';
|
||||
preg_match($preg, $execOut, $result);
|
||||
return $result[1] ?? '';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取依赖版本号
|
||||
* @param string $name 支持:npm、cnpm、yarn、pnpm、node
|
||||
* @return string
|
||||
*/
|
||||
public static function getVersion(string $name): string
|
||||
{
|
||||
if ($name == 'cnpm') {
|
||||
return self::getCnpmVersion();
|
||||
}
|
||||
if (!in_array($name, ['npm', 'yarn', 'pnpm', 'node'])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getCnpmVersion(): string
|
||||
{
|
||||
$execOut = Terminal::getOutputFromProc('version.cnpm');
|
||||
if ($execOut) {
|
||||
$preg = '/cnpm@(.+?) \(/is';
|
||||
preg_match($preg, $execOut, $result);
|
||||
return $result[1] ?? '';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
$execOut = self::getOutputFromProc($name);
|
||||
if (!$execOut) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取依赖版本号
|
||||
* @param string $name 支持:npm、cnpm、yarn、pnpm、node
|
||||
* @return string
|
||||
*/
|
||||
public static function getVersion(string $name): string
|
||||
{
|
||||
if ($name == 'cnpm') {
|
||||
return self::getCnpmVersion();
|
||||
} elseif (in_array($name, ['npm', 'yarn', 'pnpm', 'node'])) {
|
||||
$execOut = Terminal::getOutputFromProc('version.' . $name);
|
||||
if ($execOut) {
|
||||
if (strripos($execOut, 'npm WARN') !== false) {
|
||||
$preg = '/\d+(\.\d+){0,2}/';
|
||||
preg_match($preg, $execOut, $matches);
|
||||
if (isset($matches[0]) && self::checkDigitalVersion($matches[0])) {
|
||||
return $matches[0];
|
||||
}
|
||||
}
|
||||
$execOut = preg_split('/\r\n|\r|\n/', $execOut);
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
if (isset($execOut[$i]) && self::checkDigitalVersion($execOut[$i])) {
|
||||
return $execOut[$i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
if (strripos($execOut, 'npm WARN') !== false) {
|
||||
$preg = '/\d+(\.\d+){0,2}/';
|
||||
preg_match($preg, $execOut, $matches);
|
||||
if (isset($matches[0]) && self::checkDigitalVersion($matches[0])) {
|
||||
return $matches[0];
|
||||
}
|
||||
}
|
||||
|
||||
$execOut = preg_split('/\r\n|\r|\n/', $execOut);
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
if (isset($execOut[$i]) && self::checkDigitalVersion($execOut[$i])) {
|
||||
return $execOut[$i];
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
private static function getOutputFromProc(string $name): bool|string
|
||||
{
|
||||
if (!function_exists('proc_open') || !function_exists('proc_close')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$command = self::VERSION_COMMANDS[$name] ?? '';
|
||||
if (!$command) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DIRECTORY_SEPARATOR === '\\') {
|
||||
$command = 'cmd /c "' . $command . '"';
|
||||
}
|
||||
|
||||
$descriptorsPec = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
|
||||
$process = proc_open($command, $descriptorsPec, $pipes, root_path(), null);
|
||||
if (!is_resource($process)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$info = stream_get_contents($pipes[1]);
|
||||
$info .= stream_get_contents($pipes[2]);
|
||||
fclose($pipes[1]);
|
||||
fclose($pipes[2]);
|
||||
proc_close($process);
|
||||
|
||||
return self::outputFilter($info);
|
||||
}
|
||||
|
||||
private static function outputFilter($str): string
|
||||
{
|
||||
$str = trim($str);
|
||||
$preg = '/\x1b\[(.*?)m/i';
|
||||
$str = preg_replace($preg, '', $str);
|
||||
$str = str_replace(["\r\n", "\r", "\n"], "\n", $str);
|
||||
return mb_convert_encoding($str, 'UTF-8', 'UTF-8,GBK,GB2312,BIG5');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user