diff --git a/binding.gyp b/binding.gyp index a2a400ed..c57935ed 100644 --- a/binding.gyp +++ b/binding.gyp @@ -39,6 +39,7 @@ 'VCCLCompilerTool': { 'ExceptionHandling': 1, 'Optimization': 1, + 'RuntimeLibrary': '2', # /MD 'WholeProgramOptimization': 'true' }, 'VCLibrarianTool': { @@ -205,6 +206,7 @@ 'VCCLCompilerTool': { 'ExceptionHandling': 1, 'Optimization': 1, + 'RuntimeLibrary': '2', # /MD 'WholeProgramOptimization': 'true' }, 'VCLibrarianTool': { diff --git a/src/sharp.cc b/src/sharp.cc index f76a5cb0..f83e7be0 100644 --- a/src/sharp.cc +++ b/src/sharp.cc @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include "common.h" @@ -21,6 +22,14 @@ #include "utilities.h" #include "stats.h" +#if defined(_MSC_VER) && _MSC_VER >= 1400 // MSVC 2005/8 +static void empty_invalid_parameter_handler(const wchar_t* expression, + const wchar_t* function, const wchar_t* file, unsigned int line, + uintptr_t reserved) { + // No-op. +} +#endif + static void* sharp_vips_init(void*) { g_setenv("VIPS_MIN_STACK_SIZE", "2m", FALSE); vips_init("sharp"); @@ -34,6 +43,13 @@ Napi::Object init(Napi::Env env, Napi::Object exports) { g_log_set_handler("VIPS", static_cast(G_LOG_LEVEL_WARNING), static_cast(sharp::VipsWarningCallback), nullptr); + // Tell the CRT to not exit the application when an invalid parameter is + // passed. The main issue is that invalid FDs will trigger this behaviour. + // See: https://github.com/libvips/libvips/pull/2571. +#if defined(_MSC_VER) && _MSC_VER >= 1400 // MSVC 2005/8 + _set_invalid_parameter_handler(empty_invalid_parameter_handler); +#endif + // Methods available to JavaScript exports.Set("metadata", Napi::Function::New(env, metadata)); exports.Set("pipeline", Napi::Function::New(env, pipeline)); diff --git a/test/unit/io.js b/test/unit/io.js index e0266316..258b42b4 100644 --- a/test/unit/io.js +++ b/test/unit/io.js @@ -797,6 +797,19 @@ describe('Input/output', function () { }); }); + it('Fails when writing to missing directory', async () => { + const create = { + width: 8, + height: 8, + channels: 3, + background: { r: 0, g: 0, b: 0 } + }; + await assert.rejects( + () => sharp({ create }).toFile('does-not-exist/out.jpg'), + /unable to open for write/ + ); + }); + describe('create new image', function () { it('RGB', function (done) { const create = {