Segmentation Fault on writeRequestData
Installed Packages
Name : python3-cups
Version : 2.0.1
Release : 10.fc34
Architecture : x86_64
Source : python-cups-2.0.1-10.fc34.src.rpm
> ipython
Python 3.9.7 (default, Aug 30 2021, 00:00:00)
In [1]: import cups
In [2]: con = cups.Connection()
In [3]: con.getPrinters()
Out[3]:
{'ps': {'printer-is-shared': True,
'printer-state': 3,
...
In [6]: con.createJob('ps', 'python-job', {})
Out[6]: 101
In [7]: con.startDocument('ps', 101, 'python-doc', 'text/plain', 1)
Out[7]: 100
In [8]: con.writeRequestData('foobartaz', 3)
zsh: segmentation fault (core dumped) ipython
I'm not sure what 100 means as the return of startDocument -- I might be doing something wrong...
I experienced the same bug, and even worse, sometimes cups transferred parts of my document and parts of other strings from my application (including snippets of python source code) to the cups server. So there seems to something from in the memory management of that function.
I am on version 1.9.73 though, so this seems to be present in several versions. The crash for me happens at the invocation of strdup which is not present anymore in master (and which also explains why the lib transfers only parts of my file since strdup stops at the first '\0' byte). It crashed because a NULL pointer was passed. This can indeed also happen in the current version:
I had a look at the source code:
- One big issue is definitely that the size of the buffer is taken from the python side — which means that memory safety depends on passing the right arguments from python, which it should not. So I would suggest to ignore the
lengthparameter altogether and rely onPyBytes_Size()instead. Until this happens, users MUST pass a valid length that matches the length of the bytestring. - The return value of
PyBytes_AsString()is not checked. As the documentation on PyBytes_AsString points out, the function returnsNULLon error. This actually caused my crash. - As you asked: The
100you are seeing is simply the HTTP code returned by the request;100means "CONTINUE", so everything is fine in this and only in this case.
My stacktrace for reference:
#0 __strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:120
#1 0x00007f759e465dae in __GI___strdup (s=0x0) at strdup.c:41
#2 0x00007f759bb6d69a in Connection_writeRequestData (self=0x7f759ab782a0, args=<optimized out>, kwds=<optimized out>) at cupsconnection.c:2064
#3 0x00000000004d7914 in _PyMethodDef_RawFastCallKeywords (kwnames=<optimized out>, nargs=<optimized out>, args=<optimized out>,
self=<cups.Connection at remote 0x7f759ab782a0>, method=0x7f759bd8bfc0 <Connection_methods+1728>) at ../Objects/call.c:690