# 다섯 검사 public static String requireIdentifier(String value) { if (value == null || !IDENTIFIER.matcher(value).matches()) { throw new IllegalArgumentException( "identifier must be 1..128 characters of [A-Za-z0-9._~-] and must not contain a" + " key separator"); } String lowerCase = value.toLowerCase(Locale.ROOT); if (value.indexOf('@') >= 0) { throw new IllegalArgumentException("identifier must not contain a mail address"); } if (JSON_WEB_TOKEN.matcher(value).matches()) { throw new IllegalArgumentException("identifier must not contain a JSON web token"); } if (INTERNATIONAL_PHONE.matcher(value).matches()) { throw new IllegalArgumentException("identifier must not contain a phone number"); } if (lowerCase.startsWith("bearer") || lowerCase.startsWith("eyj")) { throw new IllegalArgumentException("identifier must not contain authentication material"); } return value; } # 검사가 쓰는 패턴 넷 private static final Pattern IDENTIFIER = Pattern.compile("^[A-Za-z0-9][A-Za-z0-9._~-]{0,127}$"); private static final Pattern JSON_WEB_TOKEN = Pattern.compile("^[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}$"); private static final Pattern INTERNATIONAL_PHONE = Pattern.compile("^\\+\\d[\\d.~-]{7,}$"); # 이 메서드에 값을 넣는 test 가 무엇을 단언하는가 @Test void rejectsEmailInIdentifier() { assertThatThrownBy(() -> new RedisKeyName("user", "person@example.com")) .isInstanceOf(IllegalArgumentException.class); } @Test void rejectsAuthenticationMaterialInIdentifier() { for (String forbidden : List.of( "eyJhbGciOiJIUzI1NiJ9", "bearer-abcdefabcdef", "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIn0.c2lnbmF0dXJlLXZhbHVl")) { assertThatThrownBy(() -> new RedisKeyName("session", forbidden)) .as("identifier '%s'", forbidden) .isInstanceOf(IllegalArgumentException.class); } } @Test void rejectsInternationalPhoneNumbersInIdentifier() { assertThatThrownBy(() -> new RedisKeyName("contact", "+821012345678")) .isInstanceOf(IllegalArgumentException.class); } @Test void rejectsSeparatorInjectionInEveryKeyPart() { assertThatThrownBy(() -> new RedisKeyName("user", "1:2")) .isInstanceOf(IllegalArgumentException.class); assertThatThrownBy(() -> new RedisSlotTag("{nested}")) .isInstanceOf(IllegalArgumentException.class); assertThatThrownBy(() -> new RedisNamespace("prod", "order:service", "shared")) .isInstanceOf(IllegalArgumentException.class); } @Test void rejectsAnIdentifierAboveTheTokenLimit() { String oversized = "a".repeat(129); assertThatThrownBy(() -> new RedisKeyName("user", oversized)) .isInstanceOf(IllegalArgumentException.class); } # 저장소 전체에서 네 메시지가 나오는 곳 (파일 형식 제한 없음) sdk/api/key/RedisKeyRules.java:67: throw new IllegalArgumentException("identifier must not contain a mail address"); sdk/api/key/RedisKeyRules.java:70: throw new IllegalArgumentException("identifier must not contain a JSON web token"); sdk/api/key/RedisKeyRules.java:73: throw new IllegalArgumentException("identifier must not contain a phone number"); sdk/api/key/RedisKeyRules.java:76: throw new IllegalArgumentException("identifier must not contain authentication material");