diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c index cabbeb8..71c4f7f 100644 --- a/ext/win32ole/win32ole.c +++ b/ext/win32ole/win32ole.c @@ -929,7 +929,13 @@ ole_mb2wc(char *pm, int len, UINT cp) #endif } size = MultiByteToWideChar(cp, 0, pm, len, NULL, 0); + if (!size) { + ole_raise(HRESULT_LASTERROR(), eWIN32OLERuntimeError, "fail to convert CP%d to Unicode", cp); + } pw = SysAllocStringLen(NULL, size); + if (!pw) { + ole_raise(HRESULT_LASTERROR(), eWIN32OLERuntimeError, "fail to allocate Unicode string"); + } pw[size-1] = 0; MultiByteToWideChar(cp, 0, pm, len, pw, size); return pw; diff --git a/ext/win32ole/win32ole_error.h b/ext/win32ole/win32ole_error.h index a2f3298..01f18d1 100644 --- a/ext/win32ole/win32ole_error.h +++ b/ext/win32ole/win32ole_error.h @@ -6,4 +6,6 @@ extern VALUE eWIN32OLEQueryInterfaceError; NORETURN(PRINTF_ARGS(void ole_raise(HRESULT hr, VALUE ecs, const char *fmt, ...), 3, 4)); void Init_win32ole_error(void); +#define HRESULT_LASTERROR() HRESULT_FROM_WIN32(GetLastError()) + #endif diff --git a/test/win32ole/test_win32ole.rb b/test/win32ole/test_win32ole.rb index e6347e8..55a3127 100644 --- a/test/win32ole/test_win32ole.rb +++ b/test/win32ole/test_win32ole.rb @@ -519,6 +519,15 @@ def test_method_missing assert_raise(ArgumentError) {@dict1.method_missing("foo=")} assert_raise(ArgumentError) {@dict1.method_missing("foo=", 1, 2)} end + + def test_invoke_with_too_long_string + skip = ENV["WIN32OLE_MEMORY_INTENSIVE_TESTS"] + return unless skip + omit "This test creates a 1GiB string" unless skip == "yes" + str = "a" * 0x40000000 + assert_raise(WIN32OLE::RuntimeError) {@dict1.invoke(str)} + assert_raise(WIN32OLE::RuntimeError) {@dict2.invoke(str)} + end end # test of subclass of WIN32OLE