Skip to content

zlib.zstd: createZstdCompress and zstdCompressSync produce different outputs #58392

Open
@willfarrell

Description

@willfarrell

Version

v24.0.2

Platform

Darwin usernames-Mac-Studio.local 24.5.0 Darwin Kernel Version 24.5.0: Tue Apr 22 19:54:49 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T6000 arm64

Subsystem

zlib

What steps will reproduce the bug?

import test from 'node:test'
import { deepEqual } from 'node:assert'
import { Readable, pipeline } from 'node:stream'
import { createZstdCompress, zstdCompressSync } from 'node:zlib'

test(`zstd`, async (t) => {
  const input = JSON.stringify(new Array(1024).fill(0))
  const expectedOutput = zstdCompressSync(input)
  const readableStream = Readable.from(input)
  const compressStream = createZstdCompress()

  const chunks = []
  for await (const chunk of readableStream.pipe(compressStream)) {
	chunks.push(Buffer.from(chunk))
  }
  const output = Buffer.concat(chunks)
  deepEqual(output, expectedOutput)
})

Run node --test

How often does it reproduce? Is there a required condition?

Always

What is the expected behavior? Why is that the expected behavior?

Outputs to be the same.

What do you see instead?

▶ node --test packages/compress/node.test.js
✖ zstd (3.136875ms)
ℹ tests 1
ℹ suites 0
ℹ pass 0
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 52.920791

✖ failing tests:

test at packages/compress/node.test.js:6:1
✖ zstd (3.136875ms)
  AssertionError [ERR_ASSERTION]: Expected values to be loosely deep-equal:
  
  Buffer(20) [Uint8Array] [
    40,
    181,
    47,
    253,
    0,
    88,
    93,
    0,
    0,
    32,
    91,
    48,
    44,
    93,
    1,
    0,
    250,
    247,
    187,
    33
  ]
  
  should loosely deep-equal
  
  Buffer(21) [Uint8Array] [
    40,
    181,
    47,
    253,
    96,
    1,
    7,
    93,
    0,
    0,
    32,
    91,
    48,
    44,
    93,
    1,
    0,
    250,
    247,
    187,
    33
  ]
      at TestContext.<anonymous> (file:///Users/username/Development/github/datastream/packages/compress/node.test.js:15:4)
      at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
      at async Test.run (node:internal/test_runner/test:1069:7)
      at async startSubtestAfterBootstrap (node:internal/test_runner/harness:332:3) {
    generatedMessage: true,
    code: 'ERR_ASSERTION',
    actual: <Buffer 28 b5 2f fd 00 58 5d 00 00 20 5b 30 2c 5d 01 00 fa f7 bb 21>,
    expected: <Buffer 28 b5 2f fd 60 01 07 5d 00 00 20 5b 30 2c 5d 01 00 fa f7 bb 21>,
    operator: 'deepEqual'
  }

Additional information

Not sure if this is a bug in zstd or if this is expect (metadata indicating how the compression happened maybe). Both variants of the output decompress correctly.

I noticed that zstdCompressSync(<string>) returns a buffer instead of a string like other algorithm convenience methods such as brotliCompressSync(<string>).

Metadata

Metadata

Assignees

No one assigned

    Labels

    zlibIssues and PRs related to the zlib subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions