GNOME Bugzilla – Bug 669594
bug in gspawn sequence-of-strings checking
Last modified: 2012-02-07 20:24:01 UTC
this will cause a segfault: from gi.repository import GLib import os GLib.spawn_async (argv=['echo', 'hello'], envp=os.environ) when this is okay: GLib.spawn_async (argv=['echo', 'hello'], envp=[]) and this is okay (and is properly detected as an error): GLib.spawn_async (argv=['echo', 'hello'], envp={}) It appears that os.environ has some weird type that's not quite a dict that's tripping up the detection code here. That's a problem for people who try to pass os.environ to envp thinking that it's a reasonable thing to do: we need to give them a proper error message in that case, not a segfault.
Created attachment 207014 [details] [review] pygspawn: improve error checking gspawn 'argv' and 'envp' parameters expect sequences of strings. This is enforced by checking that the passed argument is a sequence and that each item returned from it is a string. We do now, however, verify that each item can be successfully taken from the sequence. 'os.environ' is an example of an object that passes PySequence_Check() but fails to return objects from PySequence_ITEM(). Add a simple NULL check to avoid the crash.
I did a quick check for PySequence_ITEM and PySequence_GetItem and no other code in _glib/ is calling either of those, so it seems that this particular class of problem is limited to the gspawn code.
Review of attachment 207014 [details] [review]: Patch is obviously correct: py docs say that _ITEM can return null so we must be robust, besides we even use xdecref already. I am not sure why this happens with os.environ and not with a dict though... Oh well :-)
Attachment 207014 [details] pushed as 945fd18 - pygspawn: improve error checking
(In reply to comment #3) > I am not sure why this happens with os.environ and not with a dict though... Oh > well :-) os.environ is a os._Environ instance which is a UserDict.UserDict subclass. UserDict looks like but is not a dict and doesn't really offer much value on modern Python 2 versions, it is kept for backwards compatibility with pre Python 2.2 (iirc) code where builtin types couldn't be subclassed. At long last, UserDict was removed in Python 3.