Repository: parse-community/Parse-SDK-JS
Pull request #483 (2017-09-21 16:52:25)

Update ParseFile to handle a data URI containing a number
The regex to extract the components from a base64 encoded string doesn't handle mime types which contain a number, e.g. audio/m4a.

It was failing with the error:
TypeError: Cannot read property '1' of null
at ParseFile (/app/node_modules/parse/lib/node/ParseFile.js:121)

The regex has been updated to allow numbers, and a test added which failed before the change.

codecov[bot]: # [Codecov](https://codecov.io/gh/parse-community/Parse-SDK-JS/pull/483?src=pr&el=h1) Report
> Merging [#483](https://codecov.io/gh/parse-community/Parse-SDK-JS/pull/483?src=pr&el=desc) into [master](https://codecov.io/gh/parse-community/Parse-SDK-JS/commit/293e2e13fa8eb1c62786fecf6aa6cd4458670b7f?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/parse-community/Parse-SDK-JS/pull/483/graphs/tree.svg?height=150&width=650&token=8nCENM0QHj&src=pr)](https://codecov.io/gh/parse-community/Parse-SDK-JS/pull/483?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master     #483   +/-   ##
=======================================
  Coverage   84.03%   84.03%           
=======================================
  Files          47       47           
  Lines        3795     3795           
  Branches      868      868           
=======================================
  Hits         3189     3189           
  Misses        606      606
```


| [Impacted Files](https://codecov.io/gh/parse-community/Parse-SDK-JS/pull/483?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/ParseFile.js](https://codecov.io/gh/parse-community/Parse-SDK-JS/pull/483?src=pr&el=tree#diff-c3JjL1BhcnNlRmlsZS5qcw==) | `82.35% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/parse-community/Parse-SDK-JS/pull/483?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/parse-community/Parse-SDK-JS/pull/483?src=pr&el=footer). Last update [293e2e1...ee36a89](https://codecov.io/gh/parse-community/Parse-SDK-JS/pull/483?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

AppOrchestra: I had a proper look at a few pages:
https://tools.ietf.org/html/rfc6838 (4.2)
https://en.wikipedia.org/wiki/Data_URI_scheme
https://www.freeformatter.com/mime-types-list.html

(instead of copying what a popular data uri regex had...) and updated the regex to handle all valid mime-types, with some basic validation, and also fixed it to handle the charset param too.


Patch:
diff --git a/src/ParseFile.js b/src/ParseFile.js
index 06f71d8..915e7b2 100644
--- a/src/ParseFile.js
+++ b/src/ParseFile.js
@@ -25,7 +25,7 @@ export type FileSource = {
 };
 
 var dataUriRegexp =
-  /^data:([a-zA-Z]*\/[a-zA-Z+.-]*);(charset=[a-zA-Z0-9\-\/\s]*,)?base64,/;
+  /^data:([a-zA-Z]+\/[-a-zA-Z0-9+.]+)(;charset=[a-zA-Z0-9\-\/]*)?;base64,/;
 
 function b64Digit(number: number): string {
   if (number < 26) {


Test patch:
diff --git a/src/__tests__/ParseFile-test.js b/src/__tests__/ParseFile-test.js
index f2ac5ea..6d799eb 100644
--- a/src/__tests__/ParseFile-test.js
+++ b/src/__tests__/ParseFile-test.js
@@ -38,7 +38,7 @@ describe('ParseFile', () => {
     expect(file._source.type).toBe('');
   });
 
-  it('can extact data type from base64', () => {
+  it('can extract data type from base64', () => {
     var file = new ParseFile('parse.txt', {
       base64: 'data:image/png;base64,ParseA=='
     });
@@ -46,6 +46,30 @@ describe('ParseFile', () => {
     expect(file._source.type).toBe('image/png');
   });
 
+  it('can extract data type from base64 with data type containing a number', () => {
+    var file = new ParseFile('parse.m4a', {
+      base64: 'data:audio/m4a;base64,ParseA=='
+    });
+    expect(file._source.base64).toBe('ParseA==');
+    expect(file._source.type).toBe('audio/m4a');
+  });
+
+  it('can extract data type from base64 with a complex mime type', () => {
+    var file = new ParseFile('parse.kml', {
+        base64: 'data:application/vnd.google-earth.kml+xml;base64,ParseA=='
+    });
+    expect(file._source.base64).toBe('ParseA==');
+    expect(file._source.type).toBe('application/vnd.google-earth.kml+xml');
+  });
+
+  it('can extract data type from base64 with a charset param', () => {
+    var file = new ParseFile('parse.kml', {
+        base64: 'data:application/vnd.3gpp.pic-bw-var;charset=utf-8;base64,ParseA=='
+    });
+    expect(file._source.base64).toBe('ParseA==');
+    expect(file._source.type).toBe('application/vnd.3gpp.pic-bw-var');
+  });
+
   it('can create files with byte arrays', () => {
     var file = new ParseFile('parse.txt', [61, 170, 236, 120]);
     expect(file._source.base64).toBe('ParseA==');