-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: prevent splitting multibyte characters in
getPayload()
(#939)
If you expect that the payload is using utf8 or utf16 or any other multybyte encoding, then you have to concat the buffers first and in the final step you can serialize the buffer to a string with the desired encoding. The issue will arise, when with some "luck" a multibyte character is split between two chunks.
- Loading branch information
Showing
3 changed files
with
91 additions
and
8 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import EventEmitter from "node:events"; | ||
import { getPayload } from "../../src/middleware/node/get-payload.ts"; | ||
|
||
describe("getPayload", () => { | ||
it("returns a promise", () => { | ||
const request = new EventEmitter(); | ||
const promise = getPayload(request); | ||
|
||
expect(promise).toBeInstanceOf(Promise); | ||
}); | ||
|
||
it("resolves with a string when only receiving no chunk", async () => { | ||
const request = new EventEmitter(); | ||
const promise = getPayload(request); | ||
|
||
request.emit("end"); | ||
|
||
expect(await promise).toEqual(""); | ||
}); | ||
|
||
it("resolves with a string when only receiving one chunk", async () => { | ||
const request = new EventEmitter(); | ||
const promise = getPayload(request); | ||
|
||
request.emit("data", Buffer.from("foobar")); | ||
request.emit("end"); | ||
|
||
expect(await promise).toEqual("foobar"); | ||
}); | ||
|
||
it("resolves with a string when receiving multiple chunks", async () => { | ||
const request = new EventEmitter(); | ||
const promise = getPayload(request); | ||
|
||
request.emit("data", Buffer.from("foo")); | ||
request.emit("data", Buffer.from("bar")); | ||
request.emit("end"); | ||
|
||
expect(await promise).toEqual("foobar"); | ||
}); | ||
|
||
it("rejects with an error", async () => { | ||
const request = new EventEmitter(); | ||
const promise = getPayload(request); | ||
|
||
request.emit("error", new Error("test")); | ||
|
||
await expect(promise).rejects.toThrow("test"); | ||
}); | ||
|
||
it("resolves with a string with respecting the utf-8 encoding", async () => { | ||
const request = new EventEmitter(); | ||
const promise = getPayload(request); | ||
|
||
const doubleByteBuffer = Buffer.from("ݔ"); | ||
request.emit("data", doubleByteBuffer.subarray(0, 1)); | ||
request.emit("data", doubleByteBuffer.subarray(1, 2)); | ||
request.emit("end"); | ||
|
||
expect(await promise).toEqual("ݔ"); | ||
}); | ||
|
||
it("resolves with the body, if passed via the request", async () => { | ||
const request = new EventEmitter(); | ||
// @ts-ignore body is not part of EventEmitter, which we are using | ||
// to mock the request object | ||
request.body = "foo"; | ||
|
||
const promise = getPayload(request); | ||
|
||
// we emit data, to ensure that the body attribute is preferred | ||
request.emit("data", "bar"); | ||
request.emit("end"); | ||
|
||
expect(await promise).toEqual("foo"); | ||
}); | ||
}); |
This file contains 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