Skip to content

fix(web): close the server-function boundary defects - #3254

Closed
frenzzy wants to merge 1 commit into
solidjs:nextfrom
frenzzy:fix/server-function-boundary-sweep
Closed

fix(web): close the server-function boundary defects#3254
frenzzy wants to merge 1 commit into
solidjs:nextfrom
frenzzy:fix/server-function-boundary-sweep

Conversation

@frenzzy

@frenzzy frenzzy commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Twenty-two verified defects in the server-function runtime, fixed together because they were found together and because three of them share a hunk.

How this was built

Every defect was reproduced first, then pinned by a spec proven red on f0f7531b before a line of source changed. The fixes were written independently, in eight separate checkouts, and only then merged into one tree — so the overlap between them is measured rather than assumed.

That measurement is why this is one PR and twenty-two issues rather than twenty-two PRs. Each of the 32 source hunks was reverted one at a time, rebuilt, and the suite re-run to record which specs go red:

  • One hunk is genuinely cross-cutting. Neutering stripUnsafeKeys in server-functions/src/shared.ts reddens the new response-decode specs (7), the new flash-decode specs (2) and the already-shipped argument-road specs (server-functions-proto-keys, open-gaps). Three decode roads, one guard — which is the fix: the strip moves from a caller to extractBody, the boundary all three share.
  • Every other hunk reddens only its own group's specs. Reported as a negative result: the remaining findings are independent defects that happen to live nearby, not one defect wearing many faces. Two near-merges were refused on that evidence — isJSONSafe's -0 and own-names edits sit three lines apart in one function with the same-sounding rationale, but redden disjoint specs.

Verification

baseline f0f7531b this branch
vitest run 667 passed 667 passed
vitest run --config vite.config.server.mjs 59 files, 647 passed + 2 skipped 84 files, 737 passed + 2 skipped
vitest run --config vite.config.hydrate.mjs 164 passed 164 passed

tsc --project tsconfig.build.json and tsconfig.test.json clean; prettier --check clean on every touched file. No pre-existing test was edited or deleted — where a fix first reddened one, the fix was rewritten, not the test.

What is deliberately not here

Several findings were left unfixed with the reasoning recorded in the issues rather than forced into a patch: non-enumerable accessors on an Error carrier (closing that means invoking hidden accessors, the hazard 47995412 removed); the frames/ transport's own decode leg, which bypasses extractBody; a sync-iterable class instance, whose carrier properties are dropped by a different function. Two judgement calls are flagged in their issues as yours rather than asserted here — whether GET()'s contract should say that a declared read is a navigable document, and whether the slowloris time bound belongs in core or in the adapter.

Issues

@changeset-bot

changeset-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 7d5e66f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 11 packages
Name Type
@solidjs/web Patch
@solidjs/babel-plugin Patch
@solidjs/element Patch
@solidjs/h Patch
@solidjs/html Patch
test-integration Patch
@solidjs/compiler Patch
@solidjs/diagnostics Patch
@solidjs/signals Patch
solid-js Patch
@solidjs/universal Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Twenty-two verified defects across the argument decode, the result graph,
the single-flight fold, the invocation seams, the no-JS flash road and the
client transport. Each one was pinned by a test proven red on f0f7531
before any source changed; the twenty-five new specs and the eight source
files land together.

Fixes solidjs#3232
Fixes solidjs#3233
Fixes solidjs#3234
Fixes solidjs#3235
Fixes solidjs#3236
Fixes solidjs#3237
Fixes solidjs#3238
Fixes solidjs#3239
Fixes solidjs#3240
Fixes solidjs#3241
Fixes solidjs#3242
Fixes solidjs#3243
Fixes solidjs#3244
Fixes solidjs#3245
Fixes solidjs#3246
Fixes solidjs#3247
Fixes solidjs#3248
Fixes solidjs#3249
Fixes solidjs#3250
Fixes solidjs#3251
Fixes solidjs#3252
Fixes solidjs#3253
@frenzzy
frenzzy force-pushed the fix/server-function-boundary-sweep branch from 7d5e66f to a56c001 Compare September 3, 2026 07:22
@codspeed-hq

codspeed-hq Bot commented Sep 3, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 136 untouched benchmarks


Comparing frenzzy:fix/server-function-boundary-sweep (a56c001) with next (ead7b1a)

Open in CodSpeed

@frenzzy

frenzzy commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Superseded on next — closing.

Every fix here landed in your own commits, and in three places yours is the better call:

I've re-run my own repros against next to confirm the fixes hold rather than take the commit messages for it: the decoded-promise crash exits 0, the Error-carrier channel is sanitized on all four carrier shapes, Content-Length: 10 on a 2 MiB body is a 413 with zero bytes reaching the function, register -> register -> GET() is a 403 with the mutation unrun, and transformResult now observes all six throw shapes.

The three dispositions I did not get my way on are noted and not re-litigated here: the response-leg strip (#3233), the flight-slice preflight (#3243), and the flash refusal statuses (#3250). #3239 is the one still open.

Thanks for turning these around so quickly.

@frenzzy frenzzy closed this Sep 3, 2026
@ryansolid

Copy link
Copy Markdown
Member

Closing the loop with the full disposition, now that everything from this sweep has landed. Thanks again @frenzzy — 22 filed issues, and the triage upheld most of them. The complete record lives in the conformance matrix (packages/web/test/server/server-function-matrix/MATRIX.md), but in short:

Fixed on next (each as its own commit with tests): #3232 ff2ecf11, #3234 c0bc9baa, #3235 5cee0f77 (Error-carrier half), #3236 7009adfd, #3237 12263816, #3238 ed6b6053, #3241 84a94bc1, #3244 b7b17abf (clone half), #3245 6c9f8f45, #3246 292bdc52, #3247 a1ff2860, #3248 f21e060b, #3249 3393fb62, #3251 a14c1385, #3253 6bb51c9b.

#3239 (flash cookie confidentiality) got the deepest treatment: the payload is now AES-GCM encrypted, always, under a key derived from a deployment-wide secret (fbe5bef4), with SameSite=Lax + Max-Age=60 and no-key-means-no-flash rather than plaintext. Two companion drafts land in unison with rc.7: solidjs/solid-vite-plugin#343 (injects the secret into server builds with zero configuration) and solidjs/solid-router#597 (absorbs the now-async decoder).

Ratified as-is after review (closed, no code change): #3240 (entry-only wrapInvocation, semantics pinned in docs/tests), #3250 (security refusals keep raw statuses; a refused request's Referer is untrusted), #3252 (server-authored same-origin Location alone names the fold destination), #3242 (native Proxy construction semantics stay).

Rejected as proposed: #3233 (decode-boundary stripping destroys legitimate constructor/prototype data on trusted results) and #3243 (the slice-isolation probe is incomplete and leaks an internal helper) — both with the reasoning recorded on the issues.

The wholesale form of this PR was never mergeable — 43 files across independent concerns — but as an audit it was excellent: it drove a permanent conformance matrix for the server-function protocol that future changes get checked against. That's a better legacy than a merge.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants