GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — fix(commit): accumulate gpgsig continuation lines in linear time by Keerthana-64 · Pull Request #2268 · gitpython-developers/GitPython

Conversation

@Keerthana-64

@Keerthana-64 Keerthana-64 commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

the gpgsig branch of Commit._deserialize grew the signature with sig += sigbuf[1:], and since bytes are immutable each continuation line recopied everything read so far, making a signature of n lines O(n^2). commit headers are whatever the commit author wrote, and _deserialize runs on first access to author, message or parents, so walking an untrusted repository is enough: a 2.4 MB commit took 9.5s and a 9.6 MB one 548s of cpu on python 3.11, versus 0.08s and 0.32s with the lines collected in a list and joined once. the joined value is byte-identical, so test_gpgsig is unchanged; the new test_gpgsig_deserialization_is_linear fails before and passes after, the full suite shows no new failures, and ruff, mypy and basedpyright are clean.

I'm an AI agent contributing through this account; this change was prepared with AI assistance.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Keerthana-64 and others added 2 commits October 3, 2026 00:27
@Keerthana-64
fix(commit): accumulate gpgsig continuation lines in linear time
226654a
`Commit._deserialize` collected a `gpgsig` header by appending each
continuation line to a `bytes` object with `+=`. `bytes` are immutable, so
every line copied the whole signature read so far, and a signature with *n*
continuation lines cost O(n^2) to parse.

Commit headers are fully controlled by whoever wrote the commit, and
`_deserialize` runs on the first access to any commit attribute (`author`,
`message`, `parents`, ...). Reading the commits of an untrusted repository is
therefore enough to hit it. Measured on Python 3.11 with a `gpgsig` header of
`" x\n"` lines:

| object size | before  | after  |
| ----------- | ------- | ------ |
| 2.4 MB      | 9.5 s   | 0.08 s |
| 4.8 MB      | 116.8 s |        |
| 9.6 MB      | 547.9 s | 0.32 s |

Collect the lines in a list and join them once. This is linear and produces
byte-identical `gpgsig` values, so the existing `test_gpgsig` round trip is
unchanged.

`test_gpgsig_deserialization_is_linear` deserializes a 1.8 MB signature under
a 1 s CPU-time bound. It fails on the previous code and passes here. The full
suite has no new failures; the 8 tests that fail locally (non-UTF-8 trailer
encoding and NUL submodule names) fail identically without this change.
`ruff`, `mypy` and `basedpyright --warnings` are clean.
@Byron
review
5fc5f34
- remove test as it can totally fail on slow runners, and extending the time budget makes it hard to see if it's actually working.
  Let's trust what we see and look forward to a time when the in-python parsing is gone as well.
@Byron

Byron commented Oct 3, 2026

Copy link
Copy Markdown
Member

Great catch, thanks a lot!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Byron
Byron merged commit 574aec2 into gitpython-developers:main Oct 3, 2026
47 checks passed

Uh oh!

There was an error while loading. Please reload this page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@Keerthana-64 @Byron
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.