|
@@ -409,7 +409,14 @@ public class LsyOnboardingService {
|
|
|
* <b>我们的护栏</b>,上游文档没提。</li>
|
|
* <b>我们的护栏</b>,上游文档没提。</li>
|
|
|
* <li><b>文件名不含 {@code /}、{@code \}、{@code ..}</b>。是**拒绝**、不是**清洗后照发** ——
|
|
* <li><b>文件名不含 {@code /}、{@code \}、{@code ..}</b>。是**拒绝**、不是**清洗后照发** ——
|
|
|
* 清洗会让日志里的名字与实际发出去的名字不一致:排障时看到的名字不是上游收到的那个,
|
|
* 清洗会让日志里的名字与实际发出去的名字不一致:排障时看到的名字不是上游收到的那个,
|
|
|
- * 那比直接拒更坏。<b>我们的护栏</b>。</li>
|
|
|
|
|
|
|
+ * 那比直接拒更坏。<b>我们的护栏</b>。
|
|
|
|
|
+ * ★ {@code ..} 这一支是**有意过宽**的近似,不是没想到 {@code a..jpg}:
|
|
|
|
|
+ * {@code /} 与 {@code \} 已被前一条拒掉,剩下的穿越 token 只有裸 {@code ..},
|
|
|
|
|
+ * 而上游拿到 {@code ..} 会怎么处理**我们未实测**。过宽的代价 = 「文件名里合法地含
|
|
|
|
|
+ * 连续两个点」被拒(用户看到一句中文 400,改个名即可);过窄的代价 = 一条我们
|
|
|
|
|
+ * **无据可判**的路径风险 ⇒ 方向取「宁可误拒」。
|
|
|
|
|
+ * 两条判断**分开写**,是为了让每条文案**对它自己的触发输入都为真** ——
|
|
|
|
|
+ * 对 {@code a..jpg} 说「文件名不能含路径分隔符」是**假话**。</li>
|
|
|
* <li><b>扩展名在白名单内</b>(比较前先转小写,故 {@code a.JPG} 通过):
|
|
* <li><b>扩展名在白名单内</b>(比较前先转小写,故 {@code a.JPG} 通过):
|
|
|
* {@link #ALLOWED_IMAGE_EXTENSIONS}。没有后缀({@code lastIndexOf} 为 -1)⇒ 空串
|
|
* {@link #ALLOWED_IMAGE_EXTENSIONS}。没有后缀({@code lastIndexOf} 为 -1)⇒ 空串
|
|
|
* ⇒ 不在白名单。<b>我们的收窄</b>。</li>
|
|
* ⇒ 不在白名单。<b>我们的收窄</b>。</li>
|
|
@@ -434,9 +441,15 @@ public class LsyOnboardingService {
|
|
|
throw new BusinessException(400, "图片文件名不能含控制字符");
|
|
throw new BusinessException(400, "图片文件名不能含控制字符");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- if (fileName.contains("/") || fileName.contains("\\") || fileName.contains("..")) {
|
|
|
|
|
|
|
+ if (fileName.contains("/") || fileName.contains("\\")) {
|
|
|
throw new BusinessException(400, "图片文件名不能含路径分隔符");
|
|
throw new BusinessException(400, "图片文件名不能含路径分隔符");
|
|
|
}
|
|
}
|
|
|
|
|
+ // ★ 与上一条分开写,是为了让**每条文案对它自己的触发输入都为真**:
|
|
|
|
|
+ // 对 `a..jpg` 说「文件名不能含路径分隔符」是**假话** —— `..` 不是分隔符。
|
|
|
|
|
+ // 两条合写成一条判断时行为完全相同,分开只是为了文案可陈述为真。
|
|
|
|
|
+ if (fileName.contains("..")) {
|
|
|
|
|
+ throw new BusinessException(400, "图片文件名不能含连续两个点(..)");
|
|
|
|
|
+ }
|
|
|
int dot = fileName.lastIndexOf('.');
|
|
int dot = fileName.lastIndexOf('.');
|
|
|
String ext = dot < 0 ? "" : fileName.substring(dot + 1);
|
|
String ext = dot < 0 ? "" : fileName.substring(dot + 1);
|
|
|
// Locale.ROOT:不跟随默认 locale。本白名单四个扩展名都不含字母 i,默认 locale 的
|
|
// Locale.ROOT:不跟随默认 locale。本白名单四个扩展名都不含字母 i,默认 locale 的
|