修复:图标存储未跟随后台配置,本地模式下图标显示不出来
用户指出图标应当与附件同一套逻辑:管理员在后台配 local 就存本机、 配 oss 就存 OSS,前台都一样走 media.php 代理。 原实现把图标键硬编码成 icons/…(不带存储前缀),导致: - fb_attach_is_local() 恒为 false - 本机模式下文件确实写进了 uploads/icons/, 但 media.php 把它当 OSS 对象去读 → 503,图标完全显示不出来 修法:图标键与附件完全同规则,只是路径里多一段 icons/ local 模式 → local/icons/YYYY/MM/<hex>.<ext> 落 uploads/icons/ oss 模式 → <oss.prefix>/icons/YYYY/MM/<hex>.<ext> 落私有桶 前台地址两种模式一致(media.php?k=…),换存储方式旧图标不会失效。 同时: - fb_icon_is_key/ok 改为同时识别两种前缀 - fb_icon_allowed_ext 移到 attach.php(media.php 与校验都会用, 不能依赖 admin_taxonomy.php 被加载) - 写入时加断言:键前缀必须与当前存储模式一致,脱钩就报错, 不再静默存到错误位置 验证(线上真实环境,两种模式各跑一遍): - local:键带 local/icons/ 前缀、写入 uploads/icons/ 成功、 media.php 读回 200 image/png 501B、PNG 魔数正确、删除后 404 - oss:键带 fb/icons/ 前缀、is_local=false、URL 拼接正确 - 旧 bug 形态(icons/… 无前缀)现在被明确拒绝 400,不再误判成 OSS - 测试后配置已复原为 oss,临时文件与诊断入口全部清理
This commit is contained in:
+12
-6
@@ -19,12 +19,8 @@ if (!defined('FB_ROOT')) { http_response_code(403); exit('forbidden'); }
|
||||
* 对外一律 media.php?k=... 代理,不暴露真实位置。
|
||||
* ================================================================== */
|
||||
|
||||
/** 图标允许的扩展名(比附件白名单窄:图标不需要 gif 动图,也不要 svg) */
|
||||
function fb_icon_allowed_ext() {
|
||||
// ⚠️ 刻意不收 svg:SVG 能内嵌 <script>,一旦被当图片直出到浏览器就是 XSS。
|
||||
// 图标是管理员自己传的,但防线不该依赖「管理员不会传坏东西」。
|
||||
return ['png', 'jpg', 'jpeg', 'webp'];
|
||||
}
|
||||
/** 图标允许的扩展名 —— 定义在 lib/attach.php(fb_icon_allowed_ext),
|
||||
* 因为 media.php 与 CLI 场景也会用到,不能依赖这个后台文件被加载。 */
|
||||
|
||||
/**
|
||||
* 保存一个上传的图标文件,返回 [bool ok, string 值(键或错误信息), string mime]。
|
||||
@@ -77,6 +73,16 @@ function fb_icon_store_upload(array $file) {
|
||||
|
||||
$key = fb_icon_make_key($ext);
|
||||
|
||||
/* 断言:键的前缀必须与当前存储方式一致。
|
||||
* 这两者一旦脱钩,就会出现「文件写进 uploads/ 但 media.php 去 OSS 找」的 503 ——
|
||||
* 早期把键硬编码成 icons/… 就是这么坏的。宁可当场报错,也不要静默存错位置。 */
|
||||
if ($mode === 'local' && !fb_attach_is_local($key)) {
|
||||
return [false, '内部错误:本地模式下生成了非本机路径的图标键。', ''];
|
||||
}
|
||||
if ($mode === 'oss' && fb_attach_is_local($key)) {
|
||||
return [false, '内部错误:OSS 模式下生成了本机路径的图标键。', ''];
|
||||
}
|
||||
|
||||
if ($mode === 'local') {
|
||||
if (!fb_local_writable()) { return [false, '本机附件目录不可写(uploads/),无法保存图标。', '']; }
|
||||
$path = fb_local_path_of($key);
|
||||
|
||||
Reference in New Issue
Block a user