-
Notifications
You must be signed in to change notification settings - Fork 894
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve decodeBase64() to throw on invalid input rather than silently accept it #7019
Conversation
🦋 Changeset detectedLatest commit: 63b10fc The changes in this PR will be included in the next version bump. This PR includes changesets to release 28 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Size Report 1Affected Products
Test Logs |
Size Analysis Report 1This report is too large (756,081 characters) to be displayed here in a GitHub comment. Please use the below link to see the full report on Google Cloud Storage.Test Logs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
); | ||
} catch (e) { | ||
if (e instanceof DecodeBase64StringError) { | ||
throw new Base64DecodeError('Invalid base64 string: ' + e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't followed these all the way up the chain but will they eventually get wrapped in a FirestoreError
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the error won't be re-thrown as a FirestoreError
. The specific use case is a future optimization that involves decoding base64. If, for some reason, we get invalid base64 from the backend then we will just ignore it and disable the optimization. We don't expect to ever get invalid base64, but it could theoretically happen and if it ever does we don't want to crash.
The problem was that it was previously not possible to reliably detect an invalid base64 string. This PR fixes that by having the new Base64DecodeError
always thrown if an invalid base64 string is given as input. The future code will catch this exception and use it to disable the optimization.
Fix all
decodeBase64()
functions to throw an exception when given invalid input. Previously, some implementations silently accepted invalid input, potentially leading to bugs.The
decodeBase64()
function inpackages/firestore/src/platform/base64.ts
has different implementations on different platforms (e.g. browser, node, and react native). These implementations behave differently when given an invalid base64 string to decode:DOMException
on any invalid input.Error
on some invalid inputs, and silently accepts others.The node implementation used to have a regular expression that validated the input (link); however, it was removed in #6008 because it was too slow.
The "parent"
decodeBase64()
function now validates that the input string is valid base64 using an algorithm that is orders of magnitude more efficient and robust than a regular expression. It verifies that the input string has the expected length based on the number of bytes returned from the platform-specific base64 decoding function to which it delegates. If the length is not correct then the platform-specific function must have truncated at an invalid base64 character. In this case a newBase64DecodeError
is thrown.Credit for this PR goes to @milaGGL from #6992. I'm merely merging a small component of that PR into the master branch to reduce the diff when her PR ultimately gets merged.