Skip to content

Commit

Permalink
fix(blob): error early when trying to use conflicting characters (#769)
Browse files Browse the repository at this point in the history
* fix(blob): error early when trying to use conflicting characters

Trying to upload files containing ?, # or // will always result in a weird
behavior where the pathname you sent won't be exactly the one in the resulting
url. Rather than relying on this I propose we just error early on and advise to
either not use them or encode them.

BREAKING CHANGE: Previously working characters will now throw an error.

* changeset
  • Loading branch information
vvo authored Oct 8, 2024
1 parent 736b3f6 commit 61b5939
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/selfish-owls-thank.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@vercel/blob': minor
---

BREAKING CHANGE, we're no more accepting non-encoded versions of ?, # and // in pathnames. If you want to use such characters in your pathnames then you will need to encode them.
10 changes: 9 additions & 1 deletion packages/blob/src/copy.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MAXIMUM_PATHNAME_LENGTH, requestApi } from './api';
import type { CommonCreateBlobOptions } from './helpers';
import { BlobError } from './helpers';
import { BlobError, disallowedPathnameCharacters } from './helpers';

export type CopyCommandOptions = CommonCreateBlobOptions;

Expand Down Expand Up @@ -41,6 +41,14 @@ export async function copy(
);
}

for (const invalidCharacter of disallowedPathnameCharacters) {
if (toPathname.includes(invalidCharacter)) {
throw new BlobError(
`pathname cannot contain "${invalidCharacter}", please encode it if needed`,
);
}
}

const headers: Record<string, string> = {};

if (options.addRandomSuffix !== undefined) {
Expand Down
2 changes: 2 additions & 0 deletions packages/blob/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,5 @@ export function isPlainObject(value: unknown): boolean {
!(Symbol.iterator in value)
);
}

export const disallowedPathnameCharacters = ['#', '?', '//'];
36 changes: 36 additions & 0 deletions packages/blob/src/index.node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,42 @@ describe('blob client', () => {
);
});

it('throws when pathname contains #', async () => {
await expect(
put('foo#bar.txt', 'Test Body', {
access: 'public',
}),
).rejects.toThrow(
new Error(
'Vercel Blob: pathname cannot contain "#", please encode it if needed',
),
);
});

it('throws when pathname contains ?', async () => {
await expect(
put('foo?bar.txt', 'Test Body', {
access: 'public',
}),
).rejects.toThrow(
new Error(
'Vercel Blob: pathname cannot contain "?", please encode it if needed',
),
);
});

it('throws when pathname contains //', async () => {
await expect(
put('foo//bar.txt', 'Test Body', {
access: 'public',
}),
).rejects.toThrow(
new Error(
'Vercel Blob: pathname cannot contain "//", please encode it if needed',
),
);
});

const table: [string, (signal: AbortSignal) => Promise<unknown>][] = [
[
'put',
Expand Down
10 changes: 9 additions & 1 deletion packages/blob/src/put-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import type { Readable } from 'stream';
import type { ClientCommonCreateBlobOptions } from './client';
import type { CommonCreateBlobOptions } from './helpers';
import { BlobError } from './helpers';
import { BlobError, disallowedPathnameCharacters } from './helpers';
import { MAXIMUM_PATHNAME_LENGTH } from './api';

export const putOptionHeaderMap = {
Expand Down Expand Up @@ -92,6 +92,14 @@ export async function createPutOptions<
);
}

for (const invalidCharacter of disallowedPathnameCharacters) {
if (pathname.includes(invalidCharacter)) {
throw new BlobError(
`pathname cannot contain "${invalidCharacter}", please encode it if needed`,
);
}
}

if (!options) {
throw new BlobError('missing options, see usage');
}
Expand Down

0 comments on commit 61b5939

Please sign in to comment.