fix(order): restrict V5Pay order prefix to letters
This commit is contained in:
parent
ac18a90da4
commit
8922491cbe
@ -43,11 +43,13 @@ public final class V5PayOrderNumber {
|
||||
}
|
||||
|
||||
private static String normalizedPrefix(String prefix) {
|
||||
String normalized = Objects.toString(prefix, "").trim().toUpperCase(Locale.ROOT);
|
||||
if (StringUtils.isBlank(normalized) || !isAsciiLettersOrDigits(normalized)) {
|
||||
String rawPrefix = Objects.toString(prefix, "").trim();
|
||||
// 无分隔符拼接时,前缀若包含数字会产生命名空间碰撞,例如 YUMI+123 与 YUMI1+23;
|
||||
// 必须在大小写转换前校验 ASCII,避免 Unicode 字母(如 dotless i)转换成 ASCII 后绕过限制。
|
||||
if (StringUtils.isBlank(rawPrefix) || !isAsciiLetters(rawPrefix)) {
|
||||
throw new IllegalArgumentException("V5Pay order prefix is invalid");
|
||||
}
|
||||
return normalized;
|
||||
return rawPrefix.toUpperCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
private static boolean isAsciiDigits(String value) {
|
||||
@ -60,11 +62,11 @@ public final class V5PayOrderNumber {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isAsciiLettersOrDigits(String value) {
|
||||
private static boolean isAsciiLetters(String value) {
|
||||
for (int index = 0; index < value.length(); index++) {
|
||||
char item = value.charAt(index);
|
||||
boolean letter = (item >= 'A' && item <= 'Z') || (item >= 'a' && item <= 'z');
|
||||
if (!letter && (item < '0' || item > '9')) {
|
||||
if (!letter) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,6 +48,19 @@ public class V5PayOrderNumberTest {
|
||||
assertIllegalArgument(() -> V5PayOrderNumber.providerOrderNo("YUMI", -1L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rejectsDigitBearingPrefixesThatCouldCollideWithoutSeparator() {
|
||||
assertEquals("YUMI123", V5PayOrderNumber.providerOrderNo("YUMI", 123L));
|
||||
|
||||
// YUMI1 + 23 会与合法的 YUMI + 123 生成同一个三方单号,因此数字不能出现在前缀任意位置。
|
||||
assertIllegalArgument(() -> V5PayOrderNumber.providerOrderNo("YUMI1", 23L));
|
||||
assertIllegalArgument(() -> V5PayOrderNumber.localOrderId("YUMI1", "YUMI123"));
|
||||
assertIllegalArgument(() -> V5PayOrderNumber.providerOrderNo("1YUMI", 23L));
|
||||
assertIllegalArgument(() -> V5PayOrderNumber.providerOrderNo("YU1MI", 23L));
|
||||
assertIllegalArgument(() -> V5PayOrderNumber.providerOrderNo("123", 23L));
|
||||
assertIllegalArgument(() -> V5PayOrderNumber.providerOrderNo("yumı", 23L));
|
||||
}
|
||||
|
||||
private void assertIllegalArgument(Runnable action) {
|
||||
try {
|
||||
action.run();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user