[issue46966] c_void_p array is a footgun on I32LP64 systems

2022-03-09 Thread JP Sugarbroad


JP Sugarbroad  added the comment:

That matches our expectation. A subclass works - perhaps `c_void_p` could be 
deprecated in favor of a built-in subclass for generic opaque pointers as well?

Glad you agree that a warning would be useful here.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46966] c_void_p array is a footgun on I32LP64 systems

2022-03-09 Thread Eryk Sun


Eryk Sun  added the comment:

> I'm not sure what can be done here (maybe a truncation warning?)

For a function pointer, the default argument conversion for Python integers is 
the platform int type. Ideally, Python integer arguments would be converted to 
a type that matches the platform word size, as is the default behavior for 
integer arguments in C. But the behavior can't be changed at this point. 
Ideally, it would behave the same in LP64 (Unix) and LLP64 (Windows) systems, 
but OverflowError is raised in LLP64 because ctypes first converts to a long 
int. OverflowError could be manually raised if `(unsigned long)value > 
UINT_MAX`, but I think it's also too late to make that change. Scripts have 
worked around the current behavior for about two decades. Raising a warning is 
really the best that could be done, if anything is done at all.

The best solution is to not use bare function pointers without setting the 
prototype. If a function pointer is created as an attribute of a CDLL instance, 
the common way to define the prototype is by setting the function's `argtypes` 
and `restype` attributes.

Another ctypes concept to be aware of is that subclasses of simple types do not 
get converted by default when accessed as C fields, array subscripts, or 
function results. For example:

class my_void_p(ctypes.c_void_p):
pass

>>> a = (my_void_p * 1)()
>>> isinstance(a[0], my_void_p)
True

--
nosy: +eryksun
versions:  -Python 3.7, Python 3.8

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46966] c_void_p array is a footgun on I32LP64 systems

2022-03-08 Thread JP Sugarbroad


New submission from JP Sugarbroad :

The following code will likely crash on I32LP64 systems:

dim = lib.get_array_size(opaque)
ptrs = (c_void_p * dim)()
lib.get_array_values(opaque, ptrs)
for ptr in ptrs:
print(lib.get_object_value(ptr))

What happens is that `ptr` is not a `c_void_p` -- it's just a bare number. And 
when it's passed to another function it goes in as a (32-bit) `c_int`, 
resulting in a truncation.

I'm not sure what can be done here (maybe a truncation warning?) but it's 
definitely a difficult bug to notice when reviewing code.

--
components: ctypes
messages: 414783
nosy: taralx
priority: normal
severity: normal
status: open
title: c_void_p array is a footgun on I32LP64 systems
type: behavior
versions: Python 3.10, Python 3.11, Python 3.7, Python 3.8, Python 3.9

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com