aws / aws/aws-encryption-sdk-javascript

decryptStream causes unbounded memory growth

オープン 初心者向け
#1,656 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る
主要言語
TypeScript
スター
260
フォーク
68
平均マージ
22時間 19分
マージ済み PR(30日)
2

説明

### Problem:

While using `decryptStream` to stream-decrypt large S3 objects, I noticed a memory increase roughly equal to the size of the object.

I think the issue is that `_decryptStream` returns a duplexify wrapper and internally runs a pipeline:

```
const stream = new Duplexify(parseHeaderStream, decipherStream)

pipeline(
parseHeaderStream,
verifyStream,
decipherStream,
new PassThrough(),
(err: Error) => {
if (err) stream.emit('error', err)
}
)
```

The caller reads from `decipherStream` via the duplexify wrapper. The pipeline also pushes `decipherStream`'s output into the `PassThrough`. Since nothing ever reads from that `PassThrough`, its internal buffer appears to grow without bound.

### Solution:

Replacing the `PassThrough` with a no-op `Writable` that discards chunks fixes the memory growth while still absorbing the `destroy()` call:

```
const drain = new Writable({
write(_chunk, _encoding, callback) {
callback()
},
})

pipeline(
parseHeaderStream,
verifyStream,
decipherStream,
drain,
(err: Error) => {
if (err) stream.emit('error', err)
}
)
```

I tested this change locally and the memory usage stopped increasing while streaming.

コントリビューションガイド

コントリビューションガイドを開く

調査の方向性

`_decryptStream` のエントリポイントから始め、`parseHeaderStream`、`verifyStream`、`decipherStream` を `PassThrough` に接続しているパイプラインを調べます。説明されているとおりに未読の出力シンクを置き換え、その後、大きな S3 オブジェクトをストリーミングして、メモリ使用量がオブジェクトのサイズに応じて増加しなくなったことを確認して検証します。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
aws, node.js, typescript
領域
backend, cloud, stream-processing
issue の種類
バグ
難易度
2/5
見積もり時間
1〜3時間
活発さ
静か
明瞭さ
明確に書かれている
初心者へのやさしさ
68/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。