FatFs短名解析拒绝点加DEBUG打印并台架实证+AGENTS.md固化严格8.3命名约束
This commit is contained in:
+45
-5
@@ -23,6 +23,21 @@
|
||||
#include "ff.h" /* Declarations of FatFs API */
|
||||
#include "diskio.h" /* Declarations of device I/O functions */
|
||||
|
||||
/* 项目定制(2026-09-20,".fschk 无限重格式化"事故复盘):
|
||||
* FF_USE_LFN=0 时 f_open/f_create/f_unlink/f_mkdir 等一切文件 API
|
||||
* 最终都汇聚到 create_short() 做 8.3 短名解析——这是名字合法性的
|
||||
* 唯一咽喉点。在拒绝瞬间打印名字片段+原因,让"非法文件名"这类
|
||||
* 纯 RAM 判定错误从开机日志直接可见,不再需要拿错误码反查枚举表。
|
||||
* 注意:字符串字面量必须纯 ASCII(ARMCC 对无 BOM 文件按 CP936 解析)。 */
|
||||
#if FF_USE_LFN == 0
|
||||
#define DBG_TAG "[FATFS]"
|
||||
#include "dbg_log.h"
|
||||
#define FF_DBG_SFN_REJECT(why, seg, ch) \
|
||||
DBG_ERROR("SFN reject (%s) seg='%.24s' bad_ch=0x%02X" \
|
||||
" - strict 8.3 only: body<=8 ext<=3 no leading dot", \
|
||||
(why), (seg), (int)(ch))
|
||||
#endif
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@@ -2993,7 +3008,12 @@ static FRESULT create_name ( /* FR_OK: successful, FR_INVALID_NAME: could not cr
|
||||
if (c != '.' || si >= 3) break;
|
||||
sfn[i++] = c;
|
||||
}
|
||||
if (!IsSeparator(c) && c > ' ') return FR_INVALID_NAME;
|
||||
if (!IsSeparator(c) && c > ' ') {
|
||||
#if FF_USE_LFN == 0
|
||||
FF_DBG_SFN_REJECT("heading dot", p, c);
|
||||
#endif
|
||||
return FR_INVALID_NAME;
|
||||
}
|
||||
*path = p + si; /* Return pointer to the next segment */
|
||||
sfn[NSFLAG] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT; /* Set last segment flag if end of the path */
|
||||
return FR_OK;
|
||||
@@ -3007,7 +3027,12 @@ static FRESULT create_name ( /* FR_OK: successful, FR_INVALID_NAME: could not cr
|
||||
break;
|
||||
}
|
||||
if (c == '.' || i >= ni) { /* End of body or field overflow? */
|
||||
if (ni == 11 || c != '.') return FR_INVALID_NAME; /* Field overflow or invalid dot? */
|
||||
if (ni == 11 || c != '.') {
|
||||
#if FF_USE_LFN == 0
|
||||
FF_DBG_SFN_REJECT("ext overflow or bad dot", p, c);
|
||||
#endif
|
||||
return FR_INVALID_NAME; /* Field overflow or invalid dot? */
|
||||
}
|
||||
i = 8; ni = 11; /* Enter file extension field */
|
||||
continue;
|
||||
}
|
||||
@@ -3022,17 +3047,32 @@ static FRESULT create_name ( /* FR_OK: successful, FR_INVALID_NAME: could not cr
|
||||
#endif
|
||||
if (dbc_1st(c)) { /* Check if it is a DBC 1st byte */
|
||||
d = (BYTE)p[si++]; /* Get 2nd byte */
|
||||
if (!dbc_2nd(d) || i >= ni - 1) return FR_INVALID_NAME; /* Reject invalid DBC */
|
||||
if (!dbc_2nd(d) || i >= ni - 1) {
|
||||
#if FF_USE_LFN == 0
|
||||
FF_DBG_SFN_REJECT("invalid DBC", p, c);
|
||||
#endif
|
||||
return FR_INVALID_NAME; /* Reject invalid DBC */
|
||||
}
|
||||
sfn[i++] = c;
|
||||
sfn[i++] = d;
|
||||
} else { /* SBC */
|
||||
if (strchr("*+,:;<=>[]|\"\?\x7F", (int)c)) return FR_INVALID_NAME; /* Reject illegal chrs for SFN */
|
||||
if (strchr("*+,:;<=>[]|\"\?\x7F", (int)c)) {
|
||||
#if FF_USE_LFN == 0
|
||||
FF_DBG_SFN_REJECT("illegal char", p, c);
|
||||
#endif
|
||||
return FR_INVALID_NAME; /* Reject illegal chrs for SFN */
|
||||
}
|
||||
if (IsLower(c)) c -= 0x20; /* To upper */
|
||||
sfn[i++] = c;
|
||||
}
|
||||
}
|
||||
*path = &p[si]; /* Return pointer to the next segment */
|
||||
if (i == 0) return FR_INVALID_NAME; /* Reject nul string */
|
||||
if (i == 0) {
|
||||
#if FF_USE_LFN == 0
|
||||
FF_DBG_SFN_REJECT("empty name", p, c);
|
||||
#endif
|
||||
return FR_INVALID_NAME; /* Reject nul string */
|
||||
}
|
||||
|
||||
if (sfn[0] == DDEM) sfn[0] = RDDEM; /* If the first character collides with DDEM, replace it with RDDEM */
|
||||
sfn[NSFLAG] = (c <= ' ' || p[si] <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of the path */
|
||||
|
||||
Reference in New Issue
Block a user