Firebase Crashlytics - NSPlaceholderString initWithString(nil argument)

바닐라빈·2022년 11월 8일
0

iOS Developer

목록 보기
2/3
post-thumbnail

NSString을 초기화 할때 일반적으로 아래의 3가지 방법을 사용한다.

1. NSString *str = @"";
2. NSString *str = [[NSString alloc] initWithFormat: @"%@", var];
3. NSString *str = [[NSString alloc] initWithString: var];

나의 경우에는 3번을 사용하여 초기화 하였다.

구글링을 하다 보면 3번 방법보다 2번 방법이 비교적 안전하다는 이야기가 있는데 사실 2를 사용하든 3을 사용하든 (var == nil) 일 경우 동일하게 crash가 발생 하는것을 확인 하였기 때문에 NSString 초기화 방식은 문제가 아니었다.

그렇다면 왜 var의 값이 nil이 되었을까?

Flow는 다음과 같았다.

  1. 사용자로부터 민감정보를 입력 받는다.
  2. 입력 받은 민감정보를 AES256 암호화 하여 NSString으로 저장
  3. 특정 시점에 필요에 의하여 암호화된 민감정보를 복호화
  4. 복호화 한 데이터를 사용하기 위해 다른 NSString 변수에 초기화 값으로 사용

내가 사용중인 AES256 암복호화 코드는 신뢰도가 아주 높은 오픈소스였기에 해당 로직에서 nil을 반환할 가능성을 전혀 예상치 못했다.
복호화 코드를 확인하다가 다음 내용을 보는순간 문득 예전 생각이 떠올랐다.

NSString *result = [[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding];

서버 또는 웹으로부터 전달받은 문자열에 UTF-8 인코딩이 불가한 문자가 포함되어 있을 경우 nil을 반환하여서 서비스 장애가 발생한 적이 있었는데, encoding 이라는 코드가 보이자 마자 그 생각이 떠오른 것이다.

고객이 입력하는 문자열은 ASCII 범주 안의 문자를 사용하였지만 AES256 암호화와 복호화를 하는 과정에서 특수한 문자로 변환되는 케이스가 있지 않을까?

그래서 다음과 같이 방어코드를 넣어주기로 했다.

  1. UTF-8 인코딩
  2. UTF-8 인코딩 결과가 nil 일 경우, Latin-1 인코딩
  3. Latin-1 인코딩 결과가 nil 일 경우, WindowsCP1252 인코딩
NSString *result = [[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding];
    
    if (result == nil) {
        result = [[NSString alloc] initWithData:theData encoding:NSISOLatin1StringEncoding];
        
        if (result == nil) {
            result = [[NSString alloc] initWithData:theData encoding:NSWindowsCP1252StringEncoding];
        }
    }

결과는 대성공 !

profile
iOS Developer

0개의 댓글