Skip to content

Prevent TypeError when bytes passed to cursor.execute with debug middleware #1303

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

bpartridge
Copy link

@bpartridge bpartridge commented Feb 10, 2022

If DjangoDebugMiddleware is installed, calling cursor.execute(b) where b is a bytes object causes the recording (and thus the entire database call) to throw a TypeError due to

"is_select": sql.lower().strip().startswith("select"),
:

"is_select": sql.lower().strip().startswith("select"),

Calling execute with a bytes parameter, to my knowledge, is not currently done within the high-level abstractions in the Django ORM, but is very much supported by psycopg2, as evidenced by the use in psycopg2's own execute_values in https://github.com/psycopg/psycopg2/blob/2_9_3/lib/extras.py#L1270 which codebases may use when bypassing the ORM:

cur.execute(b''.join(parts))

This fix ensures that the sql parameter is safely decoded before scanning whether it begins with SELECT; since this is the only usage, the change is trivial.

The only workaround if code calls execute_values is to disable the DjangoDebugMiddleware altogether, which is far from ideal.

@bpartridge
Copy link
Author

Just following up on this - do I need to do anything to move this into review? I can add tests but wanted to confirm that this wouldn't be a wontfix before doing so.

@firaskafri
Copy link
Collaborator

@bpartridge Hello, sorry it took so long, we are revisiting this now, can you add tests please?

Copy link
Collaborator

@mahdyhamad mahdyhamad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, @bpartridge
Please rebase your branch and make sure all tests pass

@bpartridge
Copy link
Author

Hi all, sorry I missed the comments from April here. I'll rebase this branch on main and add unit tests this week!

…ware

If DjangoDebugMiddleware is installed, calling `cursor.execute(b)` where b is a `bytes` object causes the recording (and thus the entire database call) to throw a TypeError due to https://github.com/graphql-python/graphene-django/blob/775644b5369bdc5fbb45d3535ae391a069ebf9d4/graphene_django/debug/sql/tracking.py#L126 :

```
"is_select": sql.lower().strip().startswith("select"),
```

Calling execute with a bytes parameter, to my knowledge, is not currently done within the high-level abstractions in the Django ORM, but is very much supported by psycopg2, as evidenced by the use in psycopg2's own `execute_values` in https://github.com/psycopg/psycopg2/blob/2_9_3/lib/extras.py#L1270 :

```
cur.execute(b''.join(parts))
```

This fix ensures that the sql parameter is safely decoded before scanning whether it begins with SELECT; since this is the only usage, the change is trivial.

The only workaround if code calls execute_values is to disable the DjangoDebugMiddleware altogether, which is far from ideal.
@bpartridge bpartridge force-pushed the debug-middleware-sql-bytes branch from 6210273 to 7365ee3 Compare September 24, 2023 18:14
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants