[pypy-commit] pypy default: In the type parser, escape error messages and don't display the

arigo noreply at buildbot.pypy.org
Tue Jun 2 19:28:48 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r77786:f891985cf1f3
Date: 2015-06-02 19:28 +0200
http://bitbucket.org/pypy/pypy/changeset/f891985cf1f3/

Log:	In the type parser, escape error messages and don't display the
	input type if too huge

diff --git a/pypy/module/_cffi_backend/ffi_obj.py b/pypy/module/_cffi_backend/ffi_obj.py
--- a/pypy/module/_cffi_backend/ffi_obj.py
+++ b/pypy/module/_cffi_backend/ffi_obj.py
@@ -95,6 +95,23 @@
             else:
                 raise KeyError    # don't handle this error case here
 
+    def _ffi_bad_type(self, input_text):
+        info = self.ctxobj.info
+        errmsg = rffi.charp2str(info.c_error_message)
+        if len(input_text) > 500:
+            raise oefmt(self.w_FFIError, errmsg)
+        printable_text = ['?'] * len(input_text)
+        for i in range(len(input_text)):
+            if ' ' <= input_text[i] < '\x7f':
+                printable_text[i] = input_text[i]
+            elif input_text[i] == '\t' or input_text[i] == '\n':
+                printable_text[i] = ' '
+        num_spaces = rffi.getintfield(info, 'c_error_location')
+        raise oefmt(self.w_FFIError, "%s\n%s\n%s^",
+                    rffi.charp2str(info.c_error_message),
+                    ''.join(printable_text),
+                    " " * num_spaces)
+
     @jit.dont_look_inside
     def parse_string_to_type(self, string, consider_fn_as_fnptr):
         # This cannot be made @elidable because it calls general space
@@ -108,11 +125,7 @@
             info = self.ctxobj.info
             index = parse_c_type.parse_c_type(info, string)
             if index < 0:
-                num_spaces = rffi.getintfield(info, 'c_error_location')
-                raise oefmt(self.w_FFIError, "%s\n%s\n%s^",
-                            rffi.charp2str(info.c_error_message),
-                            string,
-                            " " * num_spaces)
+                raise self._ffi_bad_type(string)
             x = realize_c_type.realize_c_type_or_func(
                 self, self.ctxobj.info.c_output, index)
             assert x is not None
diff --git a/pypy/module/_cffi_backend/test/test_ffi_obj.py b/pypy/module/_cffi_backend/test/test_ffi_obj.py
--- a/pypy/module/_cffi_backend/test/test_ffi_obj.py
+++ b/pypy/module/_cffi_backend/test/test_ffi_obj.py
@@ -181,6 +181,12 @@
         assert str(e.value) == ("undefined struct/union name\n"
                                 "struct never_heard_of_s\n"
                                 "       ^")
+        e = raises(ffi.error, ffi.cast, "\t\n\x01\x1f~\x7f\x80\xff", 0)
+        assert str(e.value) == ("identifier expected\n"
+                                "  ??~???\n"
+                                "  ^")
+        e = raises(ffi.error, ffi.cast, "X" * 600, 0)
+        assert str(e.value) == ("undefined type name")
 
     def test_ffi_buffer(self):
         import _cffi_backend as _cffi1_backend


More information about the pypy-commit mailing list