Skip to content

fix: Add ConditionalOnDefaultReactiveWebSecurity - #50785

Open
michael-wirth wants to merge 1 commit into
spring-projects:mainfrom
michael-wirth:bugfix/gh-50778
Open

fix: Add ConditionalOnDefaultReactiveWebSecurity#50785
michael-wirth wants to merge 1 commit into
spring-projects:mainfrom
michael-wirth:bugfix/gh-50778

Conversation

@michael-wirth

Copy link
Copy Markdown

fixes #50778

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 17, 2026
@priyanshuvishwakarma273403

This comment was marked as outdated.

@snicoll snicoll added the status: on-hold We can't start working on this issue yet label Jul 1, 2026
Zir0-93 added a commit to hadi-technology/striff-browser-extension that referenced this pull request Aug 23, 2026
…11)

spring-projects/spring-boot#50785 failed in the extension with

    Failed downloading base zip: Failed reading repository zip:
    Maximum call stack size exceeded

which reads like a corrupt archive and was reported as a size problem. It is neither. The
same archive filters correctly through the buffered path to 12.82MiB of source and
documentation, comfortably inside the 15MiB upload ceiling. The whole failure is in how the
bytes are handed to fflate.

fflate's Unzip recurses once per entry it finishes inside a single push(), so recursion
depth follows how many entries one chunk happens to contain. Measured on that archive
(18MiB, 21,146 entries):

    4MiB push   -> Maximum call stack size exceeded at entry ~3,212
    2MiB push   -> ok, worst push completes 3,115 entries
    1MiB push   -> ok, worst push completes 2,054 entries
    256KiB push -> ok, worst push completes   742 entries

So the ceiling is around 3,200 frames, and which side of it a chunk lands on is a property
of the archive, not of the request. A network body normally arrives in small pieces, which
is why this went unseen; a fast or cached response coalesces them.

filterZipStream now slices every chunk to 64KiB before pushing, whatever the reader hands
over. 64KiB rather than the 1MiB that merely passed here, because bytes are a proxy for
entries and the ratio belongs to the repository: a minimal local header plus a short name is
about 60 bytes, so a pathological tree of tiny files puts roughly 1,100 entries in 64KiB
against the ~3,200 that breaks. The cost is more push() calls over the same bytes, which is
not where the time goes.

The regression test builds 6,000 tiny entries and delivers them in ONE chunk. Its first
version used streamOf's 4096-byte default, passed with the fix reverted, and proved nothing;
it is now pinned both ways -- fails without the slicing, passes with it.


Claude-Session: https://claude.ai/code/session_017X3m5Qxtn8KZPM6TqrknGk

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: on-hold We can't start working on this issue yet status: waiting-for-triage An issue we've not yet triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ReactiveOAuth2ResourceServerWebSecurityAutoConfiguration annotated with wrong condition

4 participants