From c8f5e511950bcf2ae6a6504430407b2ff7dfbb4f Mon Sep 17 00:00:00 2001 From: Oskar Eichler Date: Sun, 30 Aug 2026 01:45:09 +0200 Subject: [PATCH] fix(storage): decode data URLs with custom content types --- .../__tests__/StorageReference.test.ts | 20 +++++++++++++++++++ packages/storage/e2e/StorageTask.e2e.js | 15 ++++++++++++++ packages/storage/lib/StorageReference.ts | 4 ++-- 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 packages/storage/__tests__/StorageReference.test.ts diff --git a/packages/storage/__tests__/StorageReference.test.ts b/packages/storage/__tests__/StorageReference.test.ts new file mode 100644 index 0000000000..6f799118ee --- /dev/null +++ b/packages/storage/__tests__/StorageReference.test.ts @@ -0,0 +1,20 @@ +import { describe, expect, it } from '@jest/globals'; + +import Reference from '../lib/StorageReference'; +import { StringFormat } from '../lib/StorageStatics'; +import type { StorageInternal } from '../lib/types/internal'; + +describe('StorageReference string uploads', () => { + it('decodes a data URL when metadata already provides a content type', () => { + const reference = new Reference({} as StorageInternal, '/file.txt'); + const metadata = { contentType: 'text/custom' }; + + expect( + reference._updateString('data:text/plain;base64,aGVsbG8=', StringFormat.DATA_URL, metadata), + ).toEqual({ + _format: StringFormat.BASE64, + _metadata: metadata, + _string: 'aGVsbG8=', + }); + }); +}); diff --git a/packages/storage/e2e/StorageTask.e2e.js b/packages/storage/e2e/StorageTask.e2e.js index bbd233c729..f73352986c 100644 --- a/packages/storage/e2e/StorageTask.e2e.js +++ b/packages/storage/e2e/StorageTask.e2e.js @@ -171,6 +171,21 @@ describe('storage() -> StorageTask', function () { uploadTaskSnapshot.metadata.should.be.an.Object(); }); + it('uploads a data_url with an explicit content type', async function () { + const { getStorage, ref, uploadString, StringFormat, TaskState } = storageModular; + + const uploadTaskSnapshot = await uploadString( + ref(getStorage(), `${PATH}/putStringDataURLWithContentType.txt`), + 'data:text/plain;base64,aGVsbG8=', + StringFormat.DATA_URL, + { contentType: 'text/custom' }, + ); + + uploadTaskSnapshot.state.should.eql(TaskState.SUCCESS); + uploadTaskSnapshot.metadata.size.should.eql(5); + uploadTaskSnapshot.metadata.contentType.should.eql('text/custom'); + }); + it('uploads a url encoded data_url formatted string', async function () { const { getStorage, ref, uploadString, StringFormat, TaskState } = storageModular; diff --git a/packages/storage/lib/StorageReference.ts b/packages/storage/lib/StorageReference.ts index e3f904eb2c..b3cf6f3d22 100644 --- a/packages/storage/lib/StorageReference.ts +++ b/packages/storage/lib/StorageReference.ts @@ -339,9 +339,9 @@ export default class Reference extends ReferenceBase implements StorageReference _metadata = {}; } _metadata!.contentType = mediaType; - _string = base64String; - _format = StringFormat.BASE64; } + _string = base64String; + _format = StringFormat.BASE64; } return { _string, _metadata, _format }; }