[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[pygame] Intermittent failure of surfarray.make_surface



I get this error every so often when trying to use surfarray.make_surface:

Traceback (most recent call last):
  [...]
  File "/home/weeble/py/minecraft_mapping/tilemapping.py", line 348,
in hacky_map_render
    resources = make_resources(pygame.surfarray.make_surface(pixels))
  File "/usr/local/lib/python2.6/dist-packages/pygame/surfarray.py",
line 243, in make_surface
    return numpysf.make_surface (array)
  File "/usr/local/lib/python2.6/dist-packages/pygame/_numpysurfarray.py",
line 368, in make_surface
    blit_array (surface, array)
  File "/usr/local/lib/python2.6/dist-packages/pygame/_numpysurfarray.py",
line 437, in blit_array
    surface.get_buffer ().write (data, 0)
IndexError: bytes to write exceed buffer size

I've put some print statements into _numpysurfarray.py and the length
of the buffer and the length of data are always identical. I think the
problem is in bufferproxy.c:

/**
 * Writes raw data to the buffer.
 */
static PyObject*
_bufferproxy_write (PyBufferProxy *buffer, PyObject *args)
{
    Py_ssize_t offset;
    Py_ssize_t length;
    char *buf;

    if (!PyArg_ParseTuple (args, "s#i", &buf, &length, &offset))
        return NULL;

    if (offset + length > buffer->length)
    {
        return RAISE (PyExc_IndexError, "bytes to write exceed buffer size");
    }

    memcpy (((Uint8 *)buffer->buffer) + offset, buf, (size_t) length);

    Py_RETURN_NONE;
}

Here offset is defined as a Py_ssize_t, but I believe the "i" format
tells PyArg_ParseTuple to expect an int. On most 64-bit platforms,
sizeof(int)==4 and I believe sizeof(Py_ssize_t)==8. It looks to me
like part of offset is left uninitialized, resulting in the error if
it happens not to be 0. Is my analysis correct?