Repository navigation
Bump @fastify/busboy from 3.2.0 to 3.2.4 in packages/runtimes/serve-emu - #79
Open
superbot-helper wants to merge 1 commit into
Open
superbot-helper wants to merge 1 commit into
superbot-helper wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
packages/runtimes/serve-emudepends on@fastify/busboy3.2.0 and its ownpackage-lock.jsonresolves that entry to 3.2.0, which carries three published advisories. This pull request moves the dependency spec and the one lock entry to 3.2.4.wsand every other lock entry are unchanged.Two files change, because the dependency is pinned exactly:
package.json"@fastify/busboy": "3.2.0"→"3.2.4"(same spec form, no range widening), and inpackage-lock.jsonthenode_modules/@fastify/busboyentry plus the lock's own root""dependency spec. A lock-only edit is not installable here —npm cirefuses it withEUSAGE: lock file's @fastify/busboy@3.2.4 does not satisfy @fastify/busboy@3.2.0— so the manifest moves with it.The advisories
>= 3.1.0, < 3.2.1__proto__orconstructorresolves to an inherited non-array value and the parser throwsTypeError: this.header[h].push is not a function.>= 1.0.0, < 3.2.1Content-Dispositionparameter is retained verbatim and delivered to the application.< 3.2.2OSV returns three advisories for 3.2.0, one for 3.2.1, and none for 3.2.2, 3.2.3 and 3.2.4.
Why this parser is on an executed path here
packages/runtimes/serve-emuis the Node runtime behind the Mobile Dev plugin:src/cli.ts:164picks an adb device (pickDevice, or--avdboots one),src/cli.ts:242callsstartServer(...), andsrc/node-server.ts:184listens. The request chain to the parser is:src/server.ts:1353builds the API router fromcreateApiRoutes();src/server.ts:1448-1455dispatches any request whose path is/apior/api/...(src/api/router.ts:68-69).src/api/routes/applications.ts:12-19registersPOST /api/apps/install;:20-27registersPOST /api/files/import.src/server.ts:1048-1053(installEndpoint→uploadEndpoint,src/server.ts:982) callsstageUpload(req, { fieldName: "apk", ... })atsrc/server.ts:1007before it touches the device.src/multipart-upload.ts:1importsBusboyfrom@fastify/busboy;:444constructs it with the request'scontent-type;:312feeds it throughparser.write(...).src/multipart-upload.ts:19-24and:68-86are the endpoint's own parser feed: a 64 KiB + 8 KiB ring, and onfinish()one write of everything except the last 8192 bytes, then one write of those 8192 bytes.No authentication is involved on a loopback bind:
src/server.ts:333-350only enforces a token when one was configured, and--tokendefaults to off for127.0.0.1(src/cli.ts:181-186). The requests below sent noAuthorization, cookie,tokenquery orOriginheader.What was measured
The program was started from the bundle
npm run buildemits, produced withtooling/build-serve-emu.mjs's own esbuild invocation (--bundle --format=esm --platform=node --target=node22.18 --external:ws --external:@fastify/busboy), against a bootedsuperbot-demoAVD onemulator-5556, asnode src/cli.mjs -s emulator-5556 -p <port>— once withnpm cifrom the base lock (busboy 3.2.0) and once from this patch's lock (3.2.4). Each arm is one raw-socketPOST /api/apps/installwith the whole body in one client write, followed by aGET /api/deviceson the same process. Times are time-to-first-byte.filename="control.apk"adb-failed,INSTALL_PARSE_FAILED_NOT_APK; process alive__proto__: pollutedandconstructor: also{"ok":false,"error":"this.header[h].push is not a function"}; process aliveadb-failed(INSTALL_PARSE_FAILED_NOT_APK), i.e. the part parsed and the staged file reachedadb install; process alivefilename="a\rb\nc.txt"{"ok":false,"error":"APK file must end with .apk"}: the parser delivereda\rb\nc.txtas the filename{"ok":false,"code":"unexpected-multipart-part","error":"multipart field apk must be a file"}: the part is skipped and never reaches the routeA, false needle prefix away from the parser's flush pointA, false needle prefix ending exactly at byte N−8192 (the parser's write boundary)GET /api/deviceson the same process timed out at 4,002 ms, and the process's CPU time went from 0:00.19 to 0:15.67 while nothing was servedadbruns, process aliveThe 502s are the emulator rejecting the staged file (
INSTALL_PARSE_FAILED_NOT_APK), not a parser failure: the control and both boundary rows prove the parse completed and that the bytes were written to a temp file and handed toadb install. Both 400 rows are the route's own error envelope.Parser level, against the packages
npm ciinstalls from each lock, byte-identical payloads, one child process per run, killed at 8 s:__proto__/constructorpart headersTypeError: this.header[h].push is not a functionatdeps/dicer/lib/HeaderParser.js:95(uncaught, child exits 1)fileevent withfilename="proto.apk"filename="a\rb\nc.txt"fileevent, filename bytes97,13,98,10,99,46,116,120,116fileevent: the part is skippedThe last two rows are the point: the trigger is the fragmented delimiter write, not the boundary length on its own. In this endpoint the fragmentation is not the client's — the client sends all 28,824 bytes in one
write()— it is the runtime's ownParserTrailerBuffer, which splits the body at N−8192 before handing it to busboy. The payload puts a false needle prefix (\r\n--+ 250 ×A, thenBB) so that the first write ends with a 254-byte prefix of the 256-byte needle and the second write starts withB, a byte the 3.2.0 occurrence table has no entry for;deps/streamsearch/sbmh.js:129(pos += this._occ[ch]) then advances by zero. 3.2.4 changes that table toUint16Array(sbmh.js:56), so 256 no longer wraps to 0.Limits
startServeropens a scrcpy session before it listens. The measurements use the repository's own--avd-less path with an externally booted AVD (-s emulator-5556). On a machine with no device the CLI exits atsrc/adb.ts:82and no request can be made.adbnaming the staged temp file, not as a 200.Filenameda\rb\nc.txtthat the route then rejects for not ending in.apk, versus a skipped part), not a claim that a CR/LF filename is rendered or stored anywhere.The needle cannot have a length bigger than 256on every version including 3.2.4; that is a constructor guard, not a defect, and nothing here depends on it.GET /api/files/import(the otherstageUploadcaller) was not driven; it uses the same parser withfieldName: "file".packages/runtimes/serve-emuhas no test script and the workspacenpm testcovers other packages.Verification
npm ci --no-audit --no-fund, run in a directory containing only this package'spackage.jsonandpackage-lock.json(a copy ofpackages/runtimes/serve-emuat the base commit, and the same directory with this patch applied): exit 0 on the base pair (installs@fastify/busboy3.2.0) and exit 0 on this patch's pair (installs 3.2.4).node_modules/@fastify/busboy(version,resolved,integrity), plus the lock's root""dependency spec; thewsentry is byte-identical.@fastify/busboy@3.2.4declares nodependenciesand noengines, so the entry's absentdependenciesblock is correct for the new version.packages/runtimes/serve-emu/package.jsonor itspackage-lock.json(60 pull requests, all files checked). The repository has no.github/dependabot.yml.