mhammond / pywin32

Python for Windows (pywin32) Extensions
4.9k stars 783 forks source link

SAFEARRAY(VT_RECORD) missing last element #2247

Closed TeaTimeChimp closed 1 month ago

TeaTimeChimp commented 2 months ago

My COM method call with retval of type SAFEARRAY(VT_RECORD) is missing the last element. Looks like com/win32com/PyRecord.cpp @ lines 74 and (probably) 525 are missing a +1 in the array size calculation - I've changed this locally and it fixes my issue.

Steps to reproduce the problem

Call a method that returns a SAFEARRAY(VT_RECORD) see how the Python list is 1 element short.

System information

Python 3.11

pywin32 version: Lastest installed from PIP + compiled from source.

Windows Version: 11

mhammond commented 2 months ago

It seems to work fine with other COM objects though - can you demonstrate the array element missing from some well-known object (eg, any Office product, Windows Scripting Host, IE, etc?)

TeaTimeChimp commented 2 months ago

To be honest I'm struggling to find a standard library that returns arrays of UDTs - I'll keep looking though - in my case it's an in-house piece of software that's returning the array, For what it's worth, I did a find-in-files for all cases of 'SafeArrayGetUBound' and by inspection all other places appear to treat the result as 'inclusive' whereas PyRecord.cpp treats it as 'exclusive'. E.g. PyCOMImpl.cpp @ 282: *resultSize = ub - lb + 1; // Plus one PyCOMImpl.cpp @ 332: for (long i = lb; i <= ub; i++) { // Less or equal oleargs.cpp @ 736: if ((unsigned long)(exist_ubound - exist_lbound + 1) != pBounds[dimLook - 1].cElements) { // Plus one. oleargs.cpp @ 988: long cElems = ub - lb + 1; // Plus one.

mhammond commented 2 months ago

right, I missed that subtlety - only arrays of records are impacted. So yeah, it does sound like this might be a problem, thanks.