Skip to content

do_raise() doesn't make sure the constructed cause is an exception. #112217

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

Closed
apaz-cli opened this issue Nov 17, 2023 · 2 comments
Closed

do_raise() doesn't make sure the constructed cause is an exception. #112217

apaz-cli opened this issue Nov 17, 2023 · 2 comments
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error

Comments

@apaz-cli
Copy link
Contributor

apaz-cli commented Nov 17, 2023

Bug report

Bug description:

Consider the following:

class ConstructsNone(BaseException):
  @classmethod
  def __new__(*args, **kwargs): return None

raise Exception("Printing this exception raises an exception. Mwa-ha-nyaa~ >:3") from ConstructsNone
TypeError: print_exception(): Exception expected for value, NoneType found

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception: Printing this exception raises an exception. Mwa-ha-nyaa~ >:3

In Python/ceval.c, in do_raise(), when you raise an object, cpython checks if it's an exception type, and if it is, constructs it by calling it with no arguments. Then it checks to make sure that what was constructed is in fact an exception.

Then it does the same thing for the exception's cause. If it's a type, it constructs the cause by calling it with no arguments. But, for the cause, it actually doesn't check to make sure that the result of the call is in fact an exception, it just stores the result without checking. This seems like a bug. Not a catastrophic one by any means, but probably unintentional considering that the very same condition is checked a few lines above.

That doesn't necessarily explain the result above though. We've created an exception object where the cause is None (or any other sort of object that we want). Then, when the interpreter (interactive mode) goes to print the exception, it expects the cause to be an exception. This leads to yet another exception being raised, telling you that the cause is the wrong type.

The solution of course is just to add the check when the cause is called. I've submitted the pull request, here: #112216

CPython versions tested on:

3.10, 3.11, 3.12, CPython main branch

Operating systems tested on:

Linux, Windows

Linked PRs

@apaz-cli apaz-cli added the type-bug An unexpected behavior, bug, or error label Nov 17, 2023
@apaz-cli apaz-cli changed the title do_raise(), when it constructs the argument, do_raise() doesn't make sure the constructed cause is an exception. Nov 17, 2023
@Eclips4 Eclips4 added 3.11 only security fixes 3.12 only security fixes 3.13 bugs and security fixes labels Nov 17, 2023
@iritkatriel iritkatriel added interpreter-core (Objects, Python, Grammar, and Parser dirs) needs backport to 3.11 only security fixes needs backport to 3.12 only security fixes and removed 3.11 only security fixes 3.12 only security fixes 3.13 bugs and security fixes labels Nov 26, 2023
@hugovk hugovk added needs backport to 3.11 only security fixes needs backport to 3.12 only security fixes and removed needs backport to 3.12 only security fixes needs backport to 3.11 only security fixes labels Nov 29, 2023
@hugovk
Copy link
Member

hugovk commented Nov 29, 2023

@iritkatriel Please apply the "needs backport" labels to the PR (#112216) if we need to backport this. Thanks!

@iritkatriel iritkatriel removed needs backport to 3.11 only security fixes needs backport to 3.12 only security fixes labels Nov 29, 2023
@iritkatriel
Copy link
Member

Let's not backport. I don't think it will merge cleanly in the previous versions and this bug is not worth the risk of a manual backport.

aisk pushed a commit to aisk/cpython that referenced this issue Feb 11, 2024
Glyphack pushed a commit to Glyphack/cpython that referenced this issue Sep 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

4 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy