[Node.js 기여] myersDiff 입력 크기 제한 & TODO 주석 제거 PR

정하람·2025년 9월 10일

OSS-Contribution

목록 보기
7/7
post-thumbnail

[Node.js 기여] assert: myersDiff 입력 크기 제한 PR (#59578)

https://github.com/nodejs/node/pull/59578


배경

이번 기여는 internal/assert/myers_diff.js 파일에 남아있던 TODO 주석을 발견하면서 시작했다. 이 파일은 Node.js의 assert 모듈에서 객체나 배열의 차이점을 시각적으로 보여주는 데 사용되는 myersDiff 알고리즘을 담고 있었다.

코드를 살펴보니, myersDiff는 내부적으로 Int32Array를 사용해 두 배열의 길이를 기반으로 중간 계산값을 저장하고 있었다. 그런데 Int32Array는 배열의 최대 크기가 2^31 - 1로 제한되어 있다. 만약 사용자가 비교하려는 두 배열의 합산 길이가 이 제한을 넘어버리면, Int32Array를 할당하는 과정에서 RangeError: Array buffer allocation failed와 같은 런타임 오류가 발생할 수 있는 잠재적 문제가 있었다.

물론 일상적으로 이렇게 거대한 배열을 비교할 일은 없겠지만, Node.js는 모든 엣지 케이스를 고려해야 하는 핵심 모듈이다. 그래서 나는 이 PR을 통해 입력 크기를 미리 검사하고, 허용 범위를 초과할 경우 개발자에게 명확하게 알려주는 ERR_OUT_OF_RANGE 오류를 발생시키도록 수정했다. 이는 런타임에 예상치 못한 충돌을 방지하고, 에러 메시지를 통해 사용자가 문제의 원인을 바로 파악할 수 있게 해주는 중요한 개선이다.

수정사항

  1. 입력 크기 검증 로직 추가: myersDiff 함수 초입에 다음과 같은 코드를 추가했다.

    if (max > 2 ** 31 - 1) {
        throw new ERR_OUT_OF_RANGE(
          'myersDiff input size',
          '< 2^31',
          max,
        );
      }

이 로직은 두 배열의 길이를 합쳐 2^31 - 1보다 큰지 확인하고, 크다면 ERR_OUT_OF_RANGE 에러를 던지도록 한다.

  1. 명확한 상수 사용: 초기에는 16진수 값인 0x7FFFFFFF를 사용했지만, 리뷰어인 BridgeAR 님이 `2 31 - 1`*로 변경해 가독성을 높일 것을 제안했다. 훨씬 직관적인 표현이라서 바로 반영했다.
  2. 테스트 코드 추가 과정: 가장 어려웠던 부분은 테스트 케이스였다. V8 엔진은 문자열 길이에 제한이 있어 직접적으로 2^31 - 1을 초과하는 문자열을 만드는 게 불가능했기 때문이다. 그래서 처음에는 테스트를 포기할까도 생각했다. 하지만 BridgeAR 님의 피드백을 통해 문자열 대신 배열을 사용하면 이 에러를 재현할 수 있다는 힌트를 얻었다. 추가적으로 테스트에서 internal 내부에 있는 요소들을 가져오는 과정에서
    // Flags: --expose-internals 을 넣지 않으면 에러가 난다. 필자는 괜히 막 따로 built-in 에 뭘 추가해야되는 줄 알고 시간을 많이 썼다.

// 두 개의 2^30 크기 배열을 합쳐 2^31을 만들어 오류를 유발

assert.throws(() => {
  myersDiff(new Array(2 ** 30), new Array(2 ** 30));
}, {
  code: 'ERR_OUT_OF_RANGE',
  message: 'Input size must be less than 2 ** 31 - 1'
});

이 테스트 코드를 추가하면서 PR의 완성도를 높일 수 있었고, Node.js의 테스트 코드 작성 패턴에 대해서도 배울 수 있었다.


[Node.js 기여] util: 더 이상 필요 없는 TODO 주석 제거 PR (#59760)

https://github.com/nodejs/node/pull/59760


배경

이번 기여는 lib/internal/util.js에 있는 TODO 주석을 제거하는 아주 간단한 PR이었다.

deprecated() 함수 내부에는 process.noDeprecationgetOptionValue('--no-deprecation')로 바꾸라는 내용의 주석이 달려 있었다. 이 주석의 배경은 process.noDeprecation이 내부적으로 getOptionValue를 사용하기 때문에, 중복 없이 직접적으로 getOptionValue를 사용하는 것이 더 좋다는 생각이었다.

하지만 리뷰어인 joyeecheung 님이 "이 부분을 실제로 변경하면 예상치 못한 부작용이 발생할 수 있으니, 현재 로직은 그대로 두고 주석만 제거하는 게 더 낫겠다"는 의견을 주셨다.

수정사항

  • TODO 주석 제거: 이 PR은 단 한 줄, // TODO (joyeecheung): use getOptionValue('--no-deprecation') instead. 주석을 삭제하는 것으로 마무리됐다.

정리

연달아 두 개의 PR이 반영되면서 오픈소스 기여가 점점 더 익숙해지고 있다.

단순히 코드를 작성하는 것뿐만 아니라, PR 리뷰 과정에서 다른 개발자들의 생각과 조언을 듣고 반영하는 것에서 많이 배우고 성장하는 것 같다.

0개의 댓글