fix: DB 프로퍼티 컬럼 라벨을 대소문자 무시 비교하고 키 누락 행은 건너뜀 - #296
Open
z3rotig4r wants to merge 1 commit into
Open
Conversation
DbPropertySourceDelegate가 queryForList 결과의 컬럼 라벨을 PKEY/PVALUE와 대소문자 구분 equals로 비교했다. PostgreSQL은 인용부호 없는 식별자를 소문자로 폴딩하므로 쿼리를 대문자로 작성해도 라벨이 pkey/pvalue로 돌아온다(PostgreSQL 17 + JDBC 42.7.3 실측). 이 경우 매칭이 전부 실패해 properties에 null 키만 남고 DB 기반 프로퍼티가 전량 유실된다. 소문자로 작성된 SQL처럼 상수와 다른 케이스의 라벨을 반환하는 DB·드라이버도 같은 영향을 받는다. 비교를 equalsIgnoreCase로 바꾸고, 키 컬럼을 찾지 못한 행은 건너뛰며 건너뛴 건수를 모아 load당 한 번만 경고 로그를 남긴다.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
문제
EgovCrnCheckValidation의 가중치 배열이{1, 3, 7, 1, 3, 7, 1, 3, 5, 1}열 개로 선언되어 있어 반복문이 열 번째 자리까지 순회합니다. 열 번째 자리는 검증 대상인 체크디지트 자신이므로 검증해야 할 값이 가중합에 섞여 들어갑니다. 공통컴포넌트EgovNumberCheckUtil.checkCompNumber(2009년부터 운영)는 앞 아홉 자리에만 가중치를 적용합니다.그래서 판정이 규격과 어긋납니다. 유효한 사업자등록번호 1만 건 중 9,026건이 거부되고 무효 번호 8,960건이 승인됩니다(규격 대비 일치율 82%). 체크디지트가 가중합에 한 번 더 더해지므로 유효한 번호는 체크디지트가 0인 경우에만 통과합니다.
패턴 검사에도 결함이 있습니다.
matcher.find()가 최종 개행 앞의 매치를 허용하므로"1248100998\n"이 열 자리 검사를 통과합니다. 이후Integer.parseInt가"8\n"을 파싱하며NumberFormatException을 던집니다. 검증기가 false를 돌려주는 대신 예외가 그대로 전파되므로 400이 아닌 500으로 응답합니다.수정
가중치 배열을
{1, 3, 7, 1, 3, 7, 1, 3, 5}아홉 개로 줄여 앞 아홉 자리에만 적용했습니다. 체크디지트는 마지막 비교 대상으로만 남습니다. 이어서matcher.find()를matcher.matches()로 바꿔 문자열 전체가 열 자리 숫자와 일치할 때만 통과시키도록 했습니다. 커밋은 가중치 수정·테스트 추가·개행 수정 세 개로 나눠 두었습니다.검증
EgovNumberCheckUtil.checkCompNumber와 알고리즘이 같습니다. 무작위 20만 건을 대조한 결과 판정이 완전히 일치했습니다.matches()로 바꾼 뒤에도 정상 입력의 판정은 달라지지 않았습니다. 대조 집합의 승인 건수가 10,132건·10,000건으로 전환 전후 같았습니다.mvn -o clean test로 해당 모듈 테스트 20건이 모두 통과합니다. 이번에 추가한 reactive 검증기 8종 시맨틱 테스트 8건이 여기 포함됩니다.matches()를 수정 전으로 되돌리면 추가한 테스트가 각각 실패합니다.영향 범위
EgovCrnCheckValidation한 파일입니다.@EgovCrnCheck의 판정 결과는 바뀝니다. 기존에 통과했던 무효 번호는 거부되고 거부됐던 유효 번호는 통과합니다. 판정이 규격에 맞게 돌아오는 변화이므로 호출부는 그대로 두어도 됩니다.EgovCnCheckValidation·EgovRrnCheckValidation도find()를 쓰고 있어 개행이 붙은 입력에서 같은NumberFormatException이 납니다. 휴대전화·일반전화·영문·한글 검증기는 개행이 붙은 입력을 예외 없이 통과시킵니다. 이 PR은 사업자등록번호로 범위를 한정했고 나머지는 별도 PR로 분리하겠습니다.checkJuminNumber와의 차이입니다. 동작이 바뀌는 범위가 넓어 이 PR에서는 다루지 않았습니다.