Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34k
gh-126742: allow to use non-UTF8 exception messages#126746
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
24eb5214c0f85bf432dc9434cf5b48238fca38105b714dcb7ee1f3c63d71f6b1a23bf516a98a25a150d2074bd4c7f3a9091a321f9f5813a984afad2166a7367c9a793314c9f1571de052633d1845442c36bedc4b6f9ee0bb02a71547d50b8574184c4fecd7626f074ccb4d5e46798f21ce8ae028d442a3f06d6a51c052503d69de1a0795118618de89bc40121ea0f7309d60f4a5722b15fc2e1762db957c665a2d765e16cFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,12 @@ | ||
| import _ctypes | ||
| import os | ||
| import platform | ||
| import sys | ||
| import test.support | ||
| import unittest | ||
| import platform | ||
| from ctypes import CDLL, c_int | ||
| from ctypes.util import find_library | ||
| FOO_C = r""" | ||
| #include <unistd.h> | ||
| @@ -26,7 +31,7 @@ | ||
| @unittest.skipUnless(sys.platform.startswith('linux'), | ||
| 'Test only valid for Linux') | ||
| 'test requires GNU IFUNC support') | ||
| class TestNullDlsym(unittest.TestCase): | ||
| """GH-126554: Ensure that we catch NULL dlsym return values | ||
| @@ -53,14 +58,6 @@ def test_null_dlsym(self): | ||
| import subprocess | ||
| import tempfile | ||
| # To avoid ImportErrors on Windows, where _ctypes does not have | ||
| # dlopen and dlsym, | ||
| # import here, i.e., inside the test function. | ||
| # The skipUnless('linux') decorator ensures that we're on linux | ||
| # if we're executing these statements. | ||
| from ctypes import CDLL, c_int | ||
| from _ctypes import dlopen, dlsym | ||
| retcode = subprocess.call(["gcc", "--version"], | ||
| stdout=subprocess.DEVNULL, | ||
| stderr=subprocess.DEVNULL) | ||
| @@ -111,6 +108,8 @@ def test_null_dlsym(self): | ||
| self.assertEqual(os.read(pipe_r, 2), b'OK') | ||
| # Case #3: Test 'py_dl_sym' from Modules/_ctypes/callproc.c | ||
| dlopen = test.support.get_attribute(_ctypes, 'dlopen') | ||
| dlsym = test.support.get_attribute(_ctypes, 'dlsym') | ||
| L = dlopen(dstname) | ||
| with self.assertRaisesRegex(OSError, "symbol 'foo' not found"): | ||
| dlsym(L, "foo") | ||
| @@ -119,5 +118,66 @@ def test_null_dlsym(self): | ||
| self.assertEqual(os.read(pipe_r, 2), b'OK') | ||
| @unittest.skipUnless(os.name != 'nt', 'test requires dlerror() calls') | ||
| class TestLocalization(unittest.TestCase): | ||
| @staticmethod | ||
| def configure_locales(func): | ||
| return test.support.run_with_locale( | ||
picnixz marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading. Please reload this page. | ||
| 'LC_ALL', | ||
| 'fr_FR.iso88591', 'ja_JP.sjis', 'zh_CN.gbk', | ||
| 'fr_FR.utf8', 'en_US.utf8', | ||
| '', | ||
| )(func) | ||
| @classmethod | ||
| def setUpClass(cls): | ||
| cls.libc_filename = find_library("c") | ||
| @configure_locales | ||
| def test_localized_error_from_dll(self): | ||
| dll = CDLL(self.libc_filename) | ||
| with self.assertRaises(AttributeError) as cm: | ||
| dll.this_name_does_not_exist | ||
| if sys.platform.startswith('linux'): | ||
| # On macOS, the filename is not reported by dlerror(). | ||
| self.assertIn(self.libc_filename, str(cm.exception)) | ||
| @configure_locales | ||
| def test_localized_error_in_dll(self): | ||
| dll = CDLL(self.libc_filename) | ||
| with self.assertRaises(ValueError) as cm: | ||
| c_int.in_dll(dll, 'this_name_does_not_exist') | ||
| if sys.platform.startswith('linux'): | ||
| # On macOS, the filename is not reported by dlerror(). | ||
| self.assertIn(self.libc_filename, str(cm.exception)) | ||
| @unittest.skipUnless(hasattr(_ctypes, 'dlopen'), | ||
| 'test requires _ctypes.dlopen()') | ||
| @configure_locales | ||
| def test_localized_error_dlopen(self): | ||
| missing_filename = b'missing\xff.so' | ||
| # Depending whether the locale, we may encode '\xff' differently | ||
| # but we are only interested in avoiding a UnicodeDecodeError | ||
| # when reporting the dlerror() error message which contains | ||
| # the localized filename. | ||
| filename_pattern = r'missing.*?\.so' | ||
| with self.assertRaisesRegex(OSError, filename_pattern): | ||
| _ctypes.dlopen(missing_filename, 2) | ||
| @unittest.skipUnless(hasattr(_ctypes, 'dlopen'), | ||
| 'test requires _ctypes.dlopen()') | ||
| @unittest.skipUnless(hasattr(_ctypes, 'dlsym'), | ||
| 'test requires _ctypes.dlsym()') | ||
picnixz marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading. Please reload this page. | ||
| @configure_locales | ||
| def test_localized_error_dlsym(self): | ||
| dll = _ctypes.dlopen(self.libc_filename) | ||
| with self.assertRaises(OSError) as cm: | ||
| _ctypes.dlsym(dll, 'this_name_does_not_exist') | ||
| if sys.platform.startswith('linux'): | ||
| # On macOS, the filename is not reported by dlerror(). | ||
| self.assertIn(self.libc_filename, str(cm.exception)) | ||
| if __name__ == "__main__": | ||
| unittest.main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,11 @@ | ||
| from test import support | ||
| from test.support import import_helper, cpython_only | ||
| gdbm = import_helper.import_module("dbm.gnu") #skip if not supported | ||
| import unittest | ||
| import os | ||
| from test.support.os_helper import TESTFN, TESTFN_NONASCII, unlink, FakePath | ||
| import unittest | ||
| from test import support | ||
| from test.support import cpython_only, import_helper | ||
| from test.support.os_helper import (TESTFN, TESTFN_NONASCII, FakePath, | ||
| create_empty_file, temp_dir, unlink) | ||
| gdbm = import_helper.import_module("dbm.gnu") # skip if not supported | ||
| filename = TESTFN | ||
| @@ -205,6 +206,16 @@ def test_clear(self): | ||
| self.assertNotIn(k, db) | ||
| self.assertEqual(len(db), 0) | ||
| @support.run_with_locale( | ||
picnixz marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading. Please reload this page. | ||
| 'LC_ALL', | ||
| 'fr_FR.iso88591', 'ja_JP.sjis', 'zh_CN.gbk', | ||
| 'fr_FR.utf8', 'en_US.utf8', | ||
| '', | ||
| ) | ||
| def test_localized_error(self): | ||
| with temp_dir() as d: | ||
| create_empty_file(os.path.join(d, 'test')) | ||
| self.assertRaises(gdbm.error, gdbm.open, filename, 'r') | ||
| if __name__ == '__main__': | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -984,15 +984,8 @@ CDataType_in_dll_impl(PyObject *type, PyTypeObject *cls, PyObject *dll, | ||
| #ifdef USE_DLERROR | ||
| const char *dlerr = dlerror(); | ||
| if (dlerr){ | ||
| PyObject *message = PyUnicode_DecodeLocale(dlerr, "surrogateescape"); | ||
| if (message){ | ||
| PyErr_SetObject(PyExc_ValueError, message); | ||
| Py_DECREF(message); | ||
| return NULL; | ||
| } | ||
| // Ignore errors from PyUnicode_DecodeLocale, | ||
| // fall back to the generic error below. | ||
| PyErr_Clear(); | ||
| _PyErr_SetLocaleString(PyExc_ValueError, dlerr); | ||
picnixz marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading. Please reload this page. | ||
| return NULL; | ||
| } | ||
| #endif | ||
| #undef USE_DLERROR | ||
| @@ -3805,21 +3798,14 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) | ||
| address = (PPROC)dlsym(handle, name); | ||
| if (!address){ | ||
| #ifdef USE_DLERROR | ||
| #ifdef USE_DLERROR | ||
| const char *dlerr = dlerror(); | ||
| if (dlerr){ | ||
| PyObject *message = PyUnicode_DecodeLocale(dlerr, "surrogateescape"); | ||
| if (message){ | ||
| PyErr_SetObject(PyExc_AttributeError, message); | ||
| Py_DECREF(ftuple); | ||
| Py_DECREF(message); | ||
| return NULL; | ||
| } | ||
| // Ignore errors from PyUnicode_DecodeLocale, | ||
| // fall back to the generic error below. | ||
| PyErr_Clear(); | ||
| _PyErr_SetLocaleString(PyExc_AttributeError, dlerr); | ||
picnixz marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading. Please reload this page. | ||
| Py_DECREF(ftuple); | ||
| return NULL; | ||
| } | ||
| #endif | ||
| #endif | ||
| PyErr_Format(PyExc_AttributeError, "function '%s' not found", name); | ||
| Py_DECREF(ftuple); | ||
| return NULL; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -3,6 +3,7 @@ | ||
| #include "parts.h" | ||
| #include "util.h" | ||
| #include "clinic/exceptions.c.h" | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.