From b1168767d36baa59e9482ac859d505766bbb6246 Mon Sep 17 00:00:00 2001 From: Denver Coneybeare Date: Wed, 8 Feb 2023 23:12:47 -0500 Subject: [PATCH 1/4] Move newTextEncoder/Decoder() to their own file, text_serializer.ts --- .../firestore/src/core/firestore_client.ts | 3 +- .../src/platform/browser/serializer.ts | 14 ------ .../src/platform/browser/text_serializer.ts | 30 ++++++++++++ .../platform/browser_lite/text_serializer.ts | 18 +++++++ .../firestore/src/platform/node/serializer.ts | 16 ------- .../src/platform/node/text_serializer.ts | 32 +++++++++++++ .../src/platform/node_lite/text_serializer.ts | 18 +++++++ .../firestore/src/platform/rn/serializer.ts | 6 +-- .../src/platform/rn/text_serializer.ts | 18 +++++++ .../src/platform/rn_lite/text_serializer.ts | 18 +++++++ packages/firestore/src/platform/serializer.ts | 32 ------------- .../firestore/src/platform/text_serializer.ts | 48 +++++++++++++++++++ .../firestore/src/util/bundle_reader_impl.ts | 2 +- .../test/unit/specs/spec_test_runner.ts | 2 +- .../firestore/test/unit/util/bundle.test.ts | 2 +- .../firestore/test/unit/util/bundle_data.ts | 6 +-- 16 files changed, 190 insertions(+), 75 deletions(-) create mode 100644 packages/firestore/src/platform/browser/text_serializer.ts create mode 100644 packages/firestore/src/platform/browser_lite/text_serializer.ts create mode 100644 packages/firestore/src/platform/node/text_serializer.ts create mode 100644 packages/firestore/src/platform/node_lite/text_serializer.ts create mode 100644 packages/firestore/src/platform/rn/text_serializer.ts create mode 100644 packages/firestore/src/platform/rn_lite/text_serializer.ts create mode 100644 packages/firestore/src/platform/text_serializer.ts diff --git a/packages/firestore/src/core/firestore_client.ts b/packages/firestore/src/core/firestore_client.ts index 2c2c0af1771..a58786c6685 100644 --- a/packages/firestore/src/core/firestore_client.ts +++ b/packages/firestore/src/core/firestore_client.ts @@ -41,7 +41,8 @@ import { Document } from '../model/document'; import { DocumentKey } from '../model/document_key'; import { Mutation } from '../model/mutation'; import { toByteStreamReader } from '../platform/byte_stream_reader'; -import { newSerializer, newTextEncoder } from '../platform/serializer'; +import { newSerializer } from '../platform/serializer'; +import { newTextEncoder } from '../platform/text_serializer'; import { Datastore } from '../remote/datastore'; import { canUseNetwork, diff --git a/packages/firestore/src/platform/browser/serializer.ts b/packages/firestore/src/platform/browser/serializer.ts index 722f40e605f..5e009d89f60 100644 --- a/packages/firestore/src/platform/browser/serializer.ts +++ b/packages/firestore/src/platform/browser/serializer.ts @@ -22,17 +22,3 @@ import { JsonProtoSerializer } from '../../remote/serializer'; export function newSerializer(databaseId: DatabaseId): JsonProtoSerializer { return new JsonProtoSerializer(databaseId, /* useProto3Json= */ true); } - -/** - * An instance of the Platform's 'TextEncoder' implementation. - */ -export function newTextEncoder(): TextEncoder { - return new TextEncoder(); -} - -/** - * An instance of the Platform's 'TextDecoder' implementation. - */ -export function newTextDecoder(): TextDecoder { - return new TextDecoder('utf-8'); -} diff --git a/packages/firestore/src/platform/browser/text_serializer.ts b/packages/firestore/src/platform/browser/text_serializer.ts new file mode 100644 index 00000000000..6a53021f7c0 --- /dev/null +++ b/packages/firestore/src/platform/browser/text_serializer.ts @@ -0,0 +1,30 @@ +/** + * @license + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * An instance of the Platform's 'TextEncoder' implementation. + */ +export function newTextEncoder(): TextEncoder { + return new TextEncoder(); +} + +/** + * An instance of the Platform's 'TextDecoder' implementation. + */ +export function newTextDecoder(): TextDecoder { + return new TextDecoder('utf-8'); +} diff --git a/packages/firestore/src/platform/browser_lite/text_serializer.ts b/packages/firestore/src/platform/browser_lite/text_serializer.ts new file mode 100644 index 00000000000..a9231f63914 --- /dev/null +++ b/packages/firestore/src/platform/browser_lite/text_serializer.ts @@ -0,0 +1,18 @@ +/** + * @license + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from '../browser/text_serializer'; diff --git a/packages/firestore/src/platform/node/serializer.ts b/packages/firestore/src/platform/node/serializer.ts index 1f61010902b..e19dbc8b1db 100644 --- a/packages/firestore/src/platform/node/serializer.ts +++ b/packages/firestore/src/platform/node/serializer.ts @@ -16,25 +16,9 @@ */ /** Return the Platform-specific serializer monitor. */ -import { TextDecoder, TextEncoder } from 'util'; - import { DatabaseId } from '../../core/database_info'; import { JsonProtoSerializer } from '../../remote/serializer'; export function newSerializer(databaseId: DatabaseId): JsonProtoSerializer { return new JsonProtoSerializer(databaseId, /* useProto3Json= */ false); } - -/** - * An instance of the Platform's 'TextEncoder' implementation. - */ -export function newTextEncoder(): TextEncoder { - return new TextEncoder(); -} - -/** - * An instance of the Platform's 'TextDecoder' implementation. - */ -export function newTextDecoder(): TextDecoder { - return new TextDecoder('utf-8'); -} diff --git a/packages/firestore/src/platform/node/text_serializer.ts b/packages/firestore/src/platform/node/text_serializer.ts new file mode 100644 index 00000000000..cc7852e5f4b --- /dev/null +++ b/packages/firestore/src/platform/node/text_serializer.ts @@ -0,0 +1,32 @@ +/** + * @license + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TextDecoder, TextEncoder } from 'util'; + +/** + * An instance of the Platform's 'TextEncoder' implementation. + */ +export function newTextEncoder(): TextEncoder { + return new TextEncoder(); +} + +/** + * An instance of the Platform's 'TextDecoder' implementation. + */ +export function newTextDecoder(): TextDecoder { + return new TextDecoder('utf-8'); +} diff --git a/packages/firestore/src/platform/node_lite/text_serializer.ts b/packages/firestore/src/platform/node_lite/text_serializer.ts new file mode 100644 index 00000000000..efc3610847d --- /dev/null +++ b/packages/firestore/src/platform/node_lite/text_serializer.ts @@ -0,0 +1,18 @@ +/** + * @license + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from '../browser_lite/text_serializer'; diff --git a/packages/firestore/src/platform/rn/serializer.ts b/packages/firestore/src/platform/rn/serializer.ts index 2b168a0dffa..c5ab7bf2bb5 100644 --- a/packages/firestore/src/platform/rn/serializer.ts +++ b/packages/firestore/src/platform/rn/serializer.ts @@ -15,8 +15,4 @@ * limitations under the License. */ -export { - newSerializer, - newTextEncoder, - newTextDecoder -} from '../browser/serializer'; +export { newSerializer } from '../browser/serializer'; diff --git a/packages/firestore/src/platform/rn/text_serializer.ts b/packages/firestore/src/platform/rn/text_serializer.ts new file mode 100644 index 00000000000..8edf69e42f2 --- /dev/null +++ b/packages/firestore/src/platform/rn/text_serializer.ts @@ -0,0 +1,18 @@ +/** + * @license + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { newTextEncoder, newTextDecoder } from '../browser/text_serializer'; diff --git a/packages/firestore/src/platform/rn_lite/text_serializer.ts b/packages/firestore/src/platform/rn_lite/text_serializer.ts new file mode 100644 index 00000000000..efc3610847d --- /dev/null +++ b/packages/firestore/src/platform/rn_lite/text_serializer.ts @@ -0,0 +1,18 @@ +/** + * @license + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from '../browser_lite/text_serializer'; diff --git a/packages/firestore/src/platform/serializer.ts b/packages/firestore/src/platform/serializer.ts index 89e8fe650d1..47b659f5664 100644 --- a/packages/firestore/src/platform/serializer.ts +++ b/packages/firestore/src/platform/serializer.ts @@ -15,15 +15,9 @@ * limitations under the License. */ -import { isNode, isReactNative } from '@firebase/util'; - import { DatabaseId } from '../core/database_info'; import { JsonProtoSerializer } from '../remote/serializer'; -import * as browser from './browser/serializer'; -import * as node from './node/serializer'; -import * as rn from './rn/serializer'; - // This file is only used under ts-node. // eslint-disable-next-line @typescript-eslint/no-require-imports const platform = require(`./${process.env.TEST_PLATFORM ?? 'node'}/serializer`); @@ -31,29 +25,3 @@ const platform = require(`./${process.env.TEST_PLATFORM ?? 'node'}/serializer`); export function newSerializer(databaseId: DatabaseId): JsonProtoSerializer { return platform.newSerializer(databaseId); } - -/** - * An instance of the Platform's 'TextEncoder' implementation. - */ -export function newTextEncoder(): TextEncoder { - if (isNode()) { - return node.newTextEncoder(); - } else if (isReactNative()) { - return rn.newTextEncoder(); - } else { - return browser.newTextEncoder(); - } -} - -/** - * An instance of the Platform's 'TextDecoder' implementation. - */ -export function newTextDecoder(): TextDecoder { - if (isNode()) { - return node.newTextDecoder() as TextDecoder; - } else if (isReactNative()) { - return rn.newTextDecoder(); - } else { - return browser.newTextDecoder(); - } -} diff --git a/packages/firestore/src/platform/text_serializer.ts b/packages/firestore/src/platform/text_serializer.ts new file mode 100644 index 00000000000..72ebba86c3c --- /dev/null +++ b/packages/firestore/src/platform/text_serializer.ts @@ -0,0 +1,48 @@ +/** + * @license + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { isNode, isReactNative } from '@firebase/util'; + +import * as browser from './browser/text_serializer'; +import * as node from './node/text_serializer'; +import * as rn from './rn/text_serializer'; + +/** + * An instance of the Platform's 'TextEncoder' implementation. + */ +export function newTextEncoder(): TextEncoder { + if (isNode()) { + return node.newTextEncoder(); + } else if (isReactNative()) { + return rn.newTextEncoder(); + } else { + return browser.newTextEncoder(); + } +} + +/** + * An instance of the Platform's 'TextDecoder' implementation. + */ +export function newTextDecoder(): TextDecoder { + if (isNode()) { + return node.newTextDecoder() as TextDecoder; + } else if (isReactNative()) { + return rn.newTextDecoder(); + } else { + return browser.newTextDecoder(); + } +} diff --git a/packages/firestore/src/util/bundle_reader_impl.ts b/packages/firestore/src/util/bundle_reader_impl.ts index 3f08218d2fc..05875fce1af 100644 --- a/packages/firestore/src/util/bundle_reader_impl.ts +++ b/packages/firestore/src/util/bundle_reader_impl.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { newTextDecoder } from '../platform/serializer'; +import { newTextDecoder } from '../platform/text_serializer'; import { BundleMetadata } from '../protos/firestore_bundle_proto'; import { JsonProtoSerializer } from '../remote/serializer'; diff --git a/packages/firestore/test/unit/specs/spec_test_runner.ts b/packages/firestore/test/unit/specs/spec_test_runner.ts index e64dcbfd214..675e057ed42 100644 --- a/packages/firestore/test/unit/specs/spec_test_runner.ts +++ b/packages/firestore/test/unit/specs/spec_test_runner.ts @@ -90,7 +90,7 @@ import { Mutation } from '../../../src/model/mutation'; import { JsonObject } from '../../../src/model/object_value'; import { encodeBase64 } from '../../../src/platform/base64'; import { toByteStreamReader } from '../../../src/platform/byte_stream_reader'; -import { newTextEncoder } from '../../../src/platform/serializer'; +import { newTextEncoder } from '../../../src/platform/text_serializer'; import * as api from '../../../src/protos/firestore_proto_api'; import { ExistenceFilter } from '../../../src/remote/existence_filter'; import { diff --git a/packages/firestore/test/unit/util/bundle.test.ts b/packages/firestore/test/unit/util/bundle.test.ts index 9f225138491..b32ca0842b7 100644 --- a/packages/firestore/test/unit/util/bundle.test.ts +++ b/packages/firestore/test/unit/util/bundle.test.ts @@ -18,7 +18,7 @@ import { expect, use } from 'chai'; import chaiAsPromised from 'chai-as-promised'; import { toByteStreamReader } from '../../../src/platform/byte_stream_reader'; -import { newTextEncoder } from '../../../src/platform/serializer'; +import { newTextEncoder } from '../../../src/platform/text_serializer'; import { BundleReader, SizedBundleElement diff --git a/packages/firestore/test/unit/util/bundle_data.ts b/packages/firestore/test/unit/util/bundle_data.ts index 03bc8b35f4c..92cfb8c30cd 100644 --- a/packages/firestore/test/unit/util/bundle_data.ts +++ b/packages/firestore/test/unit/util/bundle_data.ts @@ -22,10 +22,8 @@ import { queryWithLimit } from '../../../src/core/query'; import { DocumentKey } from '../../../src/model/document_key'; -import { - newSerializer, - newTextEncoder -} from '../../../src/platform/serializer'; +import { newSerializer } from '../../../src/platform/serializer'; +import { newTextEncoder } from '../../../src/platform/text_serializer'; import { BundleElement, LimitType as BundleLimitType From 897f9545bfef68e6b35d74b5a953a421097e458c Mon Sep 17 00:00:00 2001 From: Denver Coneybeare Date: Wed, 8 Feb 2023 23:26:37 -0500 Subject: [PATCH 2/4] Improve decodeBase64() to throw on invalid input rather than silently accept it --- common/api-review/util.api.md | 8 ++++++ packages/firestore/src/platform/base64.ts | 13 +++++++++- .../firestore/src/platform/browser/base64.ts | 12 ++++++++- packages/firestore/src/platform/rn/base64.ts | 26 +++++++++++++------ .../firestore/src/util/base64_decode_error.ts | 23 ++++++++++++++++ .../firestore/test/lite/integration.test.ts | 2 +- packages/util/src/crypt.ts | 9 ++++++- 7 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 packages/firestore/src/util/base64_decode_error.ts diff --git a/common/api-review/util.api.md b/common/api-review/util.api.md index be8703adf3f..75e484edd50 100644 --- a/common/api-review/util.api.md +++ b/common/api-review/util.api.md @@ -93,6 +93,14 @@ export function createSubscribe(executor: Executor, onNoObservers?: Execut // @public export const decode: (token: string) => DecodedToken; +// Warning: (ae-missing-release-tag) "DecodeBase64StringError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class DecodeBase64StringError extends Error { + // (undocumented) + readonly name = "DecodeBase64StringError"; +} + // Warning: (ae-missing-release-tag) "deepCopy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public diff --git a/packages/firestore/src/platform/base64.ts b/packages/firestore/src/platform/base64.ts index 877a78c732b..3efd0339e77 100644 --- a/packages/firestore/src/platform/base64.ts +++ b/packages/firestore/src/platform/base64.ts @@ -15,13 +15,24 @@ * limitations under the License. */ +import { Base64DecodeError } from '../util/base64_decode_error'; + // This file is only used under ts-node. // eslint-disable-next-line @typescript-eslint/no-require-imports const platform = require(`./${process.env.TEST_PLATFORM ?? 'node'}/base64`); /** Converts a Base64 encoded string to a binary string. */ export function decodeBase64(encoded: string): string { - return platform.decodeBase64(encoded); + const decoded = platform.decodeBase64(encoded); + + // A quick sanity check as node and rn will not throw error if input is an + // invalid base64 string, e.g., "A===". + const expectedEncodedLength = 4 * Math.ceil(decoded.length / 3); + if (encoded.length !== expectedEncodedLength) { + throw new Base64DecodeError('Invalid base64 string'); + } + + return decoded; } /** Converts a binary string to a Base64 encoded string. */ diff --git a/packages/firestore/src/platform/browser/base64.ts b/packages/firestore/src/platform/browser/base64.ts index 6c068b17244..4cbbfe6ced9 100644 --- a/packages/firestore/src/platform/browser/base64.ts +++ b/packages/firestore/src/platform/browser/base64.ts @@ -15,9 +15,19 @@ * limitations under the License. */ +import { Base64DecodeError } from '../../util/base64_decode_error'; + /** Converts a Base64 encoded string to a binary string. */ export function decodeBase64(encoded: string): string { - return atob(encoded); + try { + return atob(encoded); + } catch (e) { + if (e instanceof DOMException) { + throw new Base64DecodeError('Invalid base64 string: ' + e); + } else { + throw e; + } + } } /** Converts a binary string to a Base64 encoded string. */ diff --git a/packages/firestore/src/platform/rn/base64.ts b/packages/firestore/src/platform/rn/base64.ts index 4032190e5cd..f50c604ebf7 100644 --- a/packages/firestore/src/platform/rn/base64.ts +++ b/packages/firestore/src/platform/rn/base64.ts @@ -15,7 +15,9 @@ * limitations under the License. */ -import { base64 } from '@firebase/util'; +import { base64, DecodeBase64StringError } from '@firebase/util'; + +import { Base64DecodeError } from '../../util/base64_decode_error'; // WebSafe uses a different URL-encoding safe alphabet that doesn't match // the encoding used on the backend. @@ -23,13 +25,21 @@ const WEB_SAFE = false; /** Converts a Base64 encoded string to a binary string. */ export function decodeBase64(encoded: string): string { - return String.fromCharCode.apply( - null, - // We use `decodeStringToByteArray()` instead of `decodeString()` since - // `decodeString()` returns Unicode strings, which doesn't match the values - // returned by `atob()`'s Latin1 representation. - base64.decodeStringToByteArray(encoded, WEB_SAFE) - ); + try { + return String.fromCharCode.apply( + null, + // We use `decodeStringToByteArray()` instead of `decodeString()` since + // `decodeString()` returns Unicode strings, which doesn't match the values + // returned by `atob()`'s Latin1 representation. + base64.decodeStringToByteArray(encoded, WEB_SAFE) + ); + } catch (e) { + if (e instanceof DecodeBase64StringError) { + throw new Base64DecodeError('Invalid base64 string: ' + e); + } else { + throw e; + } + } } /** Converts a binary string to a Base64 encoded string. */ diff --git a/packages/firestore/src/util/base64_decode_error.ts b/packages/firestore/src/util/base64_decode_error.ts new file mode 100644 index 00000000000..84a20c55d1d --- /dev/null +++ b/packages/firestore/src/util/base64_decode_error.ts @@ -0,0 +1,23 @@ +/** + * @license + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * An error encountered while decoding base64 string. + */ +export class Base64DecodeError extends Error { + readonly name = 'Base64DecodeError'; +} diff --git a/packages/firestore/test/lite/integration.test.ts b/packages/firestore/test/lite/integration.test.ts index 54c595f9684..0cb6170652c 100644 --- a/packages/firestore/test/lite/integration.test.ts +++ b/packages/firestore/test/lite/integration.test.ts @@ -852,7 +852,7 @@ describe('DocumentSnapshot', () => { it('returns Bytes', () => { return withTestDocAndInitialData( - { bytes: Bytes.fromBase64String('aa') }, + { bytes: Bytes.fromBase64String('aa==') }, async docRef => { const docSnap = await getDoc(docRef); const bytes = docSnap.get('bytes'); diff --git a/packages/util/src/crypt.ts b/packages/util/src/crypt.ts index df1e058756f..7cd32125043 100644 --- a/packages/util/src/crypt.ts +++ b/packages/util/src/crypt.ts @@ -284,7 +284,7 @@ export const base64: Base64 = { ++i; if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) { - throw Error(); + throw new DecodeBase64StringError(); } const outByte1 = (byte1 << 2) | (byte2 >> 4); @@ -333,6 +333,13 @@ export const base64: Base64 = { } }; +/** + * An error encountered while decoding base64 string. + */ +export class DecodeBase64StringError extends Error { + readonly name = 'DecodeBase64StringError'; +} + /** * URL-safe base64 encoding */ From f4eae6e9285f883d9771631fa3ab8c8430baeb02 Mon Sep 17 00:00:00 2001 From: Denver Coneybeare Date: Fri, 10 Feb 2023 00:50:38 -0500 Subject: [PATCH 3/4] changeset added --- .changeset/large-lemons-relax.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/large-lemons-relax.md diff --git a/.changeset/large-lemons-relax.md b/.changeset/large-lemons-relax.md new file mode 100644 index 00000000000..8df076bb896 --- /dev/null +++ b/.changeset/large-lemons-relax.md @@ -0,0 +1,6 @@ +--- +'@firebase/firestore': patch +'firebase': patch +--- + +Internal refactor of platform-specific logic to create TextEncoder and TextDecoder objects. From 3f058974252a1d99620e28ce485c6275e368f335 Mon Sep 17 00:00:00 2001 From: Denver Coneybeare Date: Fri, 10 Feb 2023 09:12:56 -0500 Subject: [PATCH 4/4] changeset added --- .changeset/popular-apples-peel.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/popular-apples-peel.md diff --git a/.changeset/popular-apples-peel.md b/.changeset/popular-apples-peel.md new file mode 100644 index 00000000000..3269c43d903 --- /dev/null +++ b/.changeset/popular-apples-peel.md @@ -0,0 +1,7 @@ +--- +'@firebase/firestore': patch +'@firebase/util': patch +'firebase': patch +--- + +Modify base64 decoding logic to throw on invalid input, rather than silently truncating it.