Skip to content

fix: EgovStringUtil.search 빈 target 무한 루프 방지#245

Open
z3rotig4r wants to merge 1 commit into
eGovFramework:mainfrom
z3rotig4r:fix/stringutil-search-infinite-loop
Open

fix: EgovStringUtil.search 빈 target 무한 루프 방지#245
z3rotig4r wants to merge 1 commit into
eGovFramework:mainfrom
z3rotig4r:fix/stringutil-search-infinite-loop

Conversation

@z3rotig4r

Copy link
Copy Markdown
Contributor

문제

EgovStringUtil.search(String source, String target)source 안에서 target이 나타나는 횟수를 셉니다.

public static int search(String source, String target) {
    int result = 0;
    String strCheck = source;
    for (int i = 0; i < source.length(); ) {
        int loc = strCheck.indexOf(target);
        if (loc == -1) {
            break;
        } else {
            result++;
            i = loc + target.length();
            strCheck = strCheck.substring(i);
        }
    }
    return result;
}

target이 빈 문자열("")이면 strCheck.indexOf("")가 항상 0을 반환합니다. 이때 i = loc + target.length()0으로 고정되고 strCheck = strCheck.substring(0)로 문자열이 줄어들지 않아, source가 비어 있지 않은 한 for 루프가 종료되지 않습니다. 공개 정적 유틸이라 호출 측 입력에 따라 CPU 점유·스레드 행으로 이어질 수 있습니다(CWE-835).

또한 sourcetargetnull이면 각각 source.length(), indexOf(null)에서 NullPointerException이 발생합니다.

수정

진입부에 가드를 추가했습니다. source 또는 targetnull이거나 빈 문자열이면 셀 대상이 없으므로 0을 반환합니다. 이는 Apache Commons Lang StringUtils.countMatches와 동일한 규약입니다.

if (source == null || source.isEmpty() || target == null || target.isEmpty()) {
    return 0;
}

기존의 정상 카운트 동작은 그대로 유지됩니다.

검증

EgovStringUtilTest에 테스트 3건을 추가했습니다.

  • 정상 카운트(search("aXbXc", "X") == 2 등)
  • target 무한 루프 방지(assertTimeoutPreemptively로 2초 내 0 반환 확인)
  • null/빈 입력이 예외 없이 0 반환
mvn -pl Foundation/org.egovframe.rte.fdl.string -am test -Dtest=EgovStringUtilTest
Tests run: 30, Failures: 0, Errors: 0, Skipped: 0

search(source, target)에서 target이 빈 문자열이면 indexOf("")가
항상 0을 반환하고, 루프 인덱스 i가 0에 고정되며 strCheck도 줄어들지
않아 for 루프가 끝나지 않습니다(source가 비어 있지 않은 경우).
공개 정적 유틸이라 호출 측 입력에 따라 CPU 점유·스레드 행으로
이어질 수 있습니다. 또한 source나 target이 null이면 NullPointerException이
발생합니다.

source 또는 target이 null이거나 빈 문자열이면 셀 대상이 없으므로
0을 반환하도록 진입부 가드를 추가했습니다(commons-lang
StringUtils.countMatches와 동일한 규약).

빈 target 무한 루프 방지(타임아웃), null 입력, 정상 카운트를 포함한
단위 테스트 3건을 추가했습니다.
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