1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

win32ole.c: ID overflow

* ext/win32ole/win32ole.c (GetIDsOfNames): check ID overflow against
  DISPID, aka LONG, which is always 4 bytes.

* ext/win32ole/win32ole.c (Invoke): use ID for method name to get rid
  of losing upper bits.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42674 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2013-08-23 14:09:49 +00:00
parent 282bbea0d9
commit fb9b9b1862

View file

@ -764,8 +764,10 @@ static HRESULT ( STDMETHODCALLTYPE GetIDsOfNames )(
Win32OLEIDispatch* p = (Win32OLEIDispatch*)This; Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
*/ */
char* psz = ole_wc2mb(*rgszNames); // support only one method char* psz = ole_wc2mb(*rgszNames); // support only one method
*rgDispId = rb_intern(psz); ID nameid = rb_intern(psz);
free(psz); free(psz);
if ((ID)(DISPID)nameid != nameid) return E_NOINTERFACE;
*rgDispId = (DISPID)nameid;
return S_OK; return S_OK;
} }
@ -785,17 +787,18 @@ static /* [local] */ HRESULT ( STDMETHODCALLTYPE Invoke )(
int args = pDispParams->cArgs; int args = pDispParams->cArgs;
Win32OLEIDispatch* p = (Win32OLEIDispatch*)This; Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
VALUE* parg = ALLOCA_N(VALUE, args); VALUE* parg = ALLOCA_N(VALUE, args);
ID mid = (ID)dispIdMember;
for (i = 0; i < args; i++) { for (i = 0; i < args; i++) {
*(parg + i) = ole_variant2val(&pDispParams->rgvarg[args - i - 1]); *(parg + i) = ole_variant2val(&pDispParams->rgvarg[args - i - 1]);
} }
if (dispIdMember == DISPID_VALUE) { if (dispIdMember == DISPID_VALUE) {
if (wFlags == DISPATCH_METHOD) { if (wFlags == DISPATCH_METHOD) {
dispIdMember = rb_intern("call"); mid = rb_intern("call");
} else if (wFlags & DISPATCH_PROPERTYGET) { } else if (wFlags & DISPATCH_PROPERTYGET) {
dispIdMember = rb_intern("value"); mid = rb_intern("value");
} }
} }
v = rb_funcall2(p->obj, dispIdMember, args, parg); v = rb_funcall2(p->obj, mid, args, parg);
ole_val2variant(v, pVarResult); ole_val2variant(v, pVarResult);
return S_OK; return S_OK;
} }