[pypy-commit] pypy default: Merged in zyv/pypy (pull request #194)

fijal noreply at buildbot.pypy.org
Wed Oct 9 10:52:41 CEST 2013


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: 
Changeset: r67231:798905aca6f1
Date: 2013-10-09 10:51 +0200
http://bitbucket.org/pypy/pypy/changeset/798905aca6f1/

Log:	Merged in zyv/pypy (pull request #194)

	Fix segfaults when encoding is NULL in CPyExt Unicode functions

diff --git a/pypy/module/cpyext/test/test_unicodeobject.py b/pypy/module/cpyext/test/test_unicodeobject.py
--- a/pypy/module/cpyext/test/test_unicodeobject.py
+++ b/pypy/module/cpyext/test/test_unicodeobject.py
@@ -91,6 +91,7 @@
         invalid = rffi.str2charp('invalid')
         utf_8 = rffi.str2charp('utf-8')
         prev_encoding = rffi.str2charp(space.unwrap(w_default_encoding))
+        self.raises(space, api, TypeError, api.PyUnicode_SetDefaultEncoding, lltype.nullptr(rffi.CCHARP.TO))
         assert api.PyUnicode_SetDefaultEncoding(invalid) == -1
         assert api.PyErr_Occurred() is space.w_LookupError
         api.PyErr_Clear()
@@ -316,6 +317,15 @@
         rffi.free_charp(b_text)
         rffi.free_charp(b_encoding)
 
+    def test_decode_null_encoding(self, space, api):
+        null_charp = lltype.nullptr(rffi.CCHARP.TO)
+        u_text = u'abcdefg'
+        s_text = space.str_w(api.PyUnicode_AsEncodedString(space.wrap(u_text), null_charp, null_charp))
+        b_text = rffi.str2charp(s_text)
+        assert space.unwrap(api.PyUnicode_Decode(b_text, len(s_text), null_charp, null_charp)) == u_text
+        self.raises(space, api, TypeError, api.PyUnicode_FromEncodedObject, space.wrap(u_text), null_charp, None)
+        rffi.free_charp(b_text)
+
     def test_leak(self):
         size = 50
         raw_buf, gc_buf = rffi.alloc_buffer(size)
diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -273,6 +273,8 @@
 def PyUnicode_SetDefaultEncoding(space, encoding):
     """Sets the currently active default encoding. Returns 0 on
     success, -1 in case of an error."""
+    if not encoding:
+        PyErr_BadArgument(space)
     w_encoding = space.wrap(rffi.charp2str(encoding))
     setdefaultencoding(space, w_encoding)
     default_encoding[0] = '\x00'
@@ -350,8 +352,11 @@
     in the unicode() built-in function.  The codec to be used is looked up
     using the Python codec registry.  Return NULL if an exception was raised by
     the codec."""
+    if not encoding:
+        # This tracks CPython 2.7, in CPython 3.4 'utf-8' is hardcoded instead
+        encoding = PyUnicode_GetDefaultEncoding(space)
+    w_encoding = space.wrap(rffi.charp2str(encoding))
     w_str = space.wrap(rffi.charpsize2str(s, size))
-    w_encoding = space.wrap(rffi.charp2str(encoding))
     if errors:
         w_errors = space.wrap(rffi.charp2str(errors))
     else:
@@ -379,6 +384,9 @@
 
     All other objects, including Unicode objects, cause a TypeError to be
     set."""
+    if not encoding:
+        raise OperationError(space.w_TypeError,
+                             space.wrap("decoding Unicode is not supported"))
     w_encoding = space.wrap(rffi.charp2str(encoding))
     if errors:
         w_errors = space.wrap(rffi.charp2str(errors))


More information about the pypy-commit mailing list