Skip to content

fix: 설정 리더 3종이 로케일에 따라 properties 키를 조용히 무시하는 문제 수정 - #330

Open
wantaekchoi wants to merge 1 commit into
eGovFramework:mainfrom
wantaekchoi:fix/config-reader-setter-name-locale
Open

fix: 설정 리더 3종이 로케일에 따라 properties 키를 조용히 무시하는 문제 수정#330
wantaekchoi wants to merge 1 commit into
eGovFramework:mainfrom
wantaekchoi:fix/config-reader-setter-name-locale

Conversation

@wantaekchoi

Copy link
Copy Markdown
Contributor

수정 사유 Reason for modification

  • 버그수정 Bug fixes
  • 기능개선 Enhancements
  • 기능추가 Adding features
  • 기타 Others

수정된 소스 내용 Modified source

EgovAccessConfigReader · EgovCryptoConfigReader · EgovSecurityConfigReadermapPropertiesToBean은 properties 키로 setter 이름을 만들 때 첫 글자를 toUpperCase()로 올립니다. 인자 없는 toUpperCase()는 JVM 기본 로케일을 따르므로, 터키어·아제르바이잔어 로케일에서 "id"는 점 있는 İ(U+0130)가 되어 setİd를 찾게 되고 실제 메서드명 setId와 일치하지 않습니다.

findSetternull을 돌려주면 바로 아래 if (setter != null) 가드에 걸려 그 키가 예외도 로그도 없이 버려집니다. 그 가드는 파일에 없는 키를 관대하게 넘기려는 것인데, 여기서는 setId(String)가 실제로 있는데도 이름을 못 찾아 버려집니다.

Egov*Config가 모두 id 필드를 갖고 있고 EgovCryptoConfig에는 initial도 있습니다. 다만 지금은 getId()를 읽는 곳이 없어 관측되는 오동작은 없습니다. i로 시작하는 키가 앞으로 하나라도 실제로 쓰이면 그때부터 조용히 어긋납니다.

세 파일의 해당 줄은 글자까지 같은 복붙이라 함께 고쳤습니다.

AS-IS

String setterName = "set" + key.substring(0, 1).toUpperCase() + key.substring(1);

TO-BE

String setterName = "set" + key.substring(0, 1).toUpperCase(Locale.ROOT) + key.substring(1);

같은 결함 클래스를 Locale.ROOT로 고친 선례가 이 저장소에 있습니다 — DefaultMapUserDetailsMapping의 컬럼명 소문자화(#321). main 코드에 Locale.ENGLISH·Locale.US 사용은 없고 Locale.ROOT만 씁니다.

영향 범위

ASCII 키는 기본 로케일이 무엇이든 결과가 같습니다. 바뀌는 것은 터키어 계열 로케일에서 i로 시작하는 키뿐입니다.

JUnit 테스트 JUnit tests

  • JUnit 테스트 JUnit tests
  • 수동 테스트 Manual testing

세 리더에 각각 로케일 테스트를 1건씩 추가했습니다. access 모듈에는 리더 테스트가 없어 새로 만들었고, 나머지 둘은 기존 테스트 파일에 붙였습니다.

수정 지점만 되돌린 상태(RED)

access     [ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
crypto     [ERROR] Tests run: 3, Failures: 1, Errors: 0, Skipped: 0
security   [ERROR] Tests run: 3, Failures: 1, Errors: 0, Skipped: 0

EgovAccessConfigReaderTest.testReadConfigAppliesKeysUnderTurkishLocale
  터키어 로케일에서도 properties의 id 키가 반영되어야 한다(기본값 egovAccessConfig로 남으면 안 된다)
  ==> expected: <customConfigId> but was: <egovAccessConfig>

수정 후(GREEN, 세 모듈 전체)

access     [INFO] Tests run: 11, Failures: 0, Errors: 0, Skipped: 0
crypto     [INFO] Tests run: 25, Failures: 0, Errors: 0, Skipped: 0
security   [INFO] Tests run: 32, Failures: 0, Errors: 0, Skipped: 0

EgovAccessConfigReader·EgovCryptoConfigReader·EgovSecurityConfigReader의
mapPropertiesToBean은 properties 키로 setter 이름을 만들 때 첫 글자를
toUpperCase()로 올린다. 인자 없는 toUpperCase()는 JVM 기본 로케일을 따르므로,
터키어·아제르바이잔어 로케일에서 "id"는 점 있는 'İ'(U+0130)가 되어 "setİd"를
찾게 되고 실제 메서드명 setId와 일치하지 않는다.

findSetter가 null을 돌려주면 아래 if (setter != null) 가드에 걸려 그 키가
예외도 로그도 없이 버려진다. 세 Config 클래스 모두 id 필드를 갖고 있고
EgovCryptoConfig에는 initial도 있어, 사용자가 파일에 적은 값이 조용히 무시되고
createDefaultConfig()의 기본값이 그대로 남는다.

세 파일의 해당 줄은 글자까지 같은 복붙이라 함께 고쳤다.

  String setterName = "set" + key.substring(0, 1).toUpperCase(Locale.ROOT) + key.substring(1);

같은 결함 클래스를 Locale.ROOT로 고친 선례가 이 저장소에 있다 —
DefaultMapUserDetailsMapping의 컬럼명 소문자화(eGovFramework#321, 59e4d31).
main 코드에 Locale.ENGLISH·Locale.US 사용은 없고 Locale.ROOT만 쓴다.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant