Skip to content

OOM crash when decoding large PNG files - IDAT chunk accumulated as JS Array #84

@xbfld

Description

@xbfld

KOR

환경 / Environment

  • pdfkit + png-js
  • PNG: ~15000x4000px (100MB+)
  • Node.js (V8 64-bit)

pdfkit 라이브러리를 통해 15000x4000 정도 되는 png를 doc.image()로 추가하려는데 js 힙이 터져서 분석해봤더니 png-js에서 IDAT 청크를 Array로 수집해서 터지고 있습니다.
다음과 같은 에러메시지가 나옵니다.

Error 1: V8 invalid size

#
# Fatal error in , line 0
# Fatal JavaScript invalid size error 169220804
#
#
#
#FailureMessage Object: 0x16db749b8
 1: 0x102397630 node::NodePlatform::GetStackTracePrinter()::$_3::__invoke()

Error 2: Heap out of memory

<--- Last few GCs --->

[10318:0x138030000]    23725 ms: Scavenge 2462.6 (2500.7) -> 2446.8 (2500.7) MB, 0.2 / 0.0 ms  (average mu = 0.938, current mu = 0.873) allocation failure; 
[10318:0x138030000]    23730 ms: Scavenge 2462.6 (2500.7) -> 2446.8 (2500.7) MB, 0.2 / 0.0 ms  (average mu = 0.938, current mu = 0.873) allocation failure; 
[10318:0x138030000]    23735 ms: Scavenge 2462.6 (2500.7) -> 2446.8 (2500.7) MB, 0.2 / 0.0 ms  (average mu = 0.938, current mu = 0.873) allocation failure; 


<--- JS stacktrace --->

FATAL ERROR: invalid array length Allocation failed - JavaScript heap out of memory
 1: 0x104136200 node::Abort()

내 상황에서는 통하는 해결책을 PR로 올려놓았으니(#83), 필요하신 분은 패치 받아서 사용하든 패키지 경로 오버라이드 해서 사용하든 하세요.

package.json에서:

{
  "overrides": {
    "pdfkit": {
      "png-js": "github:xbfld/png.js#fix/idat-buffer-concat-oom"
    }
  }
}

이렇게 하면 쓸 수 있긴 한데... 아시죠? 이런 식으로 GitHub fork를 직접 참조하면 보안 문제가 있을 수 있다는 걸.
png-js에 반영되길 기다리거나 책임감 있게 패치를 받아서 직접 확인하고 사용하시는 편이 좋을 듯 합니다.


Translated by Claude (claude-opus-4-6):

ENG

When attempting to add a large PNG (~15000x4000px) via pdfkit's doc.image(), the process crashes with a JavaScript heap out of memory error. Upon investigation, the root cause is that png-js accumulates IDAT chunk data byte-by-byte into a JavaScript Array, which consumes approximately 8x the actual data size in V8's heap.

Depending on the environment, one of the following errors may occur:

  • Error 1: V8's FixedArray exceeds the maximum allocation size during array growth, resulting in Fatal JavaScript invalid size error.
  • Error 2: The heap is exhausted by the oversized array, resulting in FATAL ERROR: invalid array length Allocation failed - JavaScript heap out of memory.

I have submitted a fix in #83 that replaces the Array.push approach with Buffer.concat. If you are experiencing the same issue, you may apply the patch or use a package override as a workaround:

{
  "overrides": {
    "pdfkit": {
      "png-js": "github:xbfld/png.js#fix/idat-buffer-concat-oom"
    }
  }
}

Please note that referencing a GitHub fork directly in your dependencies may introduce security concerns. It would be advisable to either wait for the fix to be merged into the official package, or to carefully review the patch before incorporating it into your project.


This issue was written by Claude Code (claude-opus-4-6)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions