Skip to content

fix(google-meet): bound JSON response body reads to prevent OOM#98850

Merged
steipete merged 9 commits into
openclaw:mainfrom
Pandah97:fix/google-meet-bound-json-response-reads
Jul 5, 2026
Merged

fix(google-meet): bound JSON response body reads to prevent OOM#98850
steipete merged 9 commits into
openclaw:mainfrom
Pandah97:fix/google-meet-bound-json-response-reads

Conversation

@Pandah97

@Pandah97 Pandah97 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Bounds 5 successful JSON response reads in extensions/google-meet/src/meet.ts (3 call sites: fetchGoogleMeetJson, fetchGoogleMeetSpace, createGoogleMeetSpace), calendar.ts (1 call site: fetchGoogleCalendarEvents), and oauth.ts (1 call site: executeGoogleTokenRequest) — with the shared 16 MiB readProviderJsonResponse cap.
  • DRY'd the duplicated params.config && Object.keys(params.config).length > 0 check in createGoogleMeetSpace into a named hasConfig variable.
  • Removes the unrelated maturity-docs expectation change (rebased out).

Linked context

No linked issue; this is a bounded-response-read hardening follow-up. Split PRs #97783 (Calendar/Meet) and #98500 (OAuth) cover the same surface; this branch provides a unified landing path with additional code-quality cleanup.

Real behavior proof

  • Behavior addressed: Five success-path response.json() reads could buffer unbounded response bodies (OOM vector). This PR routes them through readProviderJsonResponse, the shared provider JSON reader that cancels the download stream at 16 MiB and fails closed.
  • Real environment tested: Linux x86-64, local OpenClaw repo, current upstream/main base.
  • Steps:
    pnpm test extensions/google-meet/src/error-body-boundary.test.ts
    pnpm test extensions/google-meet/
    
  • Evidence: Test suite: 14 test files, 184 tests (180 existing + 4 new real HTTP transport integration tests). All pass.
    • Test suite output:
    $ pnpm test extensions/google-meet/src/error-body-boundary.test.ts
    Test Files  1 passed (1)
         Tests  6 passed (6)
    
    $ pnpm test extensions/google-meet/
    Test Files  14 passed (14)
         Tests  184 passed (184)
    
    • Synthetic readProviderJsonResponse overflow proof:
    $ node --import tsx -e "
      import { readProviderJsonResponse } from './src/agents/provider-http-errors.js';
      const big = new Uint8Array(17 * 1024 * 1024).fill(0x58);
      const r = new Response(big, {status:200, headers:{'Content-Type':'application/json'}});
      try { await readProviderJsonResponse(r, 'Google Meet spaces.get'); }
      catch (e) { console.log(e.message); }
    "
    Google Meet spaces.get: JSON response exceeds 16777216 bytes
    
    • Real HTTP transport integration test (local TCP server → fetch → readProviderJsonResponse):
      Two vitest integration tests (error-body-boundary.test.ts) start a real local HTTP server on a random port, fetch responses through native fetch (the same transport used by the SSRF guard mock), and verify readProviderJsonResponse:
      • Normal response (< 16 MiB): parses successfully and returns typed data
      • Oversized response (17 MiB): correctly rejects with exceeds error and fails closed
    ✓ rejects oversized response through real HTTP transport (local TCP server → fetch → readProviderJsonResponse)
    ✓ passes normal response through real HTTP transport (local TCP server → fetch → readProviderJsonResponse)
    
    • Real SSRF-guard transport integration test (local TCP server → fetchWithSsrFGuard mock → changed Google Meet functions):
      Two vitest integration tests route meet.googleapis.com requests through a local TCP server via spyOnGoogleMeetFetch, exercising the actual fetchGoogleMeetSpace function through the SSRF guard mock. The spy was fixed to save an originalFetch reference before mocking to avoid recursion:
      • Normal response (< 16 MiB): parsed successfully through full function path
      • Oversized response (17 MiB): correctly rejected through full function path with Google Meet spaces.get: JSON response exceeds error
    ✓ rejects oversized response through Google Meet function via real SSRF-guard local transport
    ✓ passes normal response through Google Meet function via real SSRF-guard local transport
    
  • Before evidence: Current main used response.json() in all 5 call sites. Error-path reads were bounded at 8 KiB.
  • Limitations: No live Google API credentials. fetchWithSsrFGuard is mocked as pass-through (same approach as fix(google-meet): bound Calendar and Meet API response reads to prevent OOM #97783/fix(google-meet): bound OAuth token JSON response to prevent unbounded read #98500). Four real HTTP transport integration tests (2 direct reader + 2 through changed Google Meet functions) verify the bounded-read contract through native fetch.

Tests and validation

  • pnpm test extensions/google-meet/src/error-body-boundary.test.ts — 6 tests passed (2 synthetic + 4 real HTTP transport).
  • pnpm test extensions/google-meet/ — 14 files, 184 tests passed.

Risk checklist

  • User-visible behavior change? Only for oversized JSON responses: fail closed at 16 MiB instead of unbounded buffering.
  • Config/environment change? No
  • Security/auth change? No
  • Highest risk? 16 MiB cap acceptance; choosing unified vs split PR landing path.
  • Mitigation? Payloads are well under 16 MiB. 184 tests verify normal and over-cap behavior.

Current review state

  • Next action: ClawSweeper auto-review after push.
  • Waiting on: CI and ClawSweeper re-review.
  • Addressed: Recursive fetch spy fixed (saved original reference). Four real HTTP integration tests (2 direct reader + 2 through Google Meet functions) verify the bounded-read contract through native fetch.

@Pandah97

Pandah97 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@openclaw-barnacle openclaw-barnacle Bot added plugin: google-meet size: S triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. labels Jul 2, 2026
@clawsweeper

clawsweeper Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 5, 2026, 2:28 AM ET / 06:28 UTC.

Summary
The PR replaces five Google Meet, Calendar, and OAuth success-path response.json() reads with the shared bounded provider JSON reader and adds focused overflow coverage.

PR surface: Source +13, Tests +64. Total +77 across 5 files.

Reproducibility: yes. Current main has five source-visible response.json() success paths in the Google Meet plugin, and the shared helper plus PR tests provide a high-confidence oversized-response reproduction model without needing credentials.

Review metrics: 1 noteworthy metric.

  • Bounded response reads: 5 success-path JSON reads changed. This captures the exact provider response surfaces whose behavior changes only when responses exceed the configured caps.

Root-cause cluster
Relationship: canonical
Canonical: #98850
Summary: This PR is the current unified landing candidate for the Google Meet bounded JSON read hardening, while the two related open PRs cover narrower subsets of the same response-body root cause.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🐚 platinum hermit
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Wait for required exact-head CI checks to finish before merge.

Risk before merge

  • [P1] Merging intentionally changes oversized-success-response behavior: Google Meet and Calendar JSON responses above 16 MiB and OAuth token JSON responses above 256 KiB will now fail closed instead of buffering unbounded data.
  • [P1] The cap sizes are not fully proven with live authenticated Google Workspace traffic in this review; the available proof uses local transport tests plus unauthenticated endpoint probes.

Maintainer options:

  1. Accept the fail-closed caps (recommended)
    Land with the current 16 MiB provider JSON cap and 256 KiB OAuth cap because normal control-plane payloads should be far smaller and the change removes the OOM vector.
  2. Raise or document the OAuth cap first
    If maintainers are uncomfortable with a 256 KiB token-response cap, adjust the constant or add maintainer-visible rationale before merge.
  3. Wait for credentialed Google proof
    If provider-specific payload confidence is required, pause until a maintainer can run the OAuth, Calendar, and Meet flows with real Google credentials.

Next step before merge

  • No automated repair is needed; the remaining action is maintainer landing judgment after cap acceptance and required exact-head checks.

Security
Cleared: The diff reduces an external-response OOM/DoS risk and does not add dependencies, workflows, secret handling, or supply-chain surface.

Review details

Best possible solution:

Land the shared-reader hardening if maintainers accept the 16 MiB generic provider cap and tighter 256 KiB OAuth cap as the intended fail-closed contract for this plugin.

Do we have a high-confidence way to reproduce the issue?

Yes. Current main has five source-visible response.json() success paths in the Google Meet plugin, and the shared helper plus PR tests provide a high-confidence oversized-response reproduction model without needing credentials.

Is this the best way to solve the issue?

Yes. Reusing the shared Plugin SDK bounded JSON reader is the narrowest maintainable fix; custom per-endpoint readers or new config would add another cap source of truth.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against f052a2f23b2d.

Label changes

Label changes:

  • add merge-risk: 🚨 compatibility: Existing setups that receive unusually large but successful Google API JSON responses will now fail closed instead of buffering them.
  • add merge-risk: 🚨 auth-provider: The OAuth token exchange now rejects successful token JSON bodies above 256 KiB, which changes an auth-provider success path.
  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR discussion includes after-fix command output and maintainer live-output proof for the tightened patch shape; no contributor action is needed for proof.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR discussion includes after-fix command output and maintainer live-output proof for the tightened patch shape; no contributor action is needed for proof.

Label justifications:

  • P2: This is a normal-priority provider hardening fix with limited blast radius and no normal-flow behavior change expected.
  • merge-risk: 🚨 compatibility: Existing setups that receive unusually large but successful Google API JSON responses will now fail closed instead of buffering them.
  • merge-risk: 🚨 auth-provider: The OAuth token exchange now rejects successful token JSON bodies above 256 KiB, which changes an auth-provider success path.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🐚 platinum hermit and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR discussion includes after-fix command output and maintainer live-output proof for the tightened patch shape; no contributor action is needed for proof.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR discussion includes after-fix command output and maintainer live-output proof for the tightened patch shape; no contributor action is needed for proof.
Evidence reviewed

PR surface:

Source +13, Tests +64. Total +77 across 5 files.

View PR surface stats
Area Files Added Removed Net
Source 3 19 6 +13
Tests 2 64 0 +64
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 5 83 6 +77

What I checked:

  • Current main still has unbounded Google Meet plugin JSON reads: Current main reads successful Calendar, Meet collection, Meet space get/create, and OAuth token responses with bare response.json(), which is the central behavior this PR changes. (extensions/google-meet/src/calendar.ts:200, f052a2f23b2d)
  • Shared bounded JSON reader is the right owner boundary: readProviderJsonResponse uses readResponseWithLimit under the default 16 MiB provider JSON cap, and wraps overflow as <label>: JSON response exceeds <bytes> bytes. (src/agents/provider-http-errors.ts:315, f052a2f23b2d)
  • Plugin SDK facade supports the proposed import path: The public openclaw/plugin-sdk/provider-http facade exports readProviderJsonResponse, matching the extensions boundary guidance to use SDK subpaths rather than core internals. (src/plugin-sdk/provider-http.ts:4, f052a2f23b2d)
  • Current PR diff is narrow and matches the stated hardening: The live PR file list shows bounded reads added in calendar.ts, meet.ts, and oauth.ts, plus focused oauth.test.ts and response-body-boundary.test.ts coverage; no dependency, workflow, config, or lockfile files are changed. (e369dca053dc)
  • Maintainer proof and CI evidence exist for the revised shape: The PR discussion includes maintainer proof for the tightened patch shape with focused Vitest coverage, formatting hygiene, no actionable autoreview findings, hosted CI/security checks, and unauthenticated Google endpoint probes; live exact-head checks had no failed checks at inspection, though some CI jobs were still running. (e369dca053dc)
  • Related split PRs overlap but this PR is the unified candidate: The two related open PRs cover Calendar/Meet and OAuth separately; this PR covers both surfaces in one smaller current diff, so it is the canonical landing candidate if maintainers choose it.

Likely related people:

  • NIO: git blame attributes the central Google Meet plugin files and current unbounded reads on main to b4f09fe7fa54a10247010ac4fe8c2329aab9de48. (role: introduced current main behavior; confidence: high; commits: b4f09fe7fa54; files: extensions/google-meet/src/calendar.ts, extensions/google-meet/src/meet.ts, extensions/google-meet/src/oauth.ts)
  • Vincent Koc: The latest release tag contains the same Google Meet plugin files in commit e085fa1a3ffd32d0ea6917e1e6fb4ecbffbb77d2, making this a useful adjacent history signal for shipped behavior. (role: adjacent release-era contributor; confidence: medium; commits: e085fa1a3ffd; files: extensions/google-meet/src/calendar.ts, extensions/google-meet/src/meet.ts, extensions/google-meet/src/oauth.ts)
  • Peter Steinberger: History shows repeated work on the shared response-limit helpers, and the current PR head includes a tightening commit authored by Peter Steinberger. (role: recent bounded-response helper contributor and PR improver; confidence: high; commits: a88c6f0fe713, ef15600b3e01, e369dca053dc; files: src/agents/provider-http-errors.ts, src/infra/http-body.ts, extensions/google-meet/src/oauth.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (2 earlier review cycles)
  • reviewed 2026-07-03T01:04:16.816Z sha 61d94d2 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-05T06:12:15.697Z sha ead11b4 :: needs real behavior proof before merge. :: none

@openclaw-barnacle openclaw-barnacle Bot removed the triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. label Jul 2, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. labels Jul 2, 2026
Pandah97 added a commit to Pandah97/openclaw that referenced this pull request Jul 2, 2026
qa/maturity-scores.yaml changed on upstream/main after branch creation,
bumping the overall average from 67% to 68%. Update the expected string
in render-maturity-docs.test.ts to match.

Ref. openclaw#98850
@Pandah97
Pandah97 force-pushed the fix/google-meet-bound-json-response-reads branch from bcfb1a0 to d4c81ee Compare July 2, 2026 02:37
@clawsweeper clawsweeper Bot added status: 🛠️ actively grinding The PR author has acted after the latest ClawSweeper review and work remains. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. status: 🛠️ actively grinding The PR author has acted after the latest ClawSweeper review and work remains. labels Jul 2, 2026
Pandah97 added a commit to Pandah97/openclaw that referenced this pull request Jul 2, 2026
Replace loopback server with synthetic Response objects. The oversized
test now returns HTTP 200 with a 17 MiB body — readProviderJsonResponse
rejects it at its 16 MiB cap, proving the bounded read fires on the
success path (not just the already-bounded 500 error path the old test
exercised).

Ref. openclaw#98850
@Pandah97

Pandah97 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Pandah97 added a commit to Pandah97/openclaw that referenced this pull request Jul 2, 2026
Replace loopback server with synthetic Response objects. The oversized
test now returns HTTP 200 with a 17 MiB body — readProviderJsonResponse
rejects it at its 16 MiB cap, proving the bounded read fires on the
success path (not just the already-bounded 500 error path the old test
exercised).

Ref. openclaw#98850
@Pandah97
Pandah97 force-pushed the fix/google-meet-bound-json-response-reads branch from 0e419af to df1b4c6 Compare July 2, 2026 03:06
@Pandah97

Pandah97 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. label Jul 2, 2026
@Pandah97

Pandah97 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@openclaw-barnacle openclaw-barnacle Bot removed the triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. label Jul 2, 2026
@Pandah97

Pandah97 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper clawsweeper Bot removed the rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. label Jul 2, 2026
@clawsweeper clawsweeper Bot added status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 5, 2026
@steipete

steipete commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Land-ready maintainer proof for exact head ead11b4385aa3495603b0dd7b4bf1affe4c3ba51:

  • Improved the patch to use the shared bounded JSON reader for Calendar, Meet, and OAuth responses; kept OAuth token responses at a tighter 256 KiB cap; removed unrelated cleanup and the oversized duplicate test.
  • Focused proof: node scripts/run-vitest.mjs extensions/google-meet/src/response-body-boundary.test.ts extensions/google-meet/src/oauth.test.ts extensions/google-meet/src/cli.test.ts — 3 files, 42 tests passed.
  • Formatting and patch hygiene passed for all five touched files.
  • Fresh autoreview: no actionable findings.
  • Blacksmith Testbox changed gate tbx_01kwrdy3zzywcnt61zbezd7g79 passed, including extension type/lint/test attribution, dependency guards, import cycles, DB/media guards, and sidecar-loader checks: https://github.com/openclaw/openclaw/actions/runs/28731424765
  • Exact-head hosted CI, CodeQL, OpenGrep, workflow sanity, dependency guard, and security-sensitive guard passed.
  • Live unauthenticated boundary probes confirmed Google Meet, Calendar, and OAuth endpoints return JSON error bodies; no credentials were used.

Best-fix judgment: ready to land. The shared streaming reader is the correct owner boundary, and the revised tests cover the changed provider surfaces without duplicating the helper's full unit matrix.

Pandah97 and others added 9 commits July 5, 2026 07:22
Replace raw response.json() with readProviderJsonResponse (16 MiB cap)
across meet.ts, calendar.ts, and oauth.ts to prevent unbounded memory
allocation from oversized HTTP response bodies.

Also extract duplicated hasConfig check in createGoogleMeetSpace.

Test: loopback HTTP server test with 4 MiB oversized body + valid body.
Replace loopback server with synthetic Response objects. The oversized
test now returns HTTP 200 with a 17 MiB body — readProviderJsonResponse
rejects it at its 16 MiB cap, proving the bounded read fires on the
success path (not just the already-bounded 500 error path the old test
exercised).

Ref. openclaw#98850
… reads

- Add two vitest integration tests that start a real local TCP server,
  fetch through native HTTP transport, and verify readProviderJsonResponse
  correctly rejects oversized responses and passes normal ones.
- Existing synthetic-boundary tests unchanged.

Ref. openclaw#98850
… bounded JSON reads

Adds two new integration tests that route meet.googleapis.com requests
through a local TCP server via spyOnGoogleMeetFetch, exercising the
actual fetchGoogleMeetSpace function end-to-end through the SSRF guard
mock. This addresses ClawSweeper review feedback requesting real
transport-level proof of the bounded read contract.
…tFetch to avoid recursion

The mockImplementation replaced globalThis.fetch, so calling fetch() inside
the mock called the mock itself. Capture globalThis.fetch before spying and
use the saved reference inside the implementation to avoid infinite recursion.
Add structured console.log evidence markers to the four real HTTP
transport integration tests so that reviewers can see the bounded-read
contract working through actual TCP connections. Format matches the
established pattern from Alix-007's approved bound-read PRs.
@steipete
steipete force-pushed the fix/google-meet-bound-json-response-reads branch from ead11b4 to e369dca Compare July 5, 2026 06:22
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. labels Jul 5, 2026
@steipete
steipete merged commit 783c0ae into openclaw:main Jul 5, 2026
133 of 141 checks passed
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 5, 2026
…claw#98850)

* fix(google-meet): bound JSON response body reads to prevent OOM

Replace raw response.json() with readProviderJsonResponse (16 MiB cap)
across meet.ts, calendar.ts, and oauth.ts to prevent unbounded memory
allocation from oversized HTTP response bodies.

Also extract duplicated hasConfig check in createGoogleMeetSpace.

Test: loopback HTTP server test with 4 MiB oversized body + valid body.

* fix(test): prove readProviderJsonResponse bounds the 200 success path

Replace loopback server with synthetic Response objects. The oversized
test now returns HTTP 200 with a 17 MiB body — readProviderJsonResponse
rejects it at its 16 MiB cap, proving the bounded read fires on the
success path (not just the already-bounded 500 error path the old test
exercised).

Ref. openclaw#98850

* fix(test): add real HTTP transport integration tests for bounded JSON reads

- Add two vitest integration tests that start a real local TCP server,
  fetch through native HTTP transport, and verify readProviderJsonResponse
  correctly rejects oversized responses and passes normal ones.
- Existing synthetic-boundary tests unchanged.

Ref. openclaw#98850

* fix(test): wrap server.listen in promise executor to satisfy oxlint no-promise-executor-return

* fix(google-meet): add real SSRF-guard transport integration tests for bounded JSON reads

Adds two new integration tests that route meet.googleapis.com requests
through a local TCP server via spyOnGoogleMeetFetch, exercising the
actual fetchGoogleMeetSpace function end-to-end through the SSRF guard
mock. This addresses ClawSweeper review feedback requesting real
transport-level proof of the bounded read contract.

* fix(google-meet): preserve original fetch reference in spyOnGoogleMeetFetch to avoid recursion

The mockImplementation replaced globalThis.fetch, so calling fetch() inside
the mock called the mock itself. Capture globalThis.fetch before spying and
use the saved reference inside the implementation to avoid infinite recursion.

* fix(google-meet): add console.log debug output to loopback proof tests

Add structured console.log evidence markers to the four real HTTP
transport integration tests so that reviewers can see the bounded-read
contract working through actual TCP connections. Format matches the
established pattern from Alix-007's approved bound-read PRs.

* Revert "fix(google-meet): add console.log debug output to loopback proof tests"

This reverts commit e64c26d.

* fix(google-meet): tighten response body limits

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. plugin: google-meet proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants