There were a few I'm attempting to fix in zts_py_recv():
Was allocating a static buffer of 4096, but taking whatever
length the user passed in. This change allocates a PyBytes
object of the size the user requests.
Was converting to a string without giving a size. Which probably
led to the UnicodeDecodeError I was seeing below, trying to
decode a character beyond the received bytes. Would also lead
to problems reading binary data that included embedded NULs.
Used the number of bytes received as the size of the returned data.
Variable "err" was being used, changed that to "bytes_read" as
that's what lwip_recv() returns, with <0 bytes read indicating
error.
Read data was being returned as a Unicode string, leading to this
response when I tried talking to my SSH server:
UnicodeDecodeError: 'utf-8' codec can't decode
byte 0xa1 in position 42: invalid start byte
My ssh banner is 40 bytes long, so I think position 42 was outside
the received buffer. Changed it to a PyBytes response as is
normal for network data. This code was cribbed from the Python
socketmodule
This was producing this error, as it was still returning the tuple:
SystemError: <built-in function zts_py_recv> returned a
result with an error set
This indicates that the UnicodeDecodeError had set an exception,
but a tuple was being returned instead of NULL.
In the case of a lwip_recv() error, the error response was not
being sent back to the wrapper code. Instead, a "return NULL;"
was done. I changed this case to return the tuple (err, None)
to the wrapper.
NOTE: this code built using "./build.sh host-python release", but
there was some sort of build problem I didn't understand which
produced a _libzt.so that I couldn't import, due to:
ImportError: dynamic module does not define module export
function (PyInit__libzt)
So I don't have a way to test these changes.
Store a reference to the unmanaged delegate so that the c# garbage collector doesn't wipe it out which causes a hard crash since the unmanaged dll is still referencing it.