Repository: parse-community/Parse-SDK-JS

Issue #1532: Remove inefficient/failing base64 check and add Buffer support to Parse.File()
Created: 2022-08-18T11:34:03Z
New Issue Checklist


 I am not disclosing a vulnerability.
 I am not just asking a question.
 I have searched through existing issues.
 I can reproduce the issue with the latest versions of Parse Server and the Parse JS SDK. 

Issue Description

new Parse.File()fails with large base64 string caused by complex regex test.
Steps to reproduce

Review the source code of ParseFile.js 3.3.4, line 210.
In 3.3.4, this code is executed in Parse.File() to verify the base64 encoded file data:
        // Check if data URI or base64 string is valid
        const validationRegex = new RegExp(base64Regex.source + '|' + dataUriRegex.source, 'i');


And here the regex:
const base64Regex = new RegExp('([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))', 'i');
const dataUriRegex = new RegExp(`^data:([a-zA-Z]+\\/[-a-zA-Z0-9+.]+(;[a-z-]+=[a-zA-Z0-9+.-]+)?)?(;base64)?,(${base64Regex.source})*$`, 'i');


The passed base64 is created from Uint8Array.toString("base64");
The problem has meanwhile been worked around by passing a byte array. This introduces memory overhead as a new byte array has to be created with Array.from(Uint8Array) as an UInt8Array is not accepted by Parse.File. Parse.File than uses its own base64 encoding algorithm to create a base64 string instead of the Internal javascript runtime version => Uint8Array.toString("base64");
In short:

Parse.File does a highly inefficient, unnecessary and failing base64 check, breaking core functionality
Parse.File does not accept a JS buffer making it necessary to convert it to a plain byte array causing memory overhead
base64 encoding in Parse.File does not use the JS runtime function but it's own (much less efficient) implementation

The base64 check should simply be removed. Worse case the base64 data is invalid and either:

save/upload fails (?)
the storage adapter fails (?)
a client reading it fails (most definately)

The 1st two can be caught by the client-app while uploading.
The last one can also happen with pure binary data and is the client-app responsibility to catch, not the Parse SDK.
If I find some time I'm happy to create a PR with native Buffer support, something along the line of:
if(Buffer.isBuffer(data) {
        this._data = Uint8Array.from(data).toString("base64");
        this._source = {
          format: 'base64',
          base64: this._data,
          type: specifiedType
        };
}


Actual Outcome

With a ~2MB base64 string (jpeg image) it took around 6 minutes (!!!) with 100% cpu (=full single core) until the regex failed. The base64 was however correct as any image saved with Parse JS-SDK 3.3.0 and earlier could be downloaded/viewed without error.
Expected Outcome

Seamless passing of base64 string, leaving it to the client to make sure the base64 is valid.
Alternative, a much more efficient base64 check than the current complex, failing regex and/or Buffer support.
Environment

MaxOS, node 14
Linux Node 12
Server
n/a, client issue (Parse-SDK-JS)
Database
n/a, client issue (Parse-SDK-JS)
Client

Parse JS SDK version: 3.3.4

Logs

n/a (Exception with "Cannot create a Parse.File without valid data URIs or base64 encoded data.")

Duplicate issue #1541: Parse.File base64 validation causes runaway regular expression
Created: 2022-09-08T22:00:43Z
New Issue Checklist

 I am not disclosing a vulnerability.
 I am not just asking a question.
 I have searched through existing issues.
 I can reproduce the issue with the latest versions of Parse Server and the Parse JS SDK. 

Issue Description
Using the Parse.file constructor with some base64 strings causes the browser to hang indefinitely. I believe this is a case of a runaway regular expression, probably caused by the use of Regex constructors instead of Regex string literals.
Steps to reproduce
Create a new Parse.File with the base64 string here: https://github.com/chinapalace/base64-string/blob/main/README.md
ex. new Parse.File({base64: <sample string above>})
Actual Outcome
The browser hangs indefinitely when I try to instantiate a ParseFile with certain base64 strings.
Expected Outcome
A ParseFile is instantiated successfully.
Environment
Chrome Version 105.0.5195.102 (Official Build) (arm64)
Client

Parse JS SDK version: 3.4.4

Closing comment (2022-09-08T22:35:45Z): Closing as duplicate of #1532