Xiuno BBS 审计之问题:缺 utf8mb4,Emoji 乱码
贰先生 6小时前

此文章为XIUNOX版本重构审计时发现问题,XIUNOX版本已优化修复此问题。分享出来方便后续想基于xiuno bbs4.0.4版本制作维护版本或插件模板等需求的开发者和站长参考。

现象

Xiuno BBS 4.0.4 默认使用 utf8(即 MySQL 的 utf8mb3)字符集连接数据库与建表,没有 utf8mb4 支持。MySQL 的 utf8 最多支持 3 字节字符,无法存储 Emoji 表情(如 )、部分生僻汉字(如 )、新增的 CJK 扩展区字符。这些字符入库时会被截断为 ? 或抛出 Incorrect string value 错误,导致帖子内容、用户名、签名等数据损坏。

源码证据

文件 xiunobbs_4.0.4/conf/conf.default.php 第 21、33 行:默认配置 charset 为 utf8(非 utf8mb4):

'mysql' => array (
    'master' => array (
        'host' => 'localhost',
        'user' => 'root',
        'password' => 'root',
        'name' => 'test',
        'tablepre' => 'bbs_',
        'charset' => 'utf8',         // <-- 应为 'utf8mb4'
        'engine' => 'innodb',
    ),
    'slaves' => array (),
),
'pdo_mysql' => array (
    'master' => array (
        ...
        'charset' => 'utf8',         // <-- 应为 'utf8mb4'
        'engine' => 'innodb',
    ),
    'slaves' => array (),
),

文件 xiunobbs_4.0.4/xiunophp/db_mysql.class.php 第 57 行:连接后通过 SET names $charset 设置连接字符集,但 $charset 来自 conf(即 utf8):

// 第 57 行
$charset AND $this->query("SET names $charset, sql_mode=''", $link);

文件 xiunobbs_4.0.4/xiunophp/xiunophp.min.php 第 39 行(压缩版同逻辑):

$charset AND $this->query("SET names $charset, sql_mode=''", $link);

文件 xiunobbs_4.0.4/xiunophp/db_pdo_mysql.class.php 第 28 行(PDO 驱动同样受影响):

$charset AND $link->query("SET names $charset, sql_mode=''");

文件 xiunobbs_4.0.4/install/install.sql(建表脚本,共 17 张表全部使用 CHARSET=utf8,无任何 utf8mb4):

-- 第 32 行
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;

-- 第 55, 92, 107, 134, 145, 166, 192, 200, 210, 229, 238, 255, 264, 273, 283, 301 行
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

全局搜索 utf8mb4 关键字:无任何匹配,证实整个项目(含配置、安装 SQL、迁移工具、驱动)从未支持 utf8mb4。

风险等级与结论

兼容障碍(数据损坏)。MySQL 8.0 起 utf8 默认别名指向 utf8mb3 并发出 deprecated 警告,未来版本将移除;现网用户在帖子/回复中粘贴 Emoji(iOS 输入法默认行为)会被静默截断。

危害:

  1. 帖子内容、帖子标题、用户名、用户签名中包含 Emoji 时,写入数据库被替换为 ? 或抛出 SQLSTATE[HY000]: General error: 1366 Incorrect string value,用户看到内容残缺。
  2. bbs_post.message 是 LONGTEXT,存储用户长文,Emoji 截断后无任何错误提示,导致数据不可逆损坏。
  3. MySQL 8.0+ 上 utf8 别名预警,未来 MySQL 版本(如 8.4+)可能彻底移除 utf8,届时建表失败。
  4. 与全文索引冲突:install.sql 第 32 行的 bbs_thread 表使用 MyISAM + FULLTEXT,若改为 utf8mb4,MyISAM 不支持 utf8mb4 全文索引,需同步改为 InnoDB + ngram。

修复建议:

  1. conf/conf.default.php 第 21、33 行 'charset' => 'utf8' 改为 'charset' => 'utf8mb4'
  2. install/install.sql 全部 17 处 CHARSET=utf8 COLLATE=utf8_general_ci 改为 CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci(或 utf8mb4_unicode_ci)。
  3. install/alter.sql 与各 tool/*_to_xn4.php 迁移工具补一条升级 SQL:ALTER TABLE bbs_xxx CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
  4.  bbs_thread 的 MyISAM FULLTEXT 改为 InnoDB + WITH PARSER ngram,否则 utf8mb4 下全文索引不可用。
  5. 同步修改 xiunophp.min.php(压缩版第 39 行附近)。
最新回复 (0)
全部楼主
返回