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
Long filename crashes dzsave #184
Comments
I assume this was tested on Windows since you're using the /cc @jcupitt |
Yes, Windows has the character limit. |
I believe Windows has a separate API which can handle long paths on some filesystems, but it's not very well supported. Explorer, for example, will fail for long paths, and node on windows is always struggling with this. My understanding is that it's simplest just to avoid deep directory structures on Windows. (I could be very out of date here, perhaps this has been improved since I was last bitten by it) |
I'd be a bit surprised if dzsave is crashing, I think it checks all return values. I would suspect libgsf (all software devs are always certain it's someone else's fault haha). Someone brave would need to investigate. |
... as a workaround, you could save to a zip container instead of the filesystem. It would avoid all filename length issues, and it's much faster, since you avoid the large file creation overhead on win. It'll make better use of your disc space too. |
I tried on my win VM with the openslide tests data here: https://openslide.cs.cmu.edu/download/openslide-testdata/Aperio/
So zip output is about 2x faster, on this machine anyway. |
Thanks for the hint to the zip container. |
Windows file creation has got a lot quicker over the last 10 years or so (zip output used to be 5x faster, ouch), but it's still a bit sluggish. You'll find you need noticeably less disc space with zip too, and it's not because of compression (dzsave zips are uncompressed). JPEG tiles from dzsave are typically ~2kb, so NTFS will store each in a separate 4kb disc sector, leaving 2kb unused. Zip output puts them all end to end in one file, so each disc sector is filled. You can expect maybe a 30% saving in disc space if you count allocated sectors. You often don't need to unzip them. Because they are uncompressed, most zip libraries (eg. the standard python one) will be able to fetch a tile with a one seek and one read. |
I could reproduce this on my Windows PC. Somehow the directory is not created at all, so perhaps it's (silently) failing on this line(?): Though, I'll have another look tomorrow. It could also be a security feature of UCRT (Universal C Runtime in Windows) which llvm-mingw uses by default. |
It can return `NULL` when it exceeds the path limits. See: kleisauke/net-vips#184
Details#include <assert.h>
#include <stdio.h>
#include <errno.h>
#include <glib.h>
int main(int argc, char **argv) {
if (argc != 2) {
printf("usage: %s dirname", argv[0]);
return 1;
}
GDir *dir;
int ret;
ret = g_mkdir(argv[1], 0777);
assert(errno == 0);
assert(ret == 0);
dir = g_dir_open(argv[1], 0, NULL);
assert(dir != NULL);
g_dir_close(dir);
return 0;
} Compile with: PS> cd C:\Users\kleisauke
PS> cl /Zi /MTd /IC:\vips-dev-8.14\include\glib-2.0 /IC:\vips-dev-8.14\lib\glib-2.0\include test.c /link /libpath:C:\vips-dev-8.14\lib libglib-2.0.lib Test with: PS> test.exe short
PS> test.exe longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong
PS> copy test.exe C:\Users\kleisauke\net-vips\samples\NetVips.Samples\bin\x64\Release\net7.0
1 file(s) copied.
PS> cd C:\Users\kleisauke\net-vips\samples\NetVips.Samples\bin\x64\Release\net7.0
PS> test.exe short
PS> test.exe longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong
PS> mkdir another_subdir
PS> copy test.exe another_subdir
PS> cd another_subdir
PS> test.exe short
PS> test.exe longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong
Assertion failed: ret == 0, file test.c, line 18 This means that With that PR and when applying this patch: @@ -8,6 +8,14 @@ Console.WriteLine("short success");
Directory.Delete(shortFileName + "_files", true);
string longFileName = "longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong";
-image.Dzsave(longFileName);
+try
+{
+ image.Dzsave(longFileName);
+}
+catch (VipsException e)
+{
+ Console.WriteLine($"{e.Message}");
+ throw;
+}
Console.WriteLine("long success");
Directory.Delete(longFileName + "_files", true); I now see:
And the program terminates with a proper exception instead. Thanks for reporting this! It'll be in libvips 8.14, due RSN. |
It can return `NULL` when it exceeds the path limits. See: kleisauke/net-vips#184
Nice find @kleisauke ! So yes (ahem), I was wrong, it was libvips's fault. |
A release candidate of NetVips.Native v8.14.0 is now available for testing. |
NetVips v2.3.0 and NetVips.Native v8.14.2 is now available. |
Using long filenames (>~230 characters) crashes the
Image.Dzsave
method without an exception - it actually crashes the whole application without any warning or exception.Example code:
Output:
csrpoj:
Test image file:
The text was updated successfully, but these errors were encountered: