MRBS 1.12.2 等保2.0二级整改完整提交

包含:登录失败锁定、90天密码有效期、30分钟会话超时、
强制改密、登录审计日志、屏幕水印、企业背景图、
备案信息固定底部、favicon、JS空集合保护、
会话过期体验优化(403 JSON)、display_errors 关闭、
固定 key 根治 Integrity check failed 等全部改动

注意:config.inc.php/.htaccess/.user.ini 含敏感信息,
通过 .gitignore 排除,勿推送到公开仓库。
This commit is contained in:
人事系统开发
2026-09-09 16:55:02 +08:00
commit 1ba6efd8ed
2151 changed files with 528780 additions and 0 deletions
+111
View File
@@ -0,0 +1,111 @@
<?php
declare(strict_types=1);
namespace MRBS\Intl;
class IntlDatePatternConverter
{
private const QUOTE_CHAR = "'";
private $formatter;
public function __construct(Formatter $formatter)
{
$this->formatter = $formatter;
}
public function convert(string $pattern) : string
{
// Parse the pattern
// See https://unicode-org.github.io/icu/userguide/format_parse/datetime/
// "Note: Any characters in the pattern that are not in the ranges of [a..z] and
// [A..Z] will be treated as quoted text. For instance, characters like ':', '.',
// ' ', '#' and '@' will appear in the resulting time text even they are not enclosed
// within single quotes. The single quote is used to escape letters. Two single
// quotes in a row, whether inside or outside a quoted sequence, represent a real
// single quote."
$format = '';
$token = '';
$token_char = null;
$in_quotes = false;
// Split the string into an array of multibyte characters
$chars = preg_split("//u", $pattern, 0, PREG_SPLIT_NO_EMPTY);
while (null !== ($char = array_shift($chars)))
{
$is_token_char = !$in_quotes && preg_match("/^[a-z]$/i", $char);
if ($is_token_char)
{
// The start of a token
if (!isset($token_char))
{
$token_char = $char;
$token = $char;
}
// The continuation of a token
elseif ($char === $token_char)
{
$token .= $char;
}
// The end of a token and the beginning of a new one
else
{
$format .= $this->formatter->convert($token);
$token_char = $char;
$token = $char;
}
}
// Check to see if a token has just ended, ie we've either got
// a non-token character or there are no more characters left.
if (($token !== '') && (!$is_token_char || empty($chars)))
{
$format .= $this->formatter->convert($token);
$token = '';
$token_char = null;
}
// Quoted text
if (!$is_token_char)
{
// If it's not a quote just add the character to the format
if ($char !== self::QUOTE_CHAR)
{
$format .= $this->formatter->escape($char);
}
// Otherwise we have to work out whether the quote is the start or end of a
// quoted sequence, or part of an escaped quote
else
{
// Get the next character
$char = array_shift($chars);
if (isset($char))
{
// If it is a quote then it's an escaped quote and add it to the format
if ($char === self::QUOTE_CHAR)
{
$format .= $this->formatter->escape($char);
}
// Otherwise it's either the start or end of a quoted section.
// Toggle $in_quotes and add the character to the format if we're in quotes,
// or else replace it so that it gets handled properly next time round.
else
{
$in_quotes = !$in_quotes;
if ($in_quotes)
{
$format .= $this->formatter->escape($char);
}
else
{
array_unshift($chars, $char);
}
}
}
}
}
}
return $format;
}
}