Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Windows] Missed support of long path #4292

Open
AlttiRi opened this issue Dec 9, 2024 · 2 comments
Open

[Windows] Missed support of long path #4292

AlttiRi opened this issue Dec 9, 2024 · 2 comments
Labels

Comments

@AlttiRi
Copy link

AlttiRi commented Dec 9, 2024

Possible bug

It works fine until I pass a long path to load an image with sharp function.

As workaround I can manually read the file with Node.js and pass ArrayBuffer of the image to sharp function instead of the image path string.

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

It's bug of handling a Windows filesystem long path.

ENV

  • Window 10
  • Node v20.18.0
  • Sharp 0.33.5

What are the steps to reproduce?

Run the TS code.

What is the expected behaviour?

No errors. A workaround is not needed. It just works from the box.

Please provide a minimal, standalone code sample, without other dependencies, that demonstrates this problem

import sharp from "sharp";
import fs from "node:fs/promises";
import path from "node:path";

const imageName = "image-for-long-path-3x3.png";

// create an image
await saveImageDataWithSharp({
    data: new Uint8ClampedArray([255, 255, 255, 0, 0, 0, 128, 128, 128]),
    width: 3,
    height: 3,
    channels: 1
}, imageName);

// move it to a long path directory
const dirPath = path.join("./", ...[
    "a".repeat(100), "b".repeat(100), "c".repeat(100), "d".repeat(100)
]);
await fs.mkdir(dirPath, {recursive: true});

const newPath = path.join(dirPath, imageName);
await fs.rename(imageName, newPath);

// ---

// it works fine
console.log("reading with fs:");
console.log(await getImageDataWithSharp((await fs.readFile(newPath)).buffer));

console.log();

// it throws an error
console.log("reading with sharp:");
try {
    console.log(await getImageDataWithSharp(newPath));
} catch (e) {
    console.log((e as Error).message);
}


// ---

export function saveImageDataWithSharp(imageData: ImageDataLikeEx, outputFilePath: string): Promise<sharp.OutputInfo> {
    const image: sharp.Sharp = sharp(imageData.data, {
        raw: {
            width: imageData.width,
            height: imageData.height,
            channels: imageData.channels ? imageData.channels : 4,
        }
    });
    return image.toFile(outputFilePath);
}

export async function getImageDataWithSharp(inputData: string | ArrayBuffer): Promise<ImageDataLike> {
    const imageData = await sharp(inputData)
        .ensureAlpha()
        .raw()
        .toBuffer({resolveWithObject: true});
    const {data, info} = imageData;
    return {
        width: info.width,
        height: info.height,
        data: new Uint8ClampedArray(data.buffer),
    };
}

type ImageDataLike = {
    data:   Uint8ClampedArray
    width:  number
    height: number
};
type ImageDataLikeEx = {
    data:   Uint8ClampedArray | Uint8Array
    width:  number
    height: number
    channels?: 4 | 1 | 2 | 3
};
reading with fs:
{
  width: 3,
  height: 3,
  data: Uint8ClampedArray(36) [
    255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255,   0,   0,   0, 255,
      0,   0,   0, 255,   0,   0,   0, 255,
    128, 128, 128, 255, 128, 128, 128, 255,
    128, 128, 128, 255
  ]
}

reading with sharp:
Input file is missing: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\image-for-long-path-3x3.png

Please provide sample image(s) that help explain this problem

Generated.

@AlttiRi AlttiRi added the triage label Dec 9, 2024
@AlttiRi
Copy link
Author

AlttiRi commented Dec 9, 2024

BTW, using path.toNamespacedPath(newPath)) also helps.
It simply resolves the path to absolute one and prepends \\?\.

@lovell lovell added question and removed triage labels Dec 9, 2024
@lovell
Copy link
Owner

lovell commented Dec 9, 2024

Is it still the case that Windows has problems with filesystem paths longer than 260 characters? If so, use of toNamespacedPath is probably the right approach here.

AlttiRi added a commit to AlttiRi/get-image-data that referenced this issue Dec 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants