lovell / sharp

High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.
https://sharp.pixelplumbing.com
Apache License 2.0
28.38k stars 1.28k forks source link

munmap_chunk(): invalid pointer, on bun #4042

Closed billyadelphia closed 3 months ago

billyadelphia commented 3 months ago

Possible bug

Is this a possible bug in a feature of sharp, unrelated to installation?

Are you using the latest version of sharp?

What is the output of running npx envinfo --binaries --system --npmPackages=sharp --npmGlobalPackages=sharp?

  System:
    OS: Linux 5.15 Ubuntu 22.04.4 LTS 22.04.4 LTS (Jammy Jellyfish)
    CPU: (32) x64 AMD Ryzen 9 5950X 16-Core Processor
    Memory: 74.69 GB / 125.70 GB
    Container: Yes
    Shell: 5.1.16 - /bin/bash
  Binaries:
    Node: 20.11.1 - ~/.nvm/versions/node/v20.11.1/bin/node
    npm: 10.5.0 - ~/.nvm/versions/node/v20.11.1/bin/npm
    bun: 1.0.35 - ~/.bun/bin/bun
  npmPackages:
    sharp: ^0.33.3 => 0.33.3

What are the steps to reproduce?

import sharp from "sharp";

//some function here

const theSharp = await sharp(buffer).trim().toBuffer();
lovell commented 3 months ago

I cannot reproduce this locally using Bun 1.0.35 via the oven/bun (Debian 11) Docker container.

If you're still having problems, please provide a complete code sample and image that allows someone else to reproduce.

billyadelphia commented 3 months ago

I cannot reproduce this locally using Bun 1.0.35 via the oven/bun (Debian 11) Docker container.

If you're still having problems, please provide a complete code sample and image that allows someone else to reproduce.

This is the entire code

Just my small service to remove the background image and then trim it using sharp

import Fastify from "fastify";
import { removeBackground } from "@imgly/background-removal-node";
const fastify = Fastify({
  // logger: true
});
import { Buffer } from "buffer";
import cors from "@fastify/cors";
import axios from "axios";
import { writeFileSync } from "fs";
import { join } from "path";
import { randomBytes } from "crypto";
import imageType from "image-type";
import { fileURLToPath } from "url";
import { dirname } from "path";
import sharp from "sharp";
import fs from "fs";

const __dirname = dirname(fileURLToPath(import.meta.url));

await fastify.register(cors, {
  origin: "*",
});

const downloadImage = async (url: string) => {
  const response = await axios.get(url, { responseType: "arraybuffer" });
  const buffer = Buffer.from(response.data, "binary");

  // Get the image type from the buffer
  const type = await imageType(buffer);
  console.log("type", type);
  // If the image type couldn't be detected, throw an error
  if (!type) {
    throw new Error("Could not detect image type");
  }

  // Generate a random filename with the correct extension
  const filename = randomBytes(16).toString("hex") + "." + type.ext;

  // Full path of the image
  const imagePath = join(__dirname, "backgroundImages", filename);

  // Save the image
  writeFileSync(imagePath, buffer);

  // Return the full path of the image
  return imagePath;
};

// Declare a route
fastify.post("/remove-background", async function handler(request, reply) {
  console.log("search");
  const body = request.body as any;
  const imageUrl = body.imageUrl;
  const imageId = body.imageId;
  console.log("body", body);
  if (!imageUrl && !imageId) {
    console.log("Invalid Request", "if (!imageUrl || !imageId) {");
    return reply.code(400).send("Invalid Request");
  }

  if (!imageUrl.startsWith("http")) {
    console.log("Invalid Request", "if (!imageUrl.startsWith('http')) {");
    return reply.code(400).send("Invalid Request");
  }
  let result: Blob | undefined;
  if (imageUrl) {
    try {
      //download the image, and save it to a file in backgroundImages folder
      const data = await downloadImage(imageUrl);
      console.log("removeBackground(data, {");
      result = await removeBackground(data, {
        debug: true,
        output: { format: "image/png", quality: 1 },
      });

      //remove the image file
      fs.unlinkSync(data);
    } catch (e) {
      console.log("err await removeBackground(imageUrl);", e);
      return reply.code(400).send("Invalid Request");
    }
  }
  console.log("theResultDone");
  if (!result) {
    return reply.code(400).send("Invalid Request");
  }

  const buffer = await result.arrayBuffer();
  let theBase64 = Buffer.from(buffer).toString("base64"); // you can ignore this, it's just the part of the code before I implement sharp
  // console.log("base64Image", theBase64); // This will log the base64 representation of the image
  //convert result to base64 png
  // theBase64 = `data:image/png;base64,${theBase64}`;
  // console.log("theBase64", theBase64);
  console.log("sharpingsharpingsharping");
  const theSharp = await sharp(buffer).trim().toBuffer();
  console.log("theSharp done");
  theBase64 = theSharp.toString("base64");
  theBase64 = `data:image/png;base64,${theBase64}`;

  const data = {
    base64: theBase64,
  };
  // console.log("data", data);
  return reply.code(200).send(data);
});

// Run the server!
try {
  await fastify.listen({ port: 5832 });
  console.log(`server listening on ${fastify.server.address().port}`);
} catch (err) {
  fastify.log.error("ulalafast", err);
  process.exit(1);
}
lovell commented 3 months ago

Please can you provide a more minimal code sample that allows someone else to reproduce. For example, please remove all networking code, and please remove the other dependencies such as @imgly/background-removal-node.

Perhaps create a complete, minimal, standalone repo that makes it as simple as possible for someone else to reproduce.

lovell commented 3 months ago

I've just spotted that @imgly/background-removal-node depends on an old version of sharp and will not work on Bun.

https://github.com/imgly/background-removal-js/blob/688472762e819747362e3e88d5322a8cdbf8a967/packages/node/package.json#L63

Support for Bun was added in sharp v0.33.0.