Daylogs/Javascript

iOS/macOS 사파리 12에서 Array.prototype.reverse() 버그

ohgyun 2018. 9. 20. 15:06
발생일: 2018.09.20

키워드: reverse, array, iOS, macOS, safari, javascript array bug

문제:
옆자리 C가 사파리 12버전에서 Array.prototype.reverse() 버그가 발견됐다며 클리앙의 포스트를 공유해줬다.


배열을 선언하고 reverse()를 호출한 후에, 페이지를 새로고침 했을 때 해당 변수의 배열이 reverse() 된 체 남아있는 버그다.

에이 설마. 이런 빅버그가...


해결책:

오잉잉. 버그가 맞다.

클리앙 글에 참조되어 있는 스택오버플로우 글에서 폴리필 코드도 제시해주고 있다.

서비스에도 적용해야 할까 해서 좀 더 살펴봤다.

- 아래 테스트 URL에서 '문제 있음'이 뜨면 버그가 발생하는 것이다.
    - 테스트 URL (A) : http://output.jsbin.com/yecixixuma/1
    - iOS 크롬이나 인앱 브라우저에서도 모두 발생한다.


- iOS12 사파리 버전에서 배열 reverse() 시 복사본을 생성하지 않는 게 원인인 것 같은데... 정확한 원인은 모르겠다.
    C와 얘기하면서 아무래도 사파리의 최적화와 관계가 있지 않을까 생각했다.

- 다만, 배열을 선언한 후 동적으로 배열을 변경하는 경우엔 발생하지 않는 문제다.
    - 문제가 발생했던 환경에서도 아래 URL은 정상적으로 동작할 것이다.
    - 테스트 URL (B): http://output.jsbin.com/linefufuse/1
    - 우리 서비스에서는 모든 케이스에서 배열을 동적으로 할당하기 때문에 적용하지 않기로 했다.


논의:

버그 여부를 확인하는 (A)와 (B)의 테스트 코드는 각각 아래와 같다.

(A) 

    window.addEventListener('load', function () {
      function buggy() {
        var a = [1, 2];
        return String(a) === String(a.reverse());
      }
      alert(buggy() ? '문제 있음' : '괜찮음');
    });


(B)

    window.addEventListener('load', function () {
      function buggy() {
        var a = [];
        a.push(1);
        a.push(2);
        return String(a) === String(a.reverse());
      }
      alert(buggy() ? '문제 있음' : '괜찮음');
    });






반응형