Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r2158:fa3cf2db4a04
Date: 2015-06-02 19:22 +0200
http://bitbucket.org/cffi/cffi/changeset/fa3cf2db4a04/

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

diff --git a/c/ffi_obj.c b/c/ffi_obj.c
--- a/c/ffi_obj.c
+++ b/c/ffi_obj.c
@@ -140,6 +140,38 @@
 #define ACCEPT_ALL      (ACCEPT_STRING | ACCEPT_CTYPE | ACCEPT_CDATA)
 #define CONSIDER_FN_AS_FNPTR  8
 
+static CTypeDescrObject *_ffi_bad_type(FFIObject *ffi, char *input_text)
+{
+    size_t length = strlen(input_text);
+    char *extra;
+
+    if (length > 500) {
+        extra = "";
+    }
+    else {
+        char *p;
+        size_t i, num_spaces = ffi->info.error_location;
+        extra = alloca(length + num_spaces + 4);
+        p = extra;
+        *p++ = '\n';
+        for (i = 0; i < length; i++) {
+            if (' ' <= input_text[i] && input_text[i] < 0x7f)
+                *p++ = input_text[i];
+            else if (input_text[i] == '\t' || input_text[i] == '\n')
+                *p++ = ' ';
+            else
+                *p++ = '?';
+        }
+        *p++ = '\n';
+        memset(p, ' ', num_spaces);
+        p += num_spaces;
+        *p++ = '^';
+        *p++ = 0;
+    }
+    PyErr_Format(FFIError, "%s%s", ffi->info.error_message, extra);
+    return NULL;
+}
+
 static CTypeDescrObject *_ffi_type(FFIObject *ffi, PyObject *arg,
                                    int accept)
 {
@@ -153,15 +185,9 @@
         if (x == NULL) {
             char *input_text = PyText_AS_UTF8(arg);
             int err, index = parse_c_type(&ffi->info, input_text);
-            if (index < 0) {
-                size_t num_spaces = ffi->info.error_location;
-                char *spaces = alloca(num_spaces + 1);
-                memset(spaces, ' ', num_spaces);
-                spaces[num_spaces] = '\0';
-                PyErr_Format(FFIError, "%s\n%s\n%s^", ffi->info.error_message,
-                             input_text, spaces);
-                return NULL;
-            }
+            if (index < 0)
+                return _ffi_bad_type(ffi, input_text);
+
             x = realize_c_type_or_func(&ffi->types_builder,
                                        ffi->info.output, index);
             if (x == NULL)
diff --git a/testing/cffi1/test_ffi_obj.py b/testing/cffi1/test_ffi_obj.py
--- a/testing/cffi1/test_ffi_obj.py
+++ b/testing/cffi1/test_ffi_obj.py
@@ -158,6 +158,12 @@
     assert str(e.value) == ("undefined struct/union name\n"
                             "struct never_heard_of_s\n"
                             "       ^")
+    e = py.test.raises(ffi.error, ffi.cast, "\t\n\x01\x1f~\x7f\x80\xff", 0)
+    assert str(e.value) == ("identifier expected\n"
+                            "  ??~???\n"
+                            "  ^")
+    e = py.test.raises(ffi.error, ffi.cast, "X" * 600, 0)
+    assert str(e.value) == ("undefined type name")
 
 def test_ffi_buffer():
     ffi = _cffi1_backend.FFI()
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to