Repository: python/cpython
Pull request: gh-105979: Fix exception handling in `unmarshal_frozen_code` (`Python/import.c`)
Fixes #105979

Clear exception that is set in `PyMarshal_ReadObjectFromString` when it fails to unmarshal given data. It will prevent calling `PyUnicode_FromFormat` in `set_frozen_error` with exception set

<!-- gh-issue-number: gh-105979 -->
* Issue: gh-105979
<!-- /gh-issue-number -->


Problem statement:
Assertion failure in `_imp.get_frozen_object` if data object contains bad marshal data
Repro:
```python
import _imp
>>> _imp.get_frozen_object('x', b"6\'\xd5Cu\x12")
```
Output:
```
python: Objects/object.c:541: PyObject_Repr: Assertion `!_PyErr_Occurred(tstate)' failed.
Aborted (core dumped)
```
I'll submit a PR.

<!-- gh-linked-prs -->
### Linked PRs
* gh-105980
* gh-106055
* gh-106100
<!-- /gh-linked-prs -->

Hints from issue discussion:

Commit message: 📜🤖 Added by blurb_it.

Patch to review:
diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py
index f2726da203efbd..e0e2354ae2f19f 100644
--- a/Lib/test/test_import/__init__.py
+++ b/Lib/test/test_import/__init__.py
@@ -23,6 +23,7 @@
 import unittest
 from unittest import mock
 import _testinternalcapi
+import _imp
 
 from test.support import os_helper
 from test.support import (
@@ -763,6 +764,13 @@ def test_dll_dependency_import(self):
                                     env=env,
                                     cwd=os.path.dirname(pyexe))
 
+    def test_issue105979(self):
+        # this used to crash
+        with self.assertRaises(ImportError) as cm:
+            _imp.get_frozen_object("x", b"6\'\xd5Cu\x12")
+        self.assertIn("Frozen object named 'x' is invalid",
+                      str(cm.exception))
+
 
 @skip_if_dont_write_bytecode
 class FilePermissionTests(unittest.TestCase):
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-06-22-19-16-24.gh-issue-105979.TDP2CU.rst b/Misc/NEWS.d/next/Core and Builtins/2023-06-22-19-16-24.gh-issue-105979.TDP2CU.rst
new file mode 100644
index 00000000000000..1f9ef71d6c85fa
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-06-22-19-16-24.gh-issue-105979.TDP2CU.rst	
@@ -0,0 +1 @@
+Fix crash in :func:`_imp.get_frozen_object` due to improper exception handling.
diff --git a/Python/import.c b/Python/import.c
index 969902afea1cd6..9b1ad87b84f649 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -2071,6 +2071,7 @@ unmarshal_frozen_code(PyInterpreterState *interp, struct frozen_info *info)
     PyObject *co = PyMarshal_ReadObjectFromString(info->data, info->size);
     if (co == NULL) {
         /* Does not contain executable code. */
+        PyErr_Clear();
         set_frozen_error(FROZEN_INVALID, info->nameobj);
         return NULL;
     }


Code review comments:
diff_hunk: @@ -0,0 +1 @@
+Fix crash in :func:`_imp.get_frozen_object` due to improper exception handling.
path: Misc/NEWS.d/next/Core and Builtins/2023-06-22-19-16-24.gh-issue-105979.TDP2CU.rst
text: @user1:
```suggestion
Fix crash in :func:`!_imp.get_frozen_object` due to improper exception handling.
```