Reject mongolian-vowel-separator baseURL invisible whitespace
Co-authored-by: Eric Allam <eric@trigger.dev>
This commit is contained in:
@@ -16,5 +16,7 @@ Add a new `@trigger.dev/ai` package with:
|
||||
values that normalize to empty after trimming
|
||||
- expanded unicode whitespace handling coverage to include figure space (`\u2007`) and medium
|
||||
mathematical space (`\u205F`) for both wrapper trimming and internal-whitespace rejection
|
||||
- expanded invisible-separator rejection coverage to include mongolian vowel separator (`\u180E`)
|
||||
in both wrapper and internal `baseURL` positions
|
||||
- deterministic baseURL validation error ordering for multi-issue inputs (internal whitespace → protocol → query/hash → credentials)
|
||||
- explicit default `baseURL` behavior (`https://api.trigger.dev`) and case-insensitive `HTTP(S)` protocol acceptance
|
||||
|
||||
@@ -679,6 +679,7 @@ Examples:
|
||||
- ❌ `\u200Bhttps://api.trigger.dev/custom-prefix/\u200B` (zero-width-space wrappers are rejected)
|
||||
- ❌ `\u200Chttps://api.trigger.dev/custom-prefix/\u200C` (zero-width-non-joiner wrappers are rejected)
|
||||
- ❌ `\u200Dhttps://api.trigger.dev/custom-prefix/\u200D` (zero-width-joiner wrappers are rejected)
|
||||
- ❌ `\u180Ehttps://api.trigger.dev/custom-prefix/\u180E` (mongolian-vowel-separator wrappers are rejected)
|
||||
- ❌ `https://api.trigger.dev?foo=bar`
|
||||
- ❌ `https://api.trigger.dev#fragment`
|
||||
- ❌ `https://user:pass@api.trigger.dev`
|
||||
@@ -705,6 +706,7 @@ Examples:
|
||||
- ❌ `https://api.trigger.dev/\u2007internal`
|
||||
- ❌ `https://api.trigger.dev/\u202Finternal`
|
||||
- ❌ `https://api.trigger.dev/\u205Finternal`
|
||||
- ❌ `https://api.trigger.dev/\u180Einternal`
|
||||
- ❌ `https://api.trigger.dev/\u3000internal`
|
||||
- ❌ `https://api.trigger.dev/\u2028internal`
|
||||
- ❌ `https://api.trigger.dev/\u2029internal`
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
confirmed empty-after-trim values still throw `baseURL must not be empty`.
|
||||
- Expanded unicode whitespace coverage with `\u2007` (figure space) and `\u205F` (medium mathematical space)
|
||||
across internal-whitespace rejection, wrapper trimming acceptance, and empty-after-trim validation.
|
||||
- Expanded invisible-separator coverage to reject `\u180E` (mongolian vowel separator) in both
|
||||
internal and wrapper `baseURL` positions.
|
||||
- Documented that `HTTP://` and `HTTPS://` are accepted (case-insensitive protocol matching).
|
||||
- Added deterministic validation ordering for multi-issue baseURL values
|
||||
(internal whitespace → protocol → query/hash → credentials).
|
||||
|
||||
@@ -186,6 +186,7 @@ Examples:
|
||||
- ❌ `\u200Bhttps://api.trigger.dev/custom-prefix/\u200B` (zero-width-space wrappers are rejected)
|
||||
- ❌ `\u200Chttps://api.trigger.dev/custom-prefix/\u200C` (zero-width-non-joiner wrappers are rejected)
|
||||
- ❌ `\u200Dhttps://api.trigger.dev/custom-prefix/\u200D` (zero-width-joiner wrappers are rejected)
|
||||
- ❌ `\u180Ehttps://api.trigger.dev/custom-prefix/\u180E` (mongolian-vowel-separator wrappers are rejected)
|
||||
- ❌ `https://api.trigger.dev?foo=bar` (query string)
|
||||
- ❌ `https://api.trigger.dev#fragment` (hash fragment)
|
||||
- ❌ `https://user:pass@api.trigger.dev` (credentials)
|
||||
@@ -212,6 +213,7 @@ Examples:
|
||||
- ❌ `https://api.trigger.dev/\u2007internal` (internal figure-space characters)
|
||||
- ❌ `https://api.trigger.dev/\u202Finternal` (internal narrow no-break space characters)
|
||||
- ❌ `https://api.trigger.dev/\u205Finternal` (internal medium-mathematical-space characters)
|
||||
- ❌ `https://api.trigger.dev/\u180Einternal` (internal mongolian-vowel-separator characters)
|
||||
- ❌ `https://api.trigger.dev/\u3000internal` (internal ideographic-space characters)
|
||||
- ❌ `https://api.trigger.dev/\u2028internal` (internal line-separator characters)
|
||||
- ❌ `https://api.trigger.dev/\u2029internal` (internal paragraph-separator characters)
|
||||
|
||||
@@ -950,6 +950,17 @@ describe("TriggerChatTransport", function () {
|
||||
}).toThrowError("baseURL must not contain internal whitespace characters");
|
||||
});
|
||||
|
||||
it("throws when baseURL contains internal mongolian-vowel-separator characters", function () {
|
||||
expect(function () {
|
||||
new TriggerChatTransport({
|
||||
task: "chat-task",
|
||||
accessToken: "pk_trigger",
|
||||
baseURL: "https://api.trigger.dev/\u180Einternal",
|
||||
stream: "chat-stream",
|
||||
});
|
||||
}).toThrowError("baseURL must not contain internal whitespace characters");
|
||||
});
|
||||
|
||||
it("throws when baseURL contains internal line-separator characters", function () {
|
||||
expect(function () {
|
||||
new TriggerChatTransport({
|
||||
@@ -1027,6 +1038,17 @@ describe("TriggerChatTransport", function () {
|
||||
}).toThrowError("baseURL must not contain internal whitespace characters");
|
||||
});
|
||||
|
||||
it("throws when baseURL is wrapped with mongolian-vowel-separator characters", function () {
|
||||
expect(function () {
|
||||
new TriggerChatTransport({
|
||||
task: "chat-task",
|
||||
accessToken: "pk_trigger",
|
||||
baseURL: "\u180Ehttps://api.trigger.dev/custom-prefix/\u180E",
|
||||
stream: "chat-stream",
|
||||
});
|
||||
}).toThrowError("baseURL must not contain internal whitespace characters");
|
||||
});
|
||||
|
||||
it("throws when baseURL contains internal zero-width-non-joiner characters", function () {
|
||||
expect(function () {
|
||||
new TriggerChatTransport({
|
||||
@@ -4043,6 +4065,17 @@ describe("TriggerChatTransport", function () {
|
||||
}).toThrowError("baseURL must not contain internal whitespace characters");
|
||||
});
|
||||
|
||||
it("throws from factory when baseURL contains internal mongolian-vowel-separator characters", function () {
|
||||
expect(function () {
|
||||
createTriggerChatTransport({
|
||||
task: "chat-task",
|
||||
accessToken: "pk_trigger",
|
||||
baseURL: "https://api.trigger.dev/\u180Einternal",
|
||||
stream: "chat-stream",
|
||||
});
|
||||
}).toThrowError("baseURL must not contain internal whitespace characters");
|
||||
});
|
||||
|
||||
it("throws from factory when baseURL contains internal line-separator characters", function () {
|
||||
expect(function () {
|
||||
createTriggerChatTransport({
|
||||
@@ -4120,6 +4153,17 @@ describe("TriggerChatTransport", function () {
|
||||
}).toThrowError("baseURL must not contain internal whitespace characters");
|
||||
});
|
||||
|
||||
it("throws from factory when baseURL is wrapped with mongolian-vowel-separator characters", function () {
|
||||
expect(function () {
|
||||
createTriggerChatTransport({
|
||||
task: "chat-task",
|
||||
accessToken: "pk_trigger",
|
||||
baseURL: "\u180Ehttps://api.trigger.dev/custom-prefix/\u180E",
|
||||
stream: "chat-stream",
|
||||
});
|
||||
}).toThrowError("baseURL must not contain internal whitespace characters");
|
||||
});
|
||||
|
||||
it("throws from factory when baseURL contains internal zero-width-non-joiner characters", function () {
|
||||
expect(function () {
|
||||
createTriggerChatTransport({
|
||||
|
||||
@@ -459,7 +459,7 @@ const BASE_URL_VALIDATION_ERRORS = {
|
||||
|
||||
// Includes standard whitespace plus common invisible separator/control marks
|
||||
// that can make URLs look valid while behaving unexpectedly.
|
||||
const INTERNAL_WHITESPACE_REGEX = /[\s\u200B\u200C\u200D\u2060\uFEFF]/u;
|
||||
const INTERNAL_WHITESPACE_REGEX = /[\s\u180E\u200B\u200C\u200D\u2060\uFEFF]/u;
|
||||
|
||||
function resolvePayloadMapper<
|
||||
UI_MESSAGE extends UIMessage,
|
||||
|
||||
Reference in New Issue
Block a user